Working code for STM32F0x2 test board, development of the same code for STM32F103

This commit is contained in:
eddyem 2019-05-18 18:57:57 +03:00
parent 24b953e3a3
commit 96c7e0d77c
52 changed files with 11016 additions and 4227 deletions

Binary file not shown.

View File

@ -0,0 +1,151 @@
BINARY = pl2303
BOOTPORT ?= /dev/ttyUSB0
BOOTSPEED ?= 57600
# MCU FAMILY
FAMILY = F0
# MCU code
#MCU = F042x6
MCU = F072xB
# hardware definitions
DEFS += -DUSARTNUM=1
#DEFS += -DCHECK_TMOUT
#DEFS += -DEBUG
# change this linking script depending on particular MCU model
#LDSCRIPT = stm32f042k.ld
LDSCRIPT = stm32f0728.ld
INDEPENDENT_HEADERS=
FP_FLAGS ?= -msoft-float
ASM_FLAGS = -mthumb -mcpu=cortex-m0 -march=armv6-m -mtune=cortex-m0
ARCH_FLAGS = $(ASM_FLAGS) $(FP_FLAGS)
###############################################################################
# Executables
OPREFIX ?= /opt/bin/arm-none-eabi
PREFIX ?= $(OPREFIX)
RM := rm -f
RMDIR := rmdir
CC := $(PREFIX)-gcc
LD := $(PREFIX)-gcc
AR := $(PREFIX)-ar
AS := $(PREFIX)-as
SIZE := $(PREFIX)-size
OBJCOPY := $(OPREFIX)-objcopy
OBJDUMP := $(OPREFIX)-objdump
GDB := $(OPREFIX)-gdb
STFLASH := $(shell which st-flash)
STBOOT := $(shell which stm32flash)
DFUUTIL := $(shell which dfu-util)
###############################################################################
# Source files
OBJDIR = mk
LDSCRIPT ?= $(BINARY).ld
SRC := $(wildcard *.c)
OBJS := $(addprefix $(OBJDIR)/, $(SRC:%.c=%.o))
STARTUP = $(OBJDIR)/startup.o
OBJS += $(STARTUP)
DEPS := $(OBJS:.o=.d)
INC_DIR ?= ../inc
INCLUDE := -I$(INC_DIR)/F0 -I$(INC_DIR)/cm
LIB_DIR := $(INC_DIR)/ld
###############################################################################
# C flags
CFLAGS += -O2 -g -MD -D__thumb2__=1
CFLAGS += -Wall -Werror -Wextra -Wshadow -Wimplicit-function-declaration
CFLAGS += -Wredundant-decls $(INCLUDE)
# -Wmissing-prototypes -Wstrict-prototypes
CFLAGS += -fno-common -ffunction-sections -fdata-sections
#CGLAGS += -fno-stack-protector
###############################################################################
# Linker flags
LDFLAGS += --static -nostartfiles --specs=nano.specs
#LDFLAGS += -fno-stack-protector
LDFLAGS += -L$(LIB_DIR)
LDFLAGS += -T$(LDSCRIPT)
LDFLAGS += -Wl,-Map=$(OBJDIR)/$(BINARY).map
LDFLAGS += -Wl,--gc-sections
###############################################################################
# Used libraries
LDLIBS += -Wl,--start-group -lc -lgcc -Wl,--end-group
LDLIBS += $(shell $(CC) $(CFLAGS) -print-libgcc-file-name)
DEFS += -DSTM32$(FAMILY) -DSTM32$(MCU)
#.SUFFIXES: .elf .bin .hex .srec .list .map .images
#.SECONDEXPANSION:
#.SECONDARY:
ELF := $(OBJDIR)/$(BINARY).elf
LIST := $(OBJDIR)/$(BINARY).list
BIN := $(BINARY).bin
HEX := $(BINARY).hex
all: bin list size
elf: $(ELF)
bin: $(BIN)
hex: $(HEX)
list: $(LIST)
ifneq ($(MAKECMDGOALS),clean)
-include $(DEPS)
endif
$(OBJDIR):
mkdir $(OBJDIR)
$(STARTUP): $(INC_DIR)/startup/vector.c
$(CC) $(CFLAGS) $(DEFS) $(INCLUDE) $(ARCH_FLAGS) -o $@ -c $<
$(OBJDIR)/%.o: %.c
@echo " CC $<"
$(CC) $(CFLAGS) $(DEFS) $(INCLUDE) $(ARCH_FLAGS) -o $@ -c $<
$(BIN): $(ELF)
@echo " OBJCOPY $(BIN)"
$(OBJCOPY) -Obinary $(ELF) $(BIN)
$(HEX): $(ELF)
@echo " OBJCOPY $(HEX)"
$(OBJCOPY) -Oihex $(ELF) $(HEX)
$(LIST): $(ELF)
@echo " OBJDUMP $(LIST)"
$(OBJDUMP) -S $(ELF) > $(LIST)
$(ELF): $(OBJDIR) $(OBJS)
@echo " LD $(ELF)"
$(LD) $(LDFLAGS) $(ARCH_FLAGS) $(OBJS) $(LDLIBS) -o $(ELF)
size: $(ELF)
$(SIZE) $(ELF)
clean:
@echo " CLEAN"
$(RM) $(OBJS) $(DEPS) $(ELF) $(HEX) $(LIST) $(OBJDIR)/*.map *.d
@rmdir $(OBJDIR) 2>/dev/null || true
dfuboot: $(BIN)
@echo " LOAD $(BIN) THROUGH DFU"
$(DFUUTIL) -a0 -D $(BIN) -s 0x08000000
flash: $(BIN)
@echo " FLASH $(BIN)"
$(STFLASH) write $(BIN) 0x8000000
boot: $(BIN)
@echo " LOAD $(BIN) through bootloader"
$(STBOOT) -b$(BOOTSPEED) $(BOOTPORT) -w $(BIN)
gentags:
CFLAGS="$(CFLAGS) $(DEFS)" geany -g $(BINARY).c.tags *[hc] 2>/dev/null
.PHONY: clean flash boot gentags

View File

@ -0,0 +1 @@
Simple test for STM32F0x2, blinking PA0, PWM for TIM14CH1, two user buttons (PA14 and PA15) and USB (PL2303 emulator) <> USART1 echo.

72
F0-nolib/F0_testbrd/adc.c Normal file
View File

@ -0,0 +1,72 @@
/*
* This file is part of the Chiller project.
* Copyright 2018 Edward V. Emelianov <edward.emelianoff@gmail.com>.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "adc.h"
/**
* @brief ADC_array - array for ADC channels with median filtering:
* 0 - Rvar
* 1 - internal Tsens
* 2 - Vref
*/
uint16_t ADC_array[NUMBER_OF_ADC_CHANNELS*9];
/**
* @brief getADCval - calculate median value for `nch` channel
* @param nch - number of channel
* @return
*/
uint16_t getADCval(int nch){
int i, addr = nch;
register uint16_t temp;
#define PIX_SORT(a,b) { if ((a)>(b)) PIX_SWAP((a),(b)); }
#define PIX_SWAP(a,b) { temp=(a);(a)=(b);(b)=temp; }
uint16_t p[9];
for(i = 0; i < 9; ++i, addr += NUMBER_OF_ADC_CHANNELS) // first we should prepare array for optmed
p[i] = ADC_array[addr];
PIX_SORT(p[1], p[2]) ; PIX_SORT(p[4], p[5]) ; PIX_SORT(p[7], p[8]) ;
PIX_SORT(p[0], p[1]) ; PIX_SORT(p[3], p[4]) ; PIX_SORT(p[6], p[7]) ;
PIX_SORT(p[1], p[2]) ; PIX_SORT(p[4], p[5]) ; PIX_SORT(p[7], p[8]) ;
PIX_SORT(p[0], p[3]) ; PIX_SORT(p[5], p[8]) ; PIX_SORT(p[4], p[7]) ;
PIX_SORT(p[3], p[6]) ; PIX_SORT(p[1], p[4]) ; PIX_SORT(p[2], p[5]) ;
PIX_SORT(p[4], p[7]) ; PIX_SORT(p[4], p[2]) ; PIX_SORT(p[6], p[4]) ;
PIX_SORT(p[4], p[2]) ;
return p[4];
#undef PIX_SORT
#undef PIX_SWAP
}
// return MCU temperature (degrees of celsius * 10)
int32_t getMCUtemp(){
getVdd();
// make correction on Vdd value
// int32_t temperature = (int32_t)ADC_array[4] * VddValue / 330;
int32_t ADval = getADCval(1);
int32_t temperature = (int32_t) *TEMP30_CAL_ADDR - ADval;
temperature *= (int32_t)(1100 - 300);
temperature /= (int32_t)(*TEMP30_CAL_ADDR - *TEMP110_CAL_ADDR);
temperature += 300;
return(temperature);
}
// return Vdd * 100 (V)
uint32_t getVdd(){
uint32_t vdd = ((uint32_t) *VREFINT_CAL_ADDR) * (uint32_t)330; // 3.3V
vdd /= getADCval(2);
return vdd;
}

29
F0-nolib/F0_testbrd/adc.h Normal file
View File

@ -0,0 +1,29 @@
/*
* This file is part of the Chiller project.
* Copyright 2018 Edward V. Emelianov <edward.emelianoff@gmail.com>.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef ADC_H
#define ADC_H
#include "stm32f0.h"
#define NUMBER_OF_ADC_CHANNELS (3)
extern uint16_t ADC_array[];
int32_t getMCUtemp();
uint32_t getVdd();
uint16_t getADCval(int nch);
#endif // ADC_H

View File

@ -0,0 +1,119 @@
/*
* geany_encoding=koi8-r
* hardware.c - hardware-dependent macros & functions
*
* Copyright 2018 Edward V. Emelianov <eddy@sao.ru, edward.emelianoff@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*
*/
#include "adc.h"
#include "hardware.h"
#include "usart.h"
static inline void gpio_setup(){
// here we turn on clocking for all periph.
RCC->AHBENR |= RCC_AHBENR_GPIOAEN | RCC_AHBENR_GPIOBEN | RCC_AHBENR_DMAEN;
// Set LEDS (PA0/4) as Oun & AF (PWM)
GPIOA->MODER = (GPIOA->MODER & ~(GPIO_MODER_MODER0 | GPIO_MODER_MODER4)
) |
GPIO_MODER_MODER0_O | GPIO_MODER_MODER4_AF ;
pin_set(LED0_port, LED0_pin); // clear LEDs
pin_set(LED1_port, LED1_pin);
// Buttons - PA14/15
GPIOA->PUPDR = (GPIOA->PUPDR & ~(GPIO_PUPDR_PUPDR14 | GPIO_PUPDR_PUPDR15)
) |
GPIO_PUPDR_PUPDR14_0 | GPIO_PUPDR_PUPDR15_0;
// alternate functions: PA4 - TIM14_CH1 (AF4)
GPIOA->AFR[0] = (GPIOA->AFR[0] &~ (GPIO_AFRL_AFRL4)) \
| (4 << (4 * 4)) ;
}
static inline void adc_setup(){
GPIOB->MODER = GPIO_MODER_MODER0_AI; // PB0 - ADC channel 8
uint16_t ctr = 0; // 0xfff0 - more than 1.3ms
// Enable clocking
/* (1) Enable the peripheral clock of the ADC */
/* (2) Start HSI14 RC oscillator */
/* (3) Wait HSI14 is ready */
RCC->APB2ENR |= RCC_APB2ENR_ADC1EN; /* (1) */
RCC->CR2 |= RCC_CR2_HSI14ON; /* (2) */
while ((RCC->CR2 & RCC_CR2_HSI14RDY) == 0 && ++ctr < 0xfff0){}; /* (3) */
// calibration
/* (1) Ensure that ADEN = 0 */
/* (2) Clear ADEN */
/* (3) Launch the calibration by setting ADCAL */
/* (4) Wait until ADCAL=0 */
if ((ADC1->CR & ADC_CR_ADEN) != 0){ /* (1) */
ADC1->CR &= (uint32_t)(~ADC_CR_ADEN); /* (2) */
}
ADC1->CR |= ADC_CR_ADCAL; /* (3) */
ctr = 0; // ADC calibration time is 5.9us
while ((ADC1->CR & ADC_CR_ADCAL) != 0 && ++ctr < 0xfff0){}; /* (4) */
// enable ADC
ctr = 0;
do{
ADC1->CR |= ADC_CR_ADEN;
}while ((ADC1->ISR & ADC_ISR_ADRDY) == 0 && ++ctr < 0xfff0);
// configure ADC
/* (1) Select HSI14 by writing 00 in CKMODE (reset value) */
/* (2) Select the continuous mode */
/* (3) Select CHSEL0..3 - ADC inputs, 16,17 - t. sensor and vref */
/* (4) Select a sampling mode of 111 i.e. 239.5 ADC clk to be greater than 17.1us */
/* (5) Wake-up the VREFINT and Temperature sensor (only for VBAT, Temp sensor and VRefInt) */
// ADC1->CFGR2 &= ~ADC_CFGR2_CKMODE; /* (1) */
ADC1->CFGR1 |= ADC_CFGR1_CONT; /* (2)*/
ADC1->CHSELR = ADC_CHSELR_CHSEL8 | ADC_CHSELR_CHSEL16 | ADC_CHSELR_CHSEL17; /* (3)*/
ADC1->SMPR |= ADC_SMPR_SMP_0 | ADC_SMPR_SMP_1 | ADC_SMPR_SMP_2; /* (4) */
ADC->CCR |= ADC_CCR_TSEN | ADC_CCR_VREFEN; /* (5) */
// configure DMA for ADC
// DMA for AIN
/* (1) Enable the peripheral clock on DMA */
/* (2) Enable DMA transfer on ADC and circular mode */
/* (3) Configure the peripheral data register address */
/* (4) Configure the memory address */
/* (5) Configure the number of DMA tranfer to be performs on DMA channel 1 */
/* (6) Configure increment, size, interrupts and circular mode */
/* (7) Enable DMA Channel 1 */
RCC->AHBENR |= RCC_AHBENR_DMA1EN; /* (1) */
ADC1->CFGR1 |= ADC_CFGR1_DMAEN | ADC_CFGR1_DMACFG; /* (2) */
DMA1_Channel1->CPAR = (uint32_t) (&(ADC1->DR)); /* (3) */
DMA1_Channel1->CMAR = (uint32_t)(ADC_array); /* (4) */
DMA1_Channel1->CNDTR = NUMBER_OF_ADC_CHANNELS * 9; /* (5) */
DMA1_Channel1->CCR |= DMA_CCR_MINC | DMA_CCR_MSIZE_0 | DMA_CCR_PSIZE_0 | DMA_CCR_CIRC; /* (6) */
DMA1_Channel1->CCR |= DMA_CCR_EN; /* (7) */
ADC1->CR |= ADC_CR_ADSTART; /* start the ADC conversions */
}
static inline void pwm_setup(){
RCC->APB1ENR |= RCC_APB1ENR_TIM14EN; // enable clocking for tim14
// PWM mode 2
TIM14->CCMR1 = TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_0;
TIM14->PSC = 5; // frequency - 8MHz for 31kHz PWM
// ARR for 8-bit PWM
TIM14->ARR = 254;
TIM14->CCR1 = 127; // half light
TIM14->BDTR |= TIM_BDTR_MOE; // start in OFF state
TIM14->CCER = TIM_CCER_CC1E; // enable PWM output
TIM14->CR1 |= TIM_CR1_CEN; // enable timer
}
void hw_setup(){
gpio_setup();
adc_setup();
pwm_setup();
}

View File

@ -0,0 +1,71 @@
/*
* geany_encoding=koi8-r
* hardware.h
*
* Copyright 2018 Edward V. Emelianov <eddy@sao.ru, edward.emelianoff@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*
*/
#pragma once
#ifndef __HARDWARE_H__
#define __HARDWARE_H__
#include "stm32f0.h"
#define CONCAT(a,b) a ## b
#define STR_HELPER(s) #s
#define STR(s) STR_HELPER(s)
#define FORMUSART(X) CONCAT(USART, X)
#define USARTX FORMUSART(USARTNUM)
#if USARTNUM == 2
#define USARTDMA DMA1_Channel4
#define DMAIRQn DMA1_Channel4_5_IRQn
#define USARTIRQn USART2_IRQn
#elif USARTNUM == 1
#define USARTDMA DMA1_Channel2
#define DMAIRQn DMA1_Channel2_3_IRQn
#define USARTIRQn USART1_IRQn
#else
#error "Wrong USARTNUM"
#endif
// LEDS: 0 - PA0, 1 - PA4
// LED0 - blinking each second
#define LED0_port GPIOA
#define LED0_pin (1<<0)
// LED1 - PWM
#define LED1_port GPIOA
#define LED1_pin (1<<4)
#define SET_LED_PWM(N) do{TIM14->CCR1 = (uint32_t)N;}while(0)
#define GET_LED_PWM() (uint8_t)(TIM14->CCR1)
// Buttons' state: PA14 (1)/PA15 (0)
#define GET_BTN0() ((GPIOA->IDR & (1<<15)) ? 0 : 1)
#define GET_BTN1() ((GPIOA->IDR & (1<<14)) ? 0 : 1)
// USB pullup (not used in STM32F0x2!) - PA13
#define USBPU_port GPIOA
#define USBPU_pin (1<<13)
#define LED_blink(x) pin_toggle(x ## _port, x ## _pin)
#define LED_on(x) pin_clear(x ## _port, x ## _pin)
#define LED_off(x) pin_set(x ## _port, x ## _pin)
void hw_setup();
#endif // __HARDWARE_H__

231
F0-nolib/F0_testbrd/main.c Normal file
View File

@ -0,0 +1,231 @@
/*
* main.c
*
* Copyright 2017 Edward V. Emelianoff <eddy@sao.ru, edward.emelianoff@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
#include "adc.h"
#include "hardware.h"
#include "usart.h"
#include "usb.h"
#include "usb_lib.h"
#include <string.h> // memcpy
volatile uint32_t Tms = 0;
/* Called when systick fires */
void sys_tick_handler(void){
++Tms;
}
void iwdg_setup(){
uint32_t tmout = 16000000;
/* Enable the peripheral clock RTC */
/* (1) Enable the LSI (40kHz) */
/* (2) Wait while it is not ready */
RCC->CSR |= RCC_CSR_LSION; /* (1) */
while((RCC->CSR & RCC_CSR_LSIRDY) != RCC_CSR_LSIRDY){if(--tmout == 0) break;} /* (2) */
/* Configure IWDG */
/* (1) Activate IWDG (not needed if done in option bytes) */
/* (2) Enable write access to IWDG registers */
/* (3) Set prescaler by 64 (1.6ms for each tick) */
/* (4) Set reload value to have a rollover each 2s */
/* (5) Check if flags are reset */
/* (6) Refresh counter */
IWDG->KR = IWDG_START; /* (1) */
IWDG->KR = IWDG_WRITE_ACCESS; /* (2) */
IWDG->PR = IWDG_PR_PR_1; /* (3) */
IWDG->RLR = 1250; /* (4) */
tmout = 16000000;
while(IWDG->SR){if(--tmout == 0) break;} /* (5) */
IWDG->KR = IWDG_REFRESH; /* (6) */
}
char *parse_cmd(char *buf){
static char btns[] = "BTN0=0, BTN1=0\n";
if(buf[1] != '\n') return buf;
uint8_t pwm;
switch(*buf){
case '+':
pwm = GET_LED_PWM();
if(pwm < 255){
SET_LED_PWM(pwm+1);
return u2str(GET_LED_PWM());
}else return "MAX!\n";
break;
case '-':
pwm = GET_LED_PWM();
if(pwm > 0){
SET_LED_PWM(pwm-1);
return u2str(GET_LED_PWM());
}else return "MIN!\n";
break;
case 'b':
btns[5] = GET_BTN0() + '0';
btns[13] = GET_BTN1() + '0';
return btns;
break;
case 'g':
return u2str(GET_LED_PWM());
break;
case 'A':
return u2str(getADCval(0));
break;
case 'L':
USB_send("Very long test string for USB (it's length is more than 64 bytes).\n"
"This is another part of the string! Can you see all of this?\n");
return "Long test sent\n";
break;
case 'R':
USB_send("Soft reset\n");
SEND("Soft reset\n");
NVIC_SystemReset();
break;
case 'S':
USB_send("Test string for USB\n");
return "Short test sent\n";
break;
case 'T':
return u2str(getMCUtemp());
break;
case 'V':
return u2str(getVdd());
break;
case 'W':
USB_send("Wait for reboot\n");
SEND("Wait for reboot\n");
while(1){nop();};
break;
default: // help
return
"'+'/'-' - increase/decrease PWM by 1\n"
"'b' - get buttons's state\n"
"'g' - get LED PWM value\n"
"'A' - get ADC8 value\n"
"'L' - send long string over USB\n"
"'R' - software reset\n"
"'S' - send short string over USB\n"
"'T' - MCU temperature\n"
"'V' - Vdd\n"
"'W' - test watchdog\n"
;
break;
}
return NULL;
}
// usb getline
char *get_USB(){
static char tmpbuf[129], *curptr = tmpbuf;
static int rest = 128;
int x = USB_receive(curptr, rest);
curptr[x] = 0;
if(!x) return NULL;
SEND("got: ");
SEND(curptr);
newline();
if(curptr[x-1] == '\n'){
curptr = tmpbuf;
rest = 128;
return tmpbuf;
}
curptr += x; rest -= x;
if(rest <= 0){ // buffer overflow
curptr = tmpbuf;
rest = 128;
}
return NULL;
}
int main(void){
uint32_t lastT = 0, lastB = 0;
sysreset();
SysTick_Config(6000, 1);
hw_setup();
usart_setup();
SEND("Hello! I'm ready.\n");
if(RCC->CSR & RCC_CSR_IWDGRSTF){ // watchdog reset occured
SEND("WDGRESET=1\n");
}
if(RCC->CSR & RCC_CSR_SFTRSTF){ // software reset occured
SEND("SOFTRESET=1\n");
}
RCC->CSR |= RCC_CSR_RMVF; // remove reset flags
USB_setup();
iwdg_setup();
while (1){
IWDG->KR = IWDG_REFRESH; // refresh watchdog
if(lastT > Tms || Tms - lastT > 499){
LED_blink(LED0);
lastT = Tms;
transmit_tbuf(); // non-blocking transmission of data from UART buffer every 0.5s
}
usb_proc();
int r = 0;
char *txt, *ans;
if((txt = get_USB())){
ans = parse_cmd(txt);
SEND("Received data over USB:\n");
SEND(txt);
newline();
if(ans) USB_send(ans);
}
if(usartrx()){ // usart1 received data, store in in buffer
r = usart_getline(&txt);
if(r){
txt[r] = 0;
ans = parse_cmd(txt);
if(ans){
usart_send(ans);
transmit_tbuf();
}
}
}
// check buttons - each 50ms
if(Tms - lastB > 49){
/*static uint8_t oldbtn0 = 0, oldbtn1 = 0;
uint8_t btn0 = GET_BTN0(), btn1 = GET_BTN1(), pwm = GET_LED_PWM();
// both: set to middle
if(oldbtn0 != btn0 && oldbtn1 != btn1){
SET_LED_PWM(127);
}else if(oldbtn0 != btn0){ // pressed/released
oldbtn0 = btn0;
if(pwm < 255) SET_LED_PWM(pwm+1);
}else if(oldbtn1 != btn1){
oldbtn1 = btn1;
if(pwm > 0) SET_LED_PWM(pwm-1);
}*/
lastB = Tms;
uint8_t btn0 = GET_BTN0(), btn1 = GET_BTN1(), pwm = GET_LED_PWM();
// both: set to middle
if(btn0 && btn1){
SET_LED_PWM(127);
}else if(btn0){
if(pwm < 255) SET_LED_PWM(pwm+1);
}else if(btn1){
if(pwm > 0) SET_LED_PWM(pwm-1);
}
}
}
return 0;
}

BIN
F0-nolib/F0_testbrd/pl2303.bin Executable file

Binary file not shown.

259
F0-nolib/F0_testbrd/usart.c Normal file
View File

@ -0,0 +1,259 @@
/*
* usart.c
*
* Copyright 2017 Edward V. Emelianoff <eddy@sao.ru, edward.emelianoff@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
#include "stm32f0.h"
#include "hardware.h"
#include "usart.h"
#include <string.h>
extern volatile uint32_t Tms;
static volatile int idatalen[2] = {0,0}; // received data line length (including '\n')
static volatile int odatalen[2] = {0,0};
volatile int linerdy = 0, // received data ready
dlen = 0, // length of data (including '\n') in current buffer
bufovr = 0, // input buffer overfull
txrdy = 1 // transmission done
;
int rbufno = 0, tbufno = 0; // current rbuf/tbuf numbers
static char rbuf[2][UARTBUFSZI], tbuf[2][UARTBUFSZO]; // receive & transmit buffers
static char *recvdata = NULL;
/**
* return length of received data (without trailing zero
*/
int usart_getline(char **line){
if(bufovr){
bufovr = 0;
linerdy = 0;
return 0;
}
*line = recvdata;
linerdy = 0;
return dlen;
}
// transmit current tbuf and swap buffers
void transmit_tbuf(){
uint32_t tmout = 16000000;
while(!txrdy){if(--tmout == 0) break;}; // wait for previos buffer transmission
register int l = odatalen[tbufno];
if(!l) return;
txrdy = 0;
odatalen[tbufno] = 0;
USARTDMA->CCR &= ~DMA_CCR_EN;
USARTDMA->CMAR = (uint32_t) tbuf[tbufno]; // mem
USARTDMA->CNDTR = l;
USARTDMA->CCR |= DMA_CCR_EN;
tbufno = !tbufno;
}
void usart_putchar(const char ch){
if(odatalen[tbufno] == UARTBUFSZO) transmit_tbuf();
tbuf[tbufno][odatalen[tbufno]++] = ch;
}
void usart_send(const char *str){
uint32_t x = 512;
while(*str && --x){
if(odatalen[tbufno] == UARTBUFSZO) transmit_tbuf();
tbuf[tbufno][odatalen[tbufno]++] = *str++;
}
}
void usart_sendn(const char *str, uint8_t L){
for(uint8_t i = 0; i < L; ++i){
if(odatalen[tbufno] == UARTBUFSZO) transmit_tbuf();
tbuf[tbufno][odatalen[tbufno]++] = *str++;
}
}
void newline(){
usart_putchar('\n');
transmit_tbuf();
}
void usart_setup(){
uint32_t tmout = 16000000;
// Nucleo's USART2 connected to VCP proxy of st-link
#if USARTNUM == 2
// setup pins: PA2 (Tx - AF1), PA15 (Rx - AF1)
// AF mode (AF1)
GPIOA->MODER = (GPIOA->MODER & ~(GPIO_MODER_MODER2|GPIO_MODER_MODER15))\
| (GPIO_MODER_MODER2_AF | GPIO_MODER_MODER15_AF);
GPIOA->AFR[0] = (GPIOA->AFR[0] &~GPIO_AFRH_AFRH2) | 1 << (2 * 4); // PA2
GPIOA->AFR[1] = (GPIOA->AFR[1] &~GPIO_AFRH_AFRH7) | 1 << (7 * 4); // PA15
RCC->APB1ENR |= RCC_APB1ENR_USART2EN; // clock
// USART1 of main board
#elif USARTNUM == 1
// PA9 - Tx, PA10 - Rx (AF1)
GPIOA->MODER = (GPIOA->MODER & ~(GPIO_MODER_MODER9 | GPIO_MODER_MODER10))\
| (GPIO_MODER_MODER9_AF | GPIO_MODER_MODER10_AF);
GPIOA->AFR[1] = (GPIOA->AFR[1] & ~(GPIO_AFRH_AFRH1 | GPIO_AFRH_AFRH2)) |
1 << (1 * 4) | 1 << (2 * 4); // PA9, PA10
RCC->APB2ENR |= RCC_APB2ENR_USART1EN;
#else
#error "Wrong USARTNUM"
#endif
// USARTX Tx DMA
USARTDMA->CPAR = (uint32_t) &USARTX->TDR; // periph
USARTDMA->CMAR = (uint32_t) tbuf; // mem
USARTDMA->CCR |= DMA_CCR_MINC | DMA_CCR_DIR | DMA_CCR_TCIE; // 8bit, mem++, mem->per, transcompl irq
// Tx CNDTR set @ each transmission due to data size
NVIC_SetPriority(DMAIRQn, 3);
NVIC_EnableIRQ(DMAIRQn);
NVIC_SetPriority(USARTIRQn, 0);
// setup usart1
USARTX->BRR = 480000 / 1152;
USARTX->CR3 = USART_CR3_DMAT; // enable DMA Tx
USARTX->CR1 = USART_CR1_TE | USART_CR1_RE | USART_CR1_UE; // 1start,8data,nstop; enable Rx,Tx,USART
while(!(USARTX->ISR & USART_ISR_TC)){if(--tmout == 0) break;} // polling idle frame Transmission
USARTX->ICR |= USART_ICR_TCCF; // clear TC flag
USARTX->CR1 |= USART_CR1_RXNEIE;
NVIC_EnableIRQ(USARTIRQn);
}
#if USARTNUM == 2
void usart2_isr(){
// USART1
#elif USARTNUM == 1
void usart1_isr(){
#else
#error "Wrong USARTNUM"
#endif
#ifdef CHECK_TMOUT
static uint32_t tmout = 0;
#endif
if(USARTX->ISR & USART_ISR_RXNE){ // RX not emty - receive next char
#ifdef CHECK_TMOUT
if(tmout && Tms >= tmout){ // set overflow flag
bufovr = 1;
idatalen[rbufno] = 0;
}
tmout = Tms + TIMEOUT_MS;
if(!tmout) tmout = 1; // prevent 0
#endif
// read RDR clears flag
uint8_t rb = USARTX->RDR;
if(idatalen[rbufno] < UARTBUFSZI){ // put next char into buf
rbuf[rbufno][idatalen[rbufno]++] = rb;
if(rb == '\n'){ // got newline - line ready
linerdy = 1;
dlen = idatalen[rbufno];
recvdata = rbuf[rbufno];
// prepare other buffer
rbufno = !rbufno;
idatalen[rbufno] = 0;
#ifdef CHECK_TMOUT
// clear timeout at line end
tmout = 0;
#endif
}
}else{ // buffer overrun
bufovr = 1;
idatalen[rbufno] = 0;
#ifdef CHECK_TMOUT
tmout = 0;
#endif
}
}
}
// return string buffer with val
char *u2str(uint32_t val){
static char bufa[11];
char bufb[10];
int l = 0, bpos = 0;
if(!val){
bufa[0] = '0';
l = 1;
}else{
while(val){
bufb[l++] = val % 10 + '0';
val /= 10;
}
int i;
bpos += l;
for(i = 0; i < l; ++i){
bufa[--bpos] = bufb[i];
}
}
bufa[l + bpos] = 0;
return bufa;
}
// print 32bit unsigned int
void printu(uint32_t val){
usart_send(u2str(val));
}
// print 32bit unsigned int as hex
void printuhex(uint32_t val){
usart_send("0x");
uint8_t *ptr = (uint8_t*)&val + 3, start = 1;
int i, j;
for(i = 0; i < 4; ++i, --ptr){
if(!*ptr && start) continue;
for(j = 1; j > -1; --j){
start = 0;
register uint8_t half = (*ptr >> (4*j)) & 0x0f;
if(half < 10) usart_putchar(half + '0');
else usart_putchar(half - 10 + 'a');
}
}
if(start){
usart_putchar('0');
usart_putchar('0');
}
}
// dump memory buffer
void hexdump(uint8_t *arr, uint16_t len){
for(uint16_t l = 0; l < len; ++l, ++arr){
for(int16_t j = 1; j > -1; --j){
register uint8_t half = (*arr >> (4*j)) & 0x0f;
if(half < 10) usart_putchar(half + '0');
else usart_putchar(half - 10 + 'a');
}
if(l % 16 == 15) usart_putchar('\n');
else if(l & 1) usart_putchar(' ');
}
}
#if USARTNUM == 2
void dma1_channel4_5_isr(){
if(DMA1->ISR & DMA_ISR_TCIF4){ // Tx
DMA1->IFCR |= DMA_IFCR_CTCIF4; // clear TC flag
txrdy = 1;
}
}
// USART1
#elif USARTNUM == 1
void dma1_channel2_3_isr(){
if(DMA1->ISR & DMA_ISR_TCIF2){ // Tx
DMA1->IFCR |= DMA_IFCR_CTCIF2; // clear TC flag
txrdy = 1;
}
}
#else
#error "Wrong USARTNUM"
#endif

View File

@ -0,0 +1,55 @@
/*
* usart.h
*
* Copyright 2017 Edward V. Emelianoff <eddy@sao.ru, edward.emelianoff@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
#pragma once
#ifndef __USART_H__
#define __USART_H__
#include "hardware.h"
// input and output buffers size
#define UARTBUFSZI (32)
#define UARTBUFSZO (512)
// timeout between data bytes
#ifndef TIMEOUT_MS
#define TIMEOUT_MS (1500)
#endif
// macro for static strings
#define SEND(str) usart_send(str)
#define usartrx() (linerdy)
#define usartovr() (bufovr)
extern volatile int linerdy, bufovr, txrdy;
void transmit_tbuf();
void usart_setup();
int usart_getline(char **line);
void usart_send(const char *str);
void usart_sendn(const char *str, uint8_t L);
void newline();
void usart_putchar(const char ch);
char *u2str(uint32_t val);
void printu(uint32_t val);
void printuhex(uint32_t val);
void hexdump(uint8_t *arr, uint16_t len);
#endif // __USART_H__

158
F0-nolib/F0_testbrd/usb.c Normal file
View File

@ -0,0 +1,158 @@
/*
* geany_encoding=koi8-r
* usb.c - base functions for different USB types
*
* Copyright 2018 Edward V. Emelianov <eddy@sao.ru, edward.emelianoff@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*
*/
#include "usb.h"
#include "usb_lib.h"
#include "usart.h"
#include <string.h> // memcpy, memmove
// incoming buffer size
#define IDATASZ (256)
static uint8_t incoming_data[IDATASZ];
static uint8_t ovfl = 0;
static uint16_t idatalen = 0;
static volatile uint8_t tx_succesfull = 0;
static int8_t usbON = 0; // ==1 when USB fully configured
// interrupt IN handler (never used?)
static uint16_t EP1_Handler(ep_t ep){
if (ep.rx_flag){
ep.status = SET_VALID_TX(ep.status);
ep.status = KEEP_STAT_RX(ep.status);
}else if (ep.tx_flag){
ep.status = SET_VALID_RX(ep.status);
ep.status = SET_STALL_TX(ep.status);
}
return ep.status;
}
// data IN/OUT handler
static uint16_t EP23_Handler(ep_t ep){
if(ep.rx_flag){
int rd = ep.rx_cnt, rest = IDATASZ - idatalen;
if(rd){
if(rd <= rest){
idatalen += EP_Read(2, &incoming_data[idatalen]);
ovfl = 0;
}else{
ep.status = SET_NAK_RX(ep.status);
ovfl = 1;
return ep.status;
}
}
// end of transaction: clear DTOGs
ep.status = CLEAR_DTOG_RX(ep.status);
ep.status = CLEAR_DTOG_TX(ep.status);
ep.status = SET_STALL_TX(ep.status);
}else if (ep.tx_flag){
ep.status = KEEP_STAT_TX(ep.status);
tx_succesfull = 1;
}
ep.status = SET_VALID_RX(ep.status);
return ep.status;
}
void USB_setup(){
RCC->APB1ENR |= RCC_APB1ENR_CRSEN | RCC_APB1ENR_USBEN; // enable CRS (hsi48 sync) & USB
RCC->CFGR3 &= ~RCC_CFGR3_USBSW; // reset USB
RCC->CR2 |= RCC_CR2_HSI48ON; // turn ON HSI48
uint32_t tmout = 16000000;
while(!(RCC->CR2 & RCC_CR2_HSI48RDY)){if(--tmout == 0) break;}
FLASH->ACR = FLASH_ACR_PRFTBE | FLASH_ACR_LATENCY;
CRS->CFGR &= ~CRS_CFGR_SYNCSRC;
CRS->CFGR |= CRS_CFGR_SYNCSRC_1; // USB SOF selected as sync source
CRS->CR |= CRS_CR_AUTOTRIMEN; // enable auto trim
CRS->CR |= CRS_CR_CEN; // enable freq counter & block CRS->CFGR as read-only
RCC->CFGR |= RCC_CFGR_SW;
// allow RESET and CTRM interrupts
USB->CNTR = USB_CNTR_RESETM | USB_CNTR_CTRM;
// clear flags
USB->ISTR = 0;
// and activate pullup
USB->BCDR |= USB_BCDR_DPPU;
NVIC_EnableIRQ(USB_IRQn);
}
void usb_proc(){
if(USB_GetState() == USB_CONFIGURE_STATE){ // USB configured - activate other endpoints
if(!usbON){ // endpoints not activated
// make new BULK endpoint
// Buffer have 1024 bytes, but last 256 we use for CAN bus (30.2 of RM: USB main features)
EP_Init(1, EP_TYPE_INTERRUPT, 10, 0, EP1_Handler); // IN1 - transmit
EP_Init(2, EP_TYPE_BULK, 0, USB_RXBUFSZ, EP23_Handler); // OUT2 - receive data
EP_Init(3, EP_TYPE_BULK, USB_TXBUFSZ, 0, EP23_Handler); // IN3 - transmit data
usbON = 1;
}
}else{
usbON = 0;
}
}
void USB_send(char *buf){
uint16_t l = 0, ctr = 0;
char *p = buf;
while(*p++) ++l;
while(l){
uint16_t s = (l > USB_TXBUFSZ) ? USB_TXBUFSZ : l;
tx_succesfull = 0;
EP_Write(3, (uint8_t*)&buf[ctr], s);
uint32_t ctra = 1000000;
while(--ctra && tx_succesfull == 0);
l -= s;
ctr += s;
}
}
/**
* @brief USB_receive
* @param buf (i) - buffer for received data
* @param bufsize - its size
* @return amount of received bytes
*/
int USB_receive(char *buf, int bufsize){
if(!bufsize || !idatalen) return 0;
USB->CNTR = 0;
int sz = (idatalen > bufsize) ? bufsize : idatalen, rest = idatalen - sz;
memcpy(buf, incoming_data, sz);
if(rest > 0){
memmove(incoming_data, &incoming_data[sz], rest);
idatalen = rest;
}else idatalen = 0;
if(ovfl){
EP23_Handler(endpoints[2]);
uint16_t epstatus = USB->EPnR[2];
epstatus = CLEAR_DTOG_RX(epstatus);
epstatus = SET_VALID_RX(epstatus);
USB->EPnR[2] = epstatus;
}
USB->CNTR = USB_CNTR_RESETM | USB_CNTR_CTRM;
return sz;
}
/**
* @brief USB_configured
* @return 1 if USB is in configured state
*/
int USB_configured(){
return usbON;
}

37
F0-nolib/F0_testbrd/usb.h Normal file
View File

@ -0,0 +1,37 @@
/*
* geany_encoding=koi8-r
* usb.h
*
* Copyright 2018 Edward V. Emelianov <eddy@sao.ru, edward.emelianoff@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*
*/
#pragma once
#ifndef __USB_H__
#define __USB_H__
#include "hardware.h"
#define BUFFSIZE (64)
void USB_setup();
void usb_proc();
void USB_send(char *buf);
int USB_receive(char *buf, int bufsize);
int USB_configured();
#endif // __USB_H__

View File

@ -0,0 +1,106 @@
/*
* geany_encoding=koi8-r
* usb_defs.h
*
* Copyright 2018 Edward V. Emelianov <eddy@sao.ru, edward.emelianoff@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*
*/
#pragma once
#ifndef __USB_DEFS_H__
#define __USB_DEFS_H__
#include <stm32f0xx.h>
/**
* Buffers size definition
**/
// !!! when working with CAN bus change USB_BTABLE_SIZE to 768 !!!
#define USB_BTABLE_SIZE 1024
// first 64 bytes of USB_BTABLE are registers!
#define USB_EP0_BASEADDR 64
// for USB FS EP0 buffers are from 8 to 64 bytes long (64 for PL2303)
#define USB_EP0_BUFSZ 64
// USB transmit buffer size (64 for PL2303)
#define USB_TXBUFSZ 64
// USB receive buffer size (64 for PL2303)
#define USB_RXBUFSZ 64
#define USB_BTABLE_BASE 0x40006000
#undef USB_BTABLE
#define USB_BTABLE ((USB_BtableDef *)(USB_BTABLE_BASE))
#define USB_ISTR_EPID 0x0000000F
#define USB_FNR_LSOF_0 0x00000800
#define USB_FNR_lSOF_1 0x00001000
#define USB_LPMCSR_BESL_0 0x00000010
#define USB_LPMCSR_BESL_1 0x00000020
#define USB_LPMCSR_BESL_2 0x00000040
#define USB_LPMCSR_BESL_3 0x00000080
#define USB_EPnR_CTR_RX 0x00008000
#define USB_EPnR_DTOG_RX 0x00004000
#define USB_EPnR_STAT_RX 0x00003000
#define USB_EPnR_STAT_RX_0 0x00001000
#define USB_EPnR_STAT_RX_1 0x00002000
#define USB_EPnR_SETUP 0x00000800
#define USB_EPnR_EP_TYPE 0x00000600
#define USB_EPnR_EP_TYPE_0 0x00000200
#define USB_EPnR_EP_TYPE_1 0x00000400
#define USB_EPnR_EP_KIND 0x00000100
#define USB_EPnR_CTR_TX 0x00000080
#define USB_EPnR_DTOG_TX 0x00000040
#define USB_EPnR_STAT_TX 0x00000030
#define USB_EPnR_STAT_TX_0 0x00000010
#define USB_EPnR_STAT_TX_1 0x00000020
#define USB_EPnR_EA 0x0000000F
#define USB_COUNTn_RX_BLSIZE 0x00008000
#define USB_COUNTn_NUM_BLOCK 0x00007C00
#define USB_COUNTn_RX 0x0000003F
#define USB_TypeDef USB_TypeDef_custom
typedef struct{
__IO uint32_t EPnR[8];
__IO uint32_t RESERVED1;
__IO uint32_t RESERVED2;
__IO uint32_t RESERVED3;
__IO uint32_t RESERVED4;
__IO uint32_t RESERVED5;
__IO uint32_t RESERVED6;
__IO uint32_t RESERVED7;
__IO uint32_t RESERVED8;
__IO uint32_t CNTR;
__IO uint32_t ISTR;
__IO uint32_t FNR;
__IO uint32_t DADDR;
__IO uint32_t BTABLE;
__IO uint32_t LPMCSR;
__IO uint32_t BCDR;
} USB_TypeDef;
typedef struct{
__IO uint16_t USB_ADDR_TX;
__IO uint16_t USB_COUNT_TX;
__IO uint16_t USB_ADDR_RX;
__IO uint16_t USB_COUNT_RX;
} USB_EPDATA_TypeDef;
typedef struct{
__IO USB_EPDATA_TypeDef EP[8];
} USB_BtableDef;
#endif // __USB_DEFS_H__

View File

@ -0,0 +1,484 @@
/*
* geany_encoding=koi8-r
* usb_lib.c
*
* Copyright 2018 Edward V. Emelianov <eddy@sao.ru, edward.emelianoff@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*
*/
#include <stdint.h>
#include "usb_lib.h"
#include <string.h> // memcpy
#include "usart.h"
ep_t endpoints[ENDPOINTS_NUM];
static usb_dev_t USB_Dev;
static usb_LineCoding lineCoding = {115200, 0, 0, 8};
static config_pack_t setup_packet;
static uint8_t ep0databuf[EP0DATABUF_SIZE];
static uint8_t ep0dbuflen = 0;
usb_LineCoding getLineCoding(){return lineCoding;}
// definition of parts common for USB_DeviceDescriptor & USB_DeviceQualifierDescriptor
#define bcdUSB_L 0x10
#define bcdUSB_H 0x01
#define bDeviceClass 0
#define bDeviceSubClass 0
#define bDeviceProtocol 0
#define bNumConfigurations 1
static const uint8_t USB_DeviceDescriptor[] = {
18, // bLength
0x01, // bDescriptorType - Device descriptor
bcdUSB_L, // bcdUSB_L - 1.10
bcdUSB_H, // bcdUSB_H
bDeviceClass, // bDeviceClass - USB_COMM
bDeviceSubClass, // bDeviceSubClass
bDeviceProtocol, // bDeviceProtocol
USB_EP0_BUFSZ, // bMaxPacketSize
0x7b, // idVendor_L PL2303: VID=0x067b, PID=0x2303
0x06, // idVendor_H
0x03, // idProduct_L
0x23, // idProduct_H
0x00, // bcdDevice_Ver_L
0x03, // bcdDevice_Ver_H
0x01, // iManufacturer
0x02, // iProduct
0x00, // iSerialNumber
bNumConfigurations // bNumConfigurations
};
static const uint8_t USB_DeviceQualifierDescriptor[] = {
10, //bLength
0x06, // bDescriptorType - Device qualifier
bcdUSB_L, // bcdUSB_L
bcdUSB_H, // bcdUSB_H
bDeviceClass, // bDeviceClass
bDeviceSubClass, // bDeviceSubClass
bDeviceProtocol, // bDeviceProtocol
USB_EP0_BUFSZ, // bMaxPacketSize0
bNumConfigurations, // bNumConfigurations
0x00 // Reserved
};
static const uint8_t USB_ConfigDescriptor[] = {
/*Configuration Descriptor*/
0x09, /* bLength: Configuration Descriptor size */
0x02, /* bDescriptorType: Configuration */
39, /* wTotalLength:no of returned bytes */
0x00,
0x01, /* bNumInterfaces: 1 interface */
0x01, /* bConfigurationValue: Configuration value */
0x00, /* iConfiguration: Index of string descriptor describing the configuration */
0xa0, /* bmAttributes - Bus powered, Remote wakeup */
0x32, /* MaxPower 100 mA */
/*---------------------------------------------------------------------------*/
/*Interface Descriptor */
0x09, /* bLength: Interface Descriptor size */
0x04, /* bDescriptorType: Interface */
0x00, /* bInterfaceNumber: Number of Interface */
0x00, /* bAlternateSetting: Alternate setting */
0x03, /* bNumEndpoints: 3 endpoints used */
0xff, /* bInterfaceClass */
0x00, /* bInterfaceSubClass */
0x00, /* bInterfaceProtocol */
0x00, /* iInterface: */
///////////////////////////////////////////////////
/*Endpoint 1 Descriptor*/
0x07, /* bLength: Endpoint Descriptor size */
0x05, /* bDescriptorType: Endpoint */
0x81, /* bEndpointAddress IN1 */
0x03, /* bmAttributes: Interrupt */
0x0a, /* wMaxPacketSize LO: */
0x00, /* wMaxPacketSize HI: */
0x01, /* bInterval: */
/*Endpoint OUT2 Descriptor*/
0x07, /* bLength: Endpoint Descriptor size */
0x05, /* bDescriptorType: Endpoint */
0x02, /* bEndpointAddress: OUT2 */
0x02, /* bmAttributes: Bulk */
(USB_RXBUFSZ & 0xff), /* wMaxPacketSize: 64 */
(USB_RXBUFSZ >> 8),
0x00, /* bInterval: ignore for Bulk transfer */
/*Endpoint IN3 Descriptor*/
0x07, /* bLength: Endpoint Descriptor size */
0x05, /* bDescriptorType: Endpoint */
0x83, /* bEndpointAddress IN3 */
0x02, /* bmAttributes: Bulk */
(USB_TXBUFSZ & 0xff), /* wMaxPacketSize: 64 */
(USB_TXBUFSZ >> 8),
0x00, /* bInterval: ignore for Bulk transfer */
};
_USB_LANG_ID_(USB_StringLangDescriptor, LANG_US);
// these descriptors are not used in PL2303 emulator!
_USB_STRING_(USB_StringSerialDescriptor, u"0");
_USB_STRING_(USB_StringManufacturingDescriptor, u"Prolific Technology Inc.");
_USB_STRING_(USB_StringProdDescriptor, u"USB-Serial Controller");
/*
* default handlers
*/
// SET_LINE_CODING
void WEAK linecoding_handler(usb_LineCoding __attribute__((unused)) *lc){
}
// SET_CONTROL_LINE_STATE
void WEAK clstate_handler(uint16_t __attribute__((unused)) val){
}
// SEND_BREAK
void WEAK break_handler(){
}
// handler of vendor requests
void WEAK vendor_handler(config_pack_t *packet){
if(packet->bmRequestType & 0x80){ // read
uint8_t c;
switch(packet->wValue){
case 0x8484:
c = 2;
break;
case 0x0080:
c = 1;
break;
case 0x8686:
c = 0xaa;
break;
default:
c = 0;
}
EP_WriteIRQ(0, &c, 1);
}else{ // write ZLP
EP_WriteIRQ(0, (uint8_t *)0, 0);
}
}
static void wr0(const uint8_t *buf, uint16_t size){
if(setup_packet.wLength < size) size = setup_packet.wLength;
EP_WriteIRQ(0, buf, size);
}
static inline void get_descriptor(){
switch(setup_packet.wValue){
case DEVICE_DESCRIPTOR:
wr0(USB_DeviceDescriptor, sizeof(USB_DeviceDescriptor));
break;
case CONFIGURATION_DESCRIPTOR:
wr0(USB_ConfigDescriptor, sizeof(USB_ConfigDescriptor));
break;
case STRING_LANG_DESCRIPTOR:
wr0((const uint8_t *)&USB_StringLangDescriptor, STRING_LANG_DESCRIPTOR_SIZE_BYTE);
break;
case STRING_MAN_DESCRIPTOR:
wr0((const uint8_t *)&USB_StringManufacturingDescriptor, USB_StringManufacturingDescriptor.bLength);
break;
case STRING_PROD_DESCRIPTOR:
wr0((const uint8_t *)&USB_StringProdDescriptor, USB_StringProdDescriptor.bLength);
break;
case STRING_SN_DESCRIPTOR:
wr0((const uint8_t *)&USB_StringSerialDescriptor, USB_StringSerialDescriptor.bLength);
break;
case DEVICE_QUALIFIER_DESCRIPTOR:
wr0(USB_DeviceQualifierDescriptor, USB_DeviceQualifierDescriptor[0]);
break;
default:
break;
}
}
static uint8_t configuration = 0; // reply for GET_CONFIGURATION (==1 if configured)
static inline void std_d2h_req(){
uint16_t status = 0; // bus powered
switch(setup_packet.bRequest){
case GET_DESCRIPTOR:
get_descriptor();
break;
case GET_STATUS:
EP_WriteIRQ(0, (uint8_t *)&status, 2); // send status: Bus Powered
break;
case GET_CONFIGURATION:
EP_WriteIRQ(0, &configuration, 1);
break;
default:
break;
}
}
static inline void std_h2d_req(){
switch(setup_packet.bRequest){
case SET_ADDRESS:
// new address will be assigned later - after acknowlegement or request to host
USB_Dev.USB_Addr = setup_packet.wValue;
break;
case SET_CONFIGURATION:
// Now device configured
USB_Dev.USB_Status = USB_CONFIGURE_STATE;
configuration = setup_packet.wValue;
break;
default:
break;
}
}
/*
bmRequestType: 76543210
7 direction: 0 - host->device, 1 - device->host
65 type: 0 - standard, 1 - class, 2 - vendor
4..0 getter: 0 - device, 1 - interface, 2 - endpoint, 3 - other
*/
/**
* Endpoint0 (control) handler
* @param ep - endpoint state
* @return data written to EP0R
*/
static uint16_t EP0_Handler(ep_t ep){
uint16_t epstatus = ep.status; // EP0R on input -> return this value after modifications
uint8_t reqtype = setup_packet.bmRequestType & 0x7f;
uint8_t dev2host = (setup_packet.bmRequestType & 0x80) ? 1 : 0;
if ((ep.rx_flag) && (ep.setup_flag)){
switch(reqtype){
case STANDARD_DEVICE_REQUEST_TYPE: // standard device request
if(dev2host){
std_d2h_req();
}else{
std_h2d_req();
// send ZLP
EP_WriteIRQ(0, (uint8_t *)0, 0);
}
epstatus = SET_NAK_RX(epstatus);
epstatus = SET_VALID_TX(epstatus);
break;
case STANDARD_ENDPOINT_REQUEST_TYPE: // standard endpoint request
if(setup_packet.bRequest == CLEAR_FEATURE){
// send ZLP
EP_WriteIRQ(0, (uint8_t *)0, 0);
epstatus = SET_NAK_RX(epstatus);
epstatus = SET_VALID_TX(epstatus);
}
break;
case VENDOR_REQUEST_TYPE:
vendor_handler(&setup_packet);
epstatus = SET_NAK_RX(epstatus);
epstatus = SET_VALID_TX(epstatus);
break;
case CONTROL_REQUEST_TYPE:
switch(setup_packet.bRequest){
case GET_LINE_CODING:
EP_WriteIRQ(0, (uint8_t*)&lineCoding, sizeof(lineCoding));
break;
case SET_LINE_CODING: // omit this for next stage, when data will come
break;
case SET_CONTROL_LINE_STATE:
clstate_handler(setup_packet.wValue);
break;
case SEND_BREAK:
break_handler();
break;
default:
break;
}
if(!dev2host) EP_WriteIRQ(0, (uint8_t *)0, 0); // write acknowledgement
epstatus = SET_VALID_RX(epstatus);
epstatus = SET_VALID_TX(epstatus);
break;
default:
EP_WriteIRQ(0, (uint8_t *)0, 0);
epstatus = SET_NAK_RX(epstatus);
epstatus = SET_VALID_TX(epstatus);
}
}else if (ep.rx_flag){ // got data over EP0 or host acknowlegement
if(ep.rx_cnt){
EP_WriteIRQ(0, (uint8_t *)0, 0);
if(setup_packet.bRequest == SET_LINE_CODING){
linecoding_handler((usb_LineCoding*)ep0databuf);
}
}
// Close transaction
epstatus = CLEAR_DTOG_RX(epstatus);
epstatus = CLEAR_DTOG_TX(epstatus);
// wait for new data from host
epstatus = SET_VALID_RX(epstatus);
epstatus = SET_STALL_TX(epstatus);
} else if (ep.tx_flag){ // package transmitted
// now we can change address after enumeration
if ((USB->DADDR & USB_DADDR_ADD) != USB_Dev.USB_Addr){
USB->DADDR = USB_DADDR_EF | USB_Dev.USB_Addr;
// change state to ADRESSED
USB_Dev.USB_Status = USB_ADRESSED_STATE;
}
// end of transaction
epstatus = CLEAR_DTOG_RX(epstatus);
epstatus = CLEAR_DTOG_TX(epstatus);
epstatus = SET_VALID_RX(epstatus);
epstatus = SET_VALID_TX(epstatus);
}
return epstatus;
}
static uint16_t lastaddr = USB_EP0_BASEADDR;
/**
* Endpoint initialisation
* !!! when working with CAN bus change USB_BTABLE_SIZE to 768 !!!
* @param number - EP num (0...7)
* @param type - EP type (EP_TYPE_BULK, EP_TYPE_CONTROL, EP_TYPE_ISO, EP_TYPE_INTERRUPT)
* @param txsz - transmission buffer size @ USB/CAN buffer
* @param rxsz - reception buffer size @ USB/CAN buffer
* @param uint16_t (*func)(ep_t *ep) - EP handler function
* @return 0 if all OK
*/
int EP_Init(uint8_t number, uint8_t type, uint16_t txsz, uint16_t rxsz, uint16_t (*func)(ep_t ep)){
if(number >= ENDPOINTS_NUM) return 4; // out of configured amount
if(txsz > USB_BTABLE_SIZE || rxsz > USB_BTABLE_SIZE) return 1; // buffer too large
if(lastaddr + txsz + rxsz >= USB_BTABLE_SIZE) return 2; // out of btable
USB->EPnR[number] = (type << 9) | (number & USB_EPnR_EA);
USB->EPnR[number] ^= USB_EPnR_STAT_RX | USB_EPnR_STAT_TX_1;
if(rxsz & 1 || rxsz > 992) return 3; // wrong rx buffer size
uint16_t countrx = 0;
if(rxsz < 64) countrx = rxsz / 2;
else{
if(rxsz & 0x1f) return 3; // should be multiple of 32
countrx = 31 + rxsz / 32;
}
USB_BTABLE->EP[number].USB_ADDR_TX = lastaddr;
endpoints[number].tx_buf = (uint16_t *)(USB_BTABLE_BASE + lastaddr);
lastaddr += txsz;
USB_BTABLE->EP[number].USB_COUNT_TX = 0;
USB_BTABLE->EP[number].USB_ADDR_RX = lastaddr;
endpoints[number].rx_buf = (uint8_t *)(USB_BTABLE_BASE + lastaddr);
lastaddr += rxsz;
// buffer size: Table127 of RM
USB_BTABLE->EP[number].USB_COUNT_RX = countrx << 10;
endpoints[number].func = func;
return 0;
}
// standard IRQ handler
void usb_isr(){
if (USB->ISTR & USB_ISTR_RESET){
// Reinit registers
USB->CNTR = USB_CNTR_RESETM | USB_CNTR_CTRM;
USB->ISTR = 0;
// Endpoint 0 - CONTROL
// ON USB LS size of EP0 may be 8 bytes, but on FS it should be 64 bytes!
lastaddr = USB_EP0_BASEADDR; // roll back to beginning of buffer
EP_Init(0, EP_TYPE_CONTROL, USB_EP0_BUFSZ, USB_EP0_BUFSZ, EP0_Handler);
// clear address, leave only enable bit
USB->DADDR = USB_DADDR_EF;
// state is default - wait for enumeration
USB_Dev.USB_Status = USB_DEFAULT_STATE;
}
if(USB->ISTR & USB_ISTR_CTR){
// EP number
uint8_t n = USB->ISTR & USB_ISTR_EPID;
// copy status register
uint16_t epstatus = USB->EPnR[n];
// Calculate flags
endpoints[n].rx_flag = (epstatus & USB_EPnR_CTR_RX) ? 1 : 0;
endpoints[n].setup_flag = (epstatus & USB_EPnR_SETUP) ? 1 : 0;
endpoints[n].tx_flag = (epstatus & USB_EPnR_CTR_TX) ? 1 : 0;
// copy received bytes amount
endpoints[n].rx_cnt = USB_BTABLE->EP[n].USB_COUNT_RX & 0x3FF; // low 10 bits is counter
// check direction
if(USB->ISTR & USB_ISTR_DIR){ // OUT interrupt - receive data, CTR_RX==1 (if CTR_TX == 1 - two pending transactions: receive following by transmit)
if(n == 0){ // control endpoint
if(epstatus & USB_EPnR_SETUP){ // setup packet -> copy data to conf_pack
memcpy(&setup_packet, endpoints[0].rx_buf, sizeof(setup_packet));
ep0dbuflen = 0;
// interrupt handler will be called later
}else if(epstatus & USB_EPnR_CTR_RX){ // data packet -> push received data to ep0databuf
ep0dbuflen = endpoints[0].rx_cnt;
memcpy(ep0databuf, endpoints[0].rx_buf, ep0dbuflen);
}
}
}else{ // IN interrupt - transmit data, only CTR_TX == 1
// enumeration end could be here (if EP0)
}
// prepare status field for EP handler
endpoints[n].status = epstatus;
// call EP handler (even if it will change EPnR, it should return new status)
epstatus = endpoints[n].func(endpoints[n]);
// keep DTOG state
epstatus = KEEP_DTOG_TX(epstatus);
epstatus = KEEP_DTOG_RX(epstatus);
// clear all RX/TX flags
epstatus = CLEAR_CTR_RX(epstatus);
epstatus = CLEAR_CTR_TX(epstatus);
// refresh EPnR
USB->EPnR[n] = epstatus;
}
}
/**
* Write data to EP buffer (called from IRQ handler)
* @param number - EP number
* @param *buf - array with data
* @param size - its size
*/
void EP_WriteIRQ(uint8_t number, const uint8_t *buf, uint16_t size){
uint8_t i;
if(size > USB_TXBUFSZ) size = USB_TXBUFSZ;
uint16_t N2 = (size + 1) >> 1;
// the buffer is 16-bit, so we should copy data as it would be uint16_t
uint16_t *buf16 = (uint16_t *)buf;
for (i = 0; i < N2; i++){
endpoints[number].tx_buf[i] = buf16[i];
}
USB_BTABLE->EP[number].USB_COUNT_TX = size;
}
/**
* Write data to EP buffer (called outside IRQ handler)
* @param number - EP number
* @param *buf - array with data
* @param size - its size
*/
void EP_Write(uint8_t number, const uint8_t *buf, uint16_t size){
uint16_t status = USB->EPnR[number];
EP_WriteIRQ(number, buf, size);
status = SET_NAK_RX(status);
status = SET_VALID_TX(status);
status = KEEP_DTOG_TX(status);
status = KEEP_DTOG_RX(status);
USB->EPnR[number] = status;
}
/*
* Copy data from EP buffer into user buffer area
* @param *buf - user array for data
* @return amount of data read
*/
int EP_Read(uint8_t number, uint8_t *buf){
int n = endpoints[number].rx_cnt;
if(n){
for(int i = 0; i < n; ++i)
buf[i] = endpoints[number].rx_buf[i];
}
return n;
}
// USB status
uint8_t USB_GetState(){
return USB_Dev.USB_Status;
}

View File

@ -0,0 +1,202 @@
/*
* geany_encoding=koi8-r
* usb_lib.h
*
* Copyright 2018 Edward V. Emelianov <eddy@sao.ru, edward.emelianoff@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*
*/
#pragma once
#ifndef __USB_LIB_H__
#define __USB_LIB_H__
#include <wchar.h>
#include "usb_defs.h"
#define EP0DATABUF_SIZE (64)
// Max EP amount (EP0 + other used)
#define ENDPOINTS_NUM 4
// bmRequestType & 0x7f
#define STANDARD_DEVICE_REQUEST_TYPE 0
#define STANDARD_ENDPOINT_REQUEST_TYPE 2
#define VENDOR_REQUEST_TYPE 0x40
#define CONTROL_REQUEST_TYPE 0x21
// bRequest, standard; for bmRequestType == 0x80
#define GET_STATUS 0x00
#define GET_DESCRIPTOR 0x06
#define GET_CONFIGURATION 0x08
// for bmRequestType == 0
#define CLEAR_FEATURE 0x01
#define SET_FEATURE 0x03 // unused
#define SET_ADDRESS 0x05
#define SET_DESCRIPTOR 0x07 // unused
#define SET_CONFIGURATION 0x09
// for bmRequestType == 0x81, 1 or 0xB2
#define GET_INTERFACE 0x0A // unused
#define SET_INTERFACE 0x0B // unused
#define SYNC_FRAME 0x0C // unused
#define VENDOR_REQUEST 0x01 // unused
// Class-Specific Control Requests
#define SEND_ENCAPSULATED_COMMAND 0x00 // unused
#define GET_ENCAPSULATED_RESPONSE 0x01 // unused
#define SET_COMM_FEATURE 0x02 // unused
#define GET_COMM_FEATURE 0x03 // unused
#define CLEAR_COMM_FEATURE 0x04 // unused
#define SET_LINE_CODING 0x20
#define GET_LINE_CODING 0x21
#define SET_CONTROL_LINE_STATE 0x22
#define SEND_BREAK 0x23
// control line states
#define CONTROL_DTR 0x01
#define CONTROL_RTS 0x02
// wValue
#define DEVICE_DESCRIPTOR 0x100
#define CONFIGURATION_DESCRIPTOR 0x200
#define STRING_LANG_DESCRIPTOR 0x300
#define STRING_MAN_DESCRIPTOR 0x301
#define STRING_PROD_DESCRIPTOR 0x302
#define STRING_SN_DESCRIPTOR 0x303
#define DEVICE_QUALIFIER_DESCRIPTOR 0x600
// EPnR bits manipulation
#define CLEAR_DTOG_RX(R) (R & USB_EPnR_DTOG_RX) ? R : (R & (~USB_EPnR_DTOG_RX))
#define SET_DTOG_RX(R) (R & USB_EPnR_DTOG_RX) ? (R & (~USB_EPnR_DTOG_RX)) : R
#define TOGGLE_DTOG_RX(R) (R | USB_EPnR_DTOG_RX)
#define KEEP_DTOG_RX(R) (R & (~USB_EPnR_DTOG_RX))
#define CLEAR_DTOG_TX(R) (R & USB_EPnR_DTOG_TX) ? R : (R & (~USB_EPnR_DTOG_TX))
#define SET_DTOG_TX(R) (R & USB_EPnR_DTOG_TX) ? (R & (~USB_EPnR_DTOG_TX)) : R
#define TOGGLE_DTOG_TX(R) (R | USB_EPnR_DTOG_TX)
#define KEEP_DTOG_TX(R) (R & (~USB_EPnR_DTOG_TX))
#define SET_VALID_RX(R) ((R & USB_EPnR_STAT_RX) ^ USB_EPnR_STAT_RX) | (R & (~USB_EPnR_STAT_RX))
#define SET_NAK_RX(R) ((R & USB_EPnR_STAT_RX) ^ USB_EPnR_STAT_RX_1) | (R & (~USB_EPnR_STAT_RX))
#define SET_STALL_RX(R) ((R & USB_EPnR_STAT_RX) ^ USB_EPnR_STAT_RX_0) | (R & (~USB_EPnR_STAT_RX))
#define KEEP_STAT_RX(R) (R & (~USB_EPnR_STAT_RX))
#define SET_VALID_TX(R) ((R & USB_EPnR_STAT_TX) ^ USB_EPnR_STAT_TX) | (R & (~USB_EPnR_STAT_TX))
#define SET_NAK_TX(R) ((R & USB_EPnR_STAT_TX) ^ USB_EPnR_STAT_TX_1) | (R & (~USB_EPnR_STAT_TX))
#define SET_STALL_TX(R) ((R & USB_EPnR_STAT_TX) ^ USB_EPnR_STAT_TX_0) | (R & (~USB_EPnR_STAT_TX))
#define KEEP_STAT_TX(R) (R & (~USB_EPnR_STAT_TX))
#define CLEAR_CTR_RX(R) (R & (~USB_EPnR_CTR_RX))
#define CLEAR_CTR_TX(R) (R & (~USB_EPnR_CTR_TX))
#define CLEAR_CTR_RX_TX(R) (R & (~(USB_EPnR_CTR_TX | USB_EPnR_CTR_RX)))
// USB state: uninitialized, addressed, ready for use
#define USB_DEFAULT_STATE 0
#define USB_ADRESSED_STATE 1
#define USB_CONFIGURE_STATE 2
// EP types
#define EP_TYPE_BULK 0x00
#define EP_TYPE_CONTROL 0x01
#define EP_TYPE_ISO 0x02
#define EP_TYPE_INTERRUPT 0x03
#define LANG_US (uint16_t)0x0409
#define _USB_STRING_(name, str) \
static const struct name \
{ \
uint8_t bLength; \
uint8_t bDescriptorType; \
uint16_t bString[(sizeof(str) - 2) / 2]; \
\
} \
name = {sizeof(name), 0x03, str}
#define _USB_LANG_ID_(name, lng_id) \
\
static const struct name \
{ \
uint8_t bLength; \
uint8_t bDescriptorType; \
uint16_t bString; \
\
} \
name = {0x04, 0x03, lng_id}
#define STRING_LANG_DESCRIPTOR_SIZE_BYTE (4)
// EP0 configuration packet
typedef struct {
uint8_t bmRequestType;
uint8_t bRequest;
uint16_t wValue;
uint16_t wIndex;
uint16_t wLength;
} config_pack_t;
// endpoints state
typedef struct __ep_t{
uint16_t *tx_buf; // transmission buffer address
uint8_t *rx_buf; // reception buffer address
uint16_t (*func)(); // endpoint action function
uint16_t status; // status flags
unsigned rx_cnt : 10; // received data counter
unsigned tx_flag : 1; // transmission flag
unsigned rx_flag : 1; // reception flag
unsigned setup_flag : 1; // this is setup packet (only for EP0)
} ep_t;
// USB status & its address
typedef struct {
uint8_t USB_Status;
uint16_t USB_Addr;
}usb_dev_t;
typedef struct {
uint32_t dwDTERate;
uint8_t bCharFormat;
#define USB_CDC_1_STOP_BITS 0
#define USB_CDC_1_5_STOP_BITS 1
#define USB_CDC_2_STOP_BITS 2
uint8_t bParityType;
#define USB_CDC_NO_PARITY 0
#define USB_CDC_ODD_PARITY 1
#define USB_CDC_EVEN_PARITY 2
#define USB_CDC_MARK_PARITY 3
#define USB_CDC_SPACE_PARITY 4
uint8_t bDataBits;
} __attribute__ ((packed)) usb_LineCoding;
typedef struct {
uint8_t bmRequestType;
uint8_t bNotificationType;
uint16_t wValue;
uint16_t wIndex;
uint16_t wLength;
} __attribute__ ((packed)) usb_cdc_notification;
extern ep_t endpoints[];
void USB_Init();
uint8_t USB_GetState();
int EP_Init(uint8_t number, uint8_t type, uint16_t txsz, uint16_t rxsz, uint16_t (*func)(ep_t ep));
void EP_WriteIRQ(uint8_t number, const uint8_t *buf, uint16_t size);
void EP_Write(uint8_t number, const uint8_t *buf, uint16_t size);
int EP_Read(uint8_t number, uint8_t *buf);
usb_LineCoding getLineCoding();
void WEAK linecoding_handler(usb_LineCoding *lc);
void WEAK clstate_handler(uint16_t val);
void WEAK break_handler();
void WEAK vendor_handler(config_pack_t *packet);
#endif // __USB_LIB_H__

View File

@ -1 +0,0 @@
including files

View File

@ -1,2 +0,0 @@
#!/bin/sh
CFLAGS="-IF0 -Icm -DSTM32F042x6" geany -g stm32f042.c.tags F0/stm32f042x6.h F0/stm32f0.h F0/stm32f0xx.h cm/core_cm0.h cm/core_cmFunc.h cm/core_cmInstr.h cm/core_cmSimd.h startup/vector.c

View File

@ -0,0 +1,12 @@
/* Linker script for STM32F072x8, 64K flash, 16K RAM. */
/* Define memory regions. */
MEMORY
{
rom (rx) : ORIGIN = 0x08000000, LENGTH = 64K
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 16K
}
/* Include the common ld script. */
INCLUDE stm32f0.ld

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@ -32,6 +32,7 @@ static uint8_t incoming_data[IDATASZ];
static uint8_t ovfl = 0; static uint8_t ovfl = 0;
static uint16_t idatalen = 0; static uint16_t idatalen = 0;
static int8_t usbON = 0; // ==1 when USB fully configured static int8_t usbON = 0; // ==1 when USB fully configured
static volatile uint8_t tx_succesfull = 0;
// interrupt IN handler (never used?) // interrupt IN handler (never used?)
static uint16_t EP1_Handler(ep_t ep){ static uint16_t EP1_Handler(ep_t ep){
@ -80,6 +81,7 @@ static uint16_t EP23_Handler(ep_t ep){
ep.status = SET_STALL_TX(ep.status); ep.status = SET_STALL_TX(ep.status);
}else if (ep.tx_flag){ }else if (ep.tx_flag){
ep.status = KEEP_STAT_TX(ep.status); ep.status = KEEP_STAT_TX(ep.status);
tx_succesfull = 1;
} }
ep.status = SET_VALID_RX(ep.status); ep.status = SET_VALID_RX(ep.status);
return ep.status; return ep.status;
@ -128,7 +130,10 @@ void USB_send(char *buf){
while(*p++) ++l; while(*p++) ++l;
while(l){ while(l){
uint16_t s = (l > USB_TXBUFSZ) ? USB_TXBUFSZ : l; uint16_t s = (l > USB_TXBUFSZ) ? USB_TXBUFSZ : l;
tx_succesfull = 0;
EP_Write(3, (uint8_t*)&buf[ctr], s); EP_Write(3, (uint8_t*)&buf[ctr], s);
uint32_t ctra = 1000000;
while(--ctra && tx_succesfull == 0);
l -= s; l -= s;
ctr += s; ctr += s;
} }

View File

@ -0,0 +1,190 @@
EESchema-LIBRARY Version 2.3
#encoding utf-8
#
# 74HC4051
#
DEF 74HC4051 U 0 10 Y Y 1 F N
F0 "U" 0 0 50 H V C CNN
F1 "74HC4051" 0 -150 50 H V C CNN
F2 "" 0 0 50 H V C CNN
F3 "" 0 0 50 H V C CNN
$FPLIST
SO16
TSSOP16
SSOP16
DHVQFN16
$ENDFPLIST
DRAW
S -400 450 400 -450 0 1 0 N
X Y4 1 700 -50 300 L 50 50 1 1 B
X Y6 2 700 -250 300 L 50 50 1 1 B
X Z 3 0 -750 300 U 50 50 1 1 B
X Y7 4 700 -350 300 L 50 50 1 1 B
X Y5 5 700 -150 300 L 50 50 1 1 B
X ~E 6 -700 -350 300 R 50 50 1 1 I I
X VEE 7 -700 0 300 R 50 50 1 1 W
X GND 8 -700 -200 300 R 50 50 1 1 W
X S2 9 -700 150 300 R 50 50 1 1 I
X S1 10 -700 250 300 R 50 50 1 1 I
X S0 11 -700 350 300 R 50 50 1 1 I
X Y3 12 700 50 300 L 50 50 1 1 B
X Y0 13 700 350 300 L 50 50 1 1 B
X Y1 14 700 250 300 L 50 50 1 1 B
X Y2 15 700 150 300 L 50 50 1 1 B
X VCC 16 -700 -100 300 R 50 50 1 1 W
ENDDRAW
ENDDEF
#
# D_Schottky_x2_ACom_AKK
#
DEF D_Schottky_x2_ACom_AKK D 0 30 Y N 1 F N
F0 "D" 50 -100 50 H V C CNN
F1 "D_Schottky_x2_ACom_AKK" 0 100 50 H V C CNN
F2 "" 0 0 50 H V C CNN
F3 "" 0 0 50 H V C CNN
DRAW
P 2 0 1 0 -140 0 150 0 N
P 2 0 1 0 0 0 0 -100 N
P 3 0 1 8 -150 50 -150 -50 -150 -50 N
P 3 0 1 8 150 50 150 -50 150 -50 N
P 4 0 1 8 -150 50 -170 50 -170 40 -170 40 N
P 4 0 1 8 150 -50 170 -50 170 -40 170 -40 N
P 4 0 1 8 150 50 130 50 130 40 130 40 N
P 5 0 1 8 -130 -40 -130 -50 -150 -50 -150 -50 -150 -50 N
P 6 0 1 8 -50 -50 -150 0 -50 50 -50 -50 -50 -50 -50 -50 N
P 6 0 1 8 50 50 150 0 50 -50 50 50 50 50 50 50 N
X A 1 0 -200 100 U 50 50 0 1 P
X K 2 -300 0 150 R 50 50 0 1 P
X K 3 300 0 150 L 50 50 0 1 P
ENDDRAW
ENDDEF
#
# LM1117-ADJ
#
DEF LM1117-ADJ U 0 30 Y Y 1 F N
F0 "U" 100 -250 50 H V C CNN
F1 "LM1117-ADJ" 0 250 50 H V C CNN
F2 "" 0 0 50 H V C CNN
F3 "" 0 0 50 H V C CNN
ALIAS LM1117-1.8 LM1117-2.5 LM1117-3.3 LM1117-5.0
$FPLIST
SOT-223*
TO-263*
TO-252*
$ENDFPLIST
DRAW
S -200 -200 200 200 0 1 10 f
X GND/ADJ 1 0 -300 100 U 50 50 1 1 W
X VO 2 300 0 100 L 50 50 1 1 w
X VI 3 -300 0 100 R 50 50 1 1 W
ENDDRAW
ENDDEF
#
# PESD1CAN
#
DEF PESD1CAN D 0 30 Y N 1 F N
F0 "D" 0 -350 50 H V C CNN
F1 "PESD1CAN" 50 150 50 H V C CNN
F2 "" 0 0 50 H V C CNN
F3 "" 0 0 50 H V C CNN
$FPLIST
SOT23
$ENDFPLIST
DRAW
S -200 100 300 -300 0 1 0 N
P 2 0 1 0 -140 -200 150 -200 N
P 2 0 1 0 -140 0 150 0 N
P 3 0 1 8 -150 -150 -150 -250 -150 -250 N
P 3 0 1 8 -150 50 -150 -50 -150 -50 N
P 3 0 1 8 150 -150 150 -250 150 -250 N
P 3 0 1 8 150 50 150 -50 150 -50 N
P 4 0 1 8 -150 -150 -170 -150 -170 -160 -170 -160 N
P 4 0 1 8 -150 50 -170 50 -170 40 -170 40 N
P 4 0 1 8 150 -250 170 -250 170 -240 170 -240 N
P 4 0 1 8 150 -150 130 -150 130 -160 130 -160 N
P 4 0 1 8 150 -50 170 -50 170 -40 170 -40 N
P 4 0 1 0 150 0 250 0 250 -200 150 -200 N
P 4 0 1 8 150 50 130 50 130 40 130 40 N
P 5 0 1 8 -130 -240 -130 -250 -150 -250 -150 -250 -150 -250 N
P 5 0 1 8 -130 -40 -130 -50 -150 -50 -150 -50 -150 -50 N
P 6 0 1 8 -50 -250 -150 -200 -50 -150 -50 -250 -50 -250 -50 -250 N
P 6 0 1 8 -50 -50 -150 0 -50 50 -50 -50 -50 -50 -50 -50 N
P 6 0 1 8 50 -150 150 -200 50 -250 50 -150 50 -150 50 -150 N
P 6 0 1 8 50 50 150 0 50 -50 50 50 50 50 50 50 N
X K 1 -300 0 150 R 50 50 0 1 P
X K 2 -300 -200 150 R 50 50 0 1 P
X O 3 400 -100 150 L 50 50 0 1 P
ENDDRAW
ENDDEF
#
# TPS2051
#
DEF TPS2051 U 0 40 Y Y 1 F N
F0 "U" 0 -300 60 H V C CNN
F1 "TPS2051" 0 300 60 H V C CNN
F2 "" 0 0 60 H I C CNN
F3 "" 0 0 60 H I C CNN
DRAW
S -250 250 250 -250 0 1 0 N
X GND 1 -450 150 200 R 50 50 1 1 W
X IN 2 -450 50 200 R 50 50 1 1 W
X IN 3 -450 -50 200 R 50 50 1 1 P
X EN 4 -450 -150 200 R 50 50 1 1 I
X ~OC 5 450 -150 200 L 50 50 1 1 O
X OUT 6 450 -50 200 L 50 50 1 1 P
X OUT 7 450 50 200 L 50 50 1 1 P
X OUT 8 450 150 200 L 50 50 1 1 w
ENDDRAW
ENDDEF
#
# USB6B1
#
DEF USB6B1 D 0 30 Y N 1 F N
F0 "D" 0 -450 50 H V C CNN
F1 "USB6B1" 0 400 50 H V C CNN
F2 "" 200 -100 50 V V C CNN
F3 "" 200 -100 50 V V C CNN
$FPLIST
SO8
$ENDFPLIST
DRAW
C -150 -300 7 0 1 0 N
C -150 100 7 0 1 0 N
C -150 300 7 0 1 0 N
C 0 -300 7 0 1 0 N
C 0 -100 7 0 1 0 N
C 0 300 7 0 1 0 N
C 200 -300 7 0 1 0 N
C 200 300 7 0 1 0 N
S -300 -100 300 -100 0 1 0 N
S -300 300 300 300 0 1 0 N
S -200 -150 -100 -150 0 1 0 N
S -200 250 -100 250 0 1 0 N
S -150 300 -150 -300 0 1 0 N
S -50 -150 50 -150 0 1 0 N
S -50 250 50 250 0 1 0 N
S 0 300 0 -300 0 1 0 N
S 200 300 200 -300 0 1 0 N
S 300 -300 -300 -300 0 1 0 N
S 300 100 -300 100 0 1 0 N
P 3 0 1 8 150 50 250 50 250 50 N
P 4 0 1 8 150 50 150 30 160 30 160 30 N
P 4 0 1 8 250 50 250 70 240 70 240 70 N
P 5 0 1 0 -250 350 300 350 300 -350 -250 -350 -250 350 N
P 6 0 1 8 -200 -250 -150 -150 -100 -250 -200 -250 -200 -250 -200 -250 N
P 6 0 1 8 -200 150 -150 250 -100 150 -200 150 -200 150 -200 150 N
P 6 0 1 8 -50 -250 0 -150 50 -250 -50 -250 -50 -250 -50 -250 N
P 6 0 1 8 -50 150 0 250 50 150 -50 150 -50 150 -50 150 N
P 6 0 1 8 150 -50 200 50 250 -50 150 -50 150 -50 150 -50 N
X VCC 1 -500 300 200 R 50 50 1 1 P
X I/O1 2 -500 100 200 R 50 50 1 1 P
X I/O2 3 -500 -100 200 R 50 50 1 1 P
X GND 4 -500 -300 200 R 50 50 1 1 P
X GND 5 500 -300 200 L 50 50 1 1 P
X I/O2 6 500 -100 200 L 50 50 1 1 P
X I/O1 7 500 100 200 L 50 50 1 1 P
X VCC 8 500 300 200 L 50 50 1 1 P
ENDDRAW
ENDDEF
#
#End Library

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,6 @@
(fp_lib_table
(lib (name my_footprints)(type KiCad)(uri "$(KIPRJMOD)/my_footprints.pretty")(options "")(descr ""))
(lib (name LED_THT)(type KiCad)(uri ${KISYSMOD}/LED_THT.pretty)(options "")(descr ""))
(lib (name Crystal)(type KiCad)(uri ${KISYSMOD}/Crystal.pretty)(options "")(descr ""))
(lib (name Potentiometer_THT)(type KiCad)(uri ${KISYSMOD}/Potentiometer_THT.pretty)(options "")(descr ""))
)

View File

@ -0,0 +1,9 @@
(module Hole_3mm (layer F.Cu) (tedit 5913F6E4)
(fp_text reference REF** (at 0 3.81) (layer F.SilkS) hide
(effects (font (size 1 1) (thickness 0.15)))
)
(fp_text value Hole_3mm (at 0 -7.62) (layer F.Fab) hide
(effects (font (size 1 1) (thickness 0.15)))
)
(pad 1 thru_hole circle (at 0 0) (size 5 5) (drill 3) (layers *.Cu *.Mask))
)

View File

@ -0,0 +1,51 @@
(module Potentiometer (layer F.Cu) (tedit 5CDABBAE)
(descr http://www.ttelectronics.com/sites/default/files/download-files/Datasheet_PanelPot_P09xSeries.pdf)
(tags "potentiometer vertical TT P0915N single")
(fp_text reference REF** (at 2.5 -13.5) (layer F.SilkS)
(effects (font (size 1 1) (thickness 0.15)))
)
(fp_text value Potentiometer (at 2.5 2) (layer F.Fab)
(effects (font (size 1 1) (thickness 0.15)))
)
(fp_line (start -3.1 -9.75) (end -3.1 -12.6) (layer F.CrtYd) (width 0.05))
(fp_line (start 8.1 -0.75) (end 6.15 -0.75) (layer F.CrtYd) (width 0.05))
(fp_line (start -3.1 -12.6) (end 8.1 -12.6) (layer F.CrtYd) (width 0.05))
(fp_line (start 7.97 -0.88) (end 6.15 -0.88) (layer F.SilkS) (width 0.12))
(fp_line (start -2.97 -12.47) (end -2.97 -9.75) (layer F.SilkS) (width 0.12))
(fp_line (start 7.97 -12.47) (end -2.97 -12.47) (layer F.SilkS) (width 0.12))
(fp_circle (center 2.5 -7.5) (end 5.5 -7.5) (layer F.Fab) (width 0.12))
(fp_line (start -2.85 -12.35) (end 7.85 -12.35) (layer F.Fab) (width 0.1))
(fp_line (start -2.85 -1) (end -2.85 -12.35) (layer F.Fab) (width 0.1))
(fp_line (start 7.85 -1) (end -2.85 -1) (layer F.Fab) (width 0.1))
(fp_line (start 7.85 -12.35) (end 7.85 -1) (layer F.Fab) (width 0.1))
(fp_text user %R (at 2.5 -7.5) (layer F.Fab)
(effects (font (size 1 1) (thickness 0.15)))
)
(fp_line (start -1.15 -0.88) (end -2.97 -0.88) (layer F.SilkS) (width 0.12))
(fp_line (start 6.15 1.15) (end 6.15 -0.75) (layer F.CrtYd) (width 0.05))
(fp_line (start -1.15 -0.75) (end -3.1 -0.75) (layer F.CrtYd) (width 0.05))
(fp_line (start -1.15 1.15) (end -1.15 -0.75) (layer F.CrtYd) (width 0.05))
(fp_line (start 6.15 1.15) (end -1.15 1.15) (layer F.CrtYd) (width 0.05))
(fp_line (start -3.1 -9.75) (end -4.5 -9.75) (layer F.CrtYd) (width 0.05))
(fp_line (start -4.5 -5.25) (end -4.5 -9.75) (layer F.CrtYd) (width 0.05))
(fp_line (start -3.1 -0.75) (end -3.1 -5.25) (layer F.CrtYd) (width 0.05))
(fp_line (start -3.1 -5.25) (end -4.5 -5.25) (layer F.CrtYd) (width 0.05))
(fp_line (start 8.1 -0.75) (end 8.1 -5.25) (layer F.CrtYd) (width 0.05))
(fp_line (start 8.1 -9.75) (end 8.1 -12.6) (layer F.CrtYd) (width 0.05))
(fp_line (start 9.5 -9.75) (end 8.1 -9.75) (layer F.CrtYd) (width 0.05))
(fp_line (start 9.5 -5.25) (end 8.1 -5.25) (layer F.CrtYd) (width 0.05))
(fp_line (start 9.5 -5.25) (end 9.5 -9.75) (layer F.CrtYd) (width 0.05))
(fp_line (start -2.97 -5.25) (end -2.97 -0.88) (layer F.SilkS) (width 0.12))
(fp_line (start 7.97 -5.25) (end 7.97 -0.88) (layer F.SilkS) (width 0.12))
(fp_line (start 7.97 -12.47) (end 7.97 -9.75) (layer F.SilkS) (width 0.12))
(pad "" thru_hole oval (at -2.66 -7) (size 4.5 4.5) (drill 2.2) (layers *.Cu *.Mask))
(pad 3 thru_hole circle (at 5 0) (size 2 2) (drill 0.9) (layers *.Cu *.Mask))
(pad 2 thru_hole circle (at 2.54 0) (size 2 2) (drill 0.9) (layers *.Cu *.Mask))
(pad 1 thru_hole rect (at 0 0) (size 2 3) (drill 0.9) (layers *.Cu *.Mask))
(pad "" thru_hole oval (at 7.74 -7) (size 4.5 4.5) (drill 2.2) (layers *.Cu *.Mask))
(model ${KISYS3DMOD}/Potentiometer_THT.3dshapes/Potentiometer_TT_P0915N.wrl
(at (xyz 0 0 0))
(scale (xyz 1 1 1))
(rotate (xyz 0 0 0))
)
)

View File

@ -0,0 +1,12 @@
(module SMD_conn_4x2.5mm (layer F.Cu) (tedit 58B86145)
(fp_text reference REF** (at 0 3.81) (layer F.SilkS)
(effects (font (size 1 1) (thickness 0.15)))
)
(fp_text value SMD_conn_4x2.5mm (at 0 -3.81) (layer F.Fab)
(effects (font (size 1 1) (thickness 0.15)))
)
(pad 1 smd rect (at -3.81 0) (size 1.5 5) (layers F.Cu F.Paste F.Mask))
(pad 2 smd rect (at -1.27 0) (size 1.5 5) (layers F.Cu F.Paste F.Mask))
(pad 3 smd rect (at 1.27 0) (size 1.5 5) (layers F.Cu F.Paste F.Mask))
(pad 4 smd rect (at 3.81 0) (size 1.5 5) (layers F.Cu F.Paste F.Mask))
)

View File

@ -0,0 +1,10 @@
(module TH_via (layer F.Cu) (tedit 5A5E619A)
(fp_text reference REF** (at 0 0.5) (layer F.SilkS) hide
(effects (font (size 1 1) (thickness 0.15)))
)
(fp_text value TH_via (at 0 -0.5) (layer F.Fab) hide
(effects (font (size 1 1) (thickness 0.15)))
)
(pad 1 thru_hole circle (at 0 0) (size 1.5 1.5) (drill 0.8) (layers *.Cu *.Mask)
(zone_connect 1))
)

View File

@ -0,0 +1,695 @@
EESchema-LIBRARY Version 2.4
#encoding utf-8
#
# +3.3V
#
DEF +3.3V #PWR 0 0 Y Y 1 F P
F0 "#PWR" 0 -150 50 H I C CNN
F1 "+3.3V" 0 140 50 H V C CNN
F2 "" 0 0 50 H I C CNN
F3 "" 0 0 50 H I C CNN
DRAW
P 2 0 1 0 -30 50 0 100 N
P 2 0 1 0 0 0 0 100 N
P 2 0 1 0 0 100 30 50 N
X +3V3 1 0 0 0 U 50 50 1 1 W N
ENDDRAW
ENDDEF
#
# +5V
#
DEF +5V #PWR 0 0 Y Y 1 F P
F0 "#PWR" 0 -150 50 H I C CNN
F1 "+5V" 0 140 50 H V C CNN
F2 "" 0 0 50 H I C CNN
F3 "" 0 0 50 H I C CNN
DRAW
P 2 0 1 0 -30 50 0 100 N
P 2 0 1 0 0 0 0 100 N
P 2 0 1 0 0 100 30 50 N
X +5V 1 0 0 0 U 50 50 1 1 W N
ENDDRAW
ENDDEF
#
# C
#
DEF C C 0 10 N Y 1 F N
F0 "C" 25 100 50 H V L CNN
F1 "C" 25 -100 50 H V L CNN
F2 "" 38 -150 50 H I C CNN
F3 "" 0 0 50 H I C CNN
$FPLIST
C_*
$ENDFPLIST
DRAW
P 2 0 1 20 -80 -30 80 -30 N
P 2 0 1 20 -80 30 80 30 N
X ~ 1 0 150 110 D 50 50 1 1 P
X ~ 2 0 -150 110 U 50 50 1 1 P
ENDDRAW
ENDDEF
#
# CONN_01X01
#
DEF CONN_01X01 J 0 40 Y N 1 F N
F0 "J" 0 100 50 H V C CNN
F1 "CONN_01X01" 100 0 50 V V C CNN
F2 "" 0 0 50 H I C CNN
F3 "" 0 0 50 H I C CNN
$FPLIST
Pin_Header_Straight_1X*
Pin_Header_Angled_1X*
Socket_Strip_Straight_1X*
Socket_Strip_Angled_1X*
$ENDFPLIST
DRAW
S -50 5 10 -5 0 1 0 N
S -50 50 50 -50 0 1 0 N
X P1 1 -200 0 150 R 50 50 1 1 P
ENDDRAW
ENDDEF
#
# CONN_01X03
#
DEF CONN_01X03 J 0 40 Y N 1 F N
F0 "J" 0 200 50 H V C CNN
F1 "CONN_01X03" 100 0 50 V V C CNN
F2 "" 0 0 50 H I C CNN
F3 "" 0 0 50 H I C CNN
$FPLIST
Pin_Header_Straight_1X*
Pin_Header_Angled_1X*
Socket_Strip_Straight_1X*
Socket_Strip_Angled_1X*
$ENDFPLIST
DRAW
S -50 -95 10 -105 0 1 0 N
S -50 5 10 -5 0 1 0 N
S -50 105 10 95 0 1 0 N
S -50 150 50 -150 0 1 0 N
X P1 1 -200 100 150 R 50 50 1 1 P
X P2 2 -200 0 150 R 50 50 1 1 P
X P3 3 -200 -100 150 R 50 50 1 1 P
ENDDRAW
ENDDEF
#
# CONN_02X03
#
DEF CONN_02X03 J 0 1 Y N 1 F N
F0 "J" 0 200 50 H V C CNN
F1 "CONN_02X03" 0 -200 50 H V C CNN
F2 "" 0 -1200 50 H I C CNN
F3 "" 0 -1200 50 H I C CNN
$FPLIST
Pin_Header_Straight_2X*
Pin_Header_Angled_2X*
Socket_Strip_Straight_2X*
Socket_Strip_Angled_2X*
IDC_Header_Straight_*
$ENDFPLIST
DRAW
S -100 -95 -50 -105 0 1 0 N
S -100 5 -50 -5 0 1 0 N
S -100 105 -50 95 0 1 0 N
S -100 150 100 -150 0 1 0 N
S 50 -95 100 -105 0 1 0 N
S 50 5 100 -5 0 1 0 N
S 50 105 100 95 0 1 0 N
X P1 1 -250 100 150 R 50 50 1 1 P
X P2 2 250 100 150 L 50 50 1 1 P
X P3 3 -250 0 150 R 50 50 1 1 P
X P4 4 250 0 150 L 50 50 1 1 P
X P5 5 -250 -100 150 R 50 50 1 1 P
X P6 6 250 -100 150 L 50 50 1 1 P
ENDDRAW
ENDDEF
#
# CP
#
DEF CP C 0 10 N Y 1 F N
F0 "C" 25 100 50 H V L CNN
F1 "CP" 25 -100 50 H V L CNN
F2 "" 38 -150 50 H I C CNN
F3 "" 0 0 50 H I C CNN
$FPLIST
CP_*
$ENDFPLIST
DRAW
S -90 20 -90 40 0 1 0 N
S -90 20 90 20 0 1 0 N
S 90 -20 -90 -40 0 1 0 F
S 90 40 -90 40 0 1 0 N
S 90 40 90 20 0 1 0 N
P 2 0 1 0 -70 90 -30 90 N
P 2 0 1 0 -50 110 -50 70 N
X ~ 1 0 150 110 D 50 50 1 1 P
X ~ 2 0 -150 110 U 50 50 1 1 P
ENDDRAW
ENDDEF
#
# Conn_01x01
#
DEF Conn_01x01 J 0 40 Y N 1 F N
F0 "J" 0 100 50 H V C CNN
F1 "Conn_01x01" 0 -100 50 H V C CNN
F2 "" 0 0 50 H I C CNN
F3 "" 0 0 50 H I C CNN
$FPLIST
Connector*:*_??x*mm*
Connector*:*1x??x*mm*
Pin?Header?Straight?1X*
Pin?Header?Angled?1X*
Socket?Strip?Straight?1X*
Socket?Strip?Angled?1X*
$ENDFPLIST
DRAW
S -50 5 0 -5 1 1 6 N
S -50 50 50 -50 1 1 10 f
X Pin_1 1 -200 0 150 R 50 50 1 1 P
ENDDRAW
ENDDEF
#
# Conn_01x02
#
DEF Conn_01x02 J 0 40 Y N 1 F N
F0 "J" 0 100 50 H V C CNN
F1 "Conn_01x02" 0 -200 50 H V C CNN
F2 "" 0 0 50 H I C CNN
F3 "" 0 0 50 H I C CNN
$FPLIST
Connector*:*_??x*mm*
Connector*:*1x??x*mm*
Pin?Header?Straight?1X*
Pin?Header?Angled?1X*
Socket?Strip?Straight?1X*
Socket?Strip?Angled?1X*
$ENDFPLIST
DRAW
S -50 -95 0 -105 1 1 6 N
S -50 5 0 -5 1 1 6 N
S -50 50 50 -150 1 1 10 f
X Pin_1 1 -200 0 150 R 50 50 1 1 P
X Pin_2 2 -200 -100 150 R 50 50 1 1 P
ENDDRAW
ENDDEF
#
# Conn_01x07
#
DEF Conn_01x07 J 0 40 Y N 1 F N
F0 "J" 0 400 50 H V C CNN
F1 "Conn_01x07" 0 -400 50 H V C CNN
F2 "" 0 0 50 H I C CNN
F3 "" 0 0 50 H I C CNN
$FPLIST
Connector*:*_??x*mm*
Connector*:*1x??x*mm*
Pin?Header?Straight?1X*
Pin?Header?Angled?1X*
Socket?Strip?Straight?1X*
Socket?Strip?Angled?1X*
$ENDFPLIST
DRAW
S -50 -295 0 -305 1 1 6 N
S -50 -195 0 -205 1 1 6 N
S -50 -95 0 -105 1 1 6 N
S -50 5 0 -5 1 1 6 N
S -50 105 0 95 1 1 6 N
S -50 205 0 195 1 1 6 N
S -50 305 0 295 1 1 6 N
S -50 350 50 -350 1 1 10 f
X Pin_1 1 -200 300 150 R 50 50 1 1 P
X Pin_2 2 -200 200 150 R 50 50 1 1 P
X Pin_3 3 -200 100 150 R 50 50 1 1 P
X Pin_4 4 -200 0 150 R 50 50 1 1 P
X Pin_5 5 -200 -100 150 R 50 50 1 1 P
X Pin_6 6 -200 -200 150 R 50 50 1 1 P
X Pin_7 7 -200 -300 150 R 50 50 1 1 P
ENDDRAW
ENDDEF
#
# DB9_Female
#
DEF DB9_Female J 0 40 Y N 1 F N
F0 "J" 0 550 50 H V C CNN
F1 "DB9_Female" 0 -575 50 H V C CNN
F2 "" 0 0 50 H I C CNN
F3 "" 0 0 50 H I C CNN
$FPLIST
DB*F*
$ENDFPLIST
DRAW
C -70 -400 30 0 1 0 N
C -70 -200 30 0 1 0 N
C -70 0 30 0 1 0 N
C -70 200 30 0 1 0 N
C -70 400 30 0 1 0 N
C 50 -300 30 0 1 0 N
C 50 -100 30 0 1 0 N
C 50 100 30 0 1 0 N
C 50 300 30 0 1 0 N
P 2 0 1 0 -150 -400 -100 -400 N
P 2 0 1 0 -150 -300 20 -300 N
P 2 0 1 0 -150 -200 -100 -200 N
P 2 0 1 0 -150 -100 20 -100 N
P 2 0 1 0 -150 0 -100 0 N
P 2 0 1 0 -150 100 20 100 N
P 2 0 1 0 -150 200 -100 200 N
P 2 0 1 0 -150 300 20 300 N
P 2 0 1 0 -150 400 -100 400 N
P 5 0 1 10 -150 525 -150 -525 150 -375 150 375 -150 525 f
X 1 1 -300 400 150 R 50 50 1 1 P
X 2 2 -300 200 150 R 50 50 1 1 P
X 3 3 -300 0 150 R 50 50 1 1 P
X 4 4 -300 -200 150 R 50 50 1 1 P
X 5 5 -300 -400 150 R 50 50 1 1 P
X 6 6 -300 300 150 R 50 50 1 1 P
X 7 7 -300 100 150 R 50 50 1 1 P
X 8 8 -300 -100 150 R 50 50 1 1 P
X 9 9 -300 -300 150 R 50 50 1 1 P
ENDDRAW
ENDDEF
#
# DB9_Male
#
DEF DB9_Male J 0 40 Y N 1 F N
F0 "J" 0 550 50 H V C CNN
F1 "DB9_Male" 0 -575 50 H V C CNN
F2 "" 0 0 50 H I C CNN
F3 "" 0 0 50 H I C CNN
$FPLIST
DB*M*
$ENDFPLIST
DRAW
C -70 -400 30 0 1 0 F
C -70 -200 30 0 1 0 F
C -70 0 30 0 1 0 F
C -70 200 30 0 1 0 F
C -70 400 30 0 1 0 F
C 50 -300 30 0 1 0 F
C 50 -100 30 0 1 0 F
C 50 100 30 0 1 0 F
C 50 300 30 0 1 0 F
P 2 0 1 0 -150 -400 -100 -400 N
P 2 0 1 0 -150 -300 20 -300 N
P 2 0 1 0 -150 -200 -100 -200 N
P 2 0 1 0 -150 -100 20 -100 N
P 2 0 1 0 -150 0 -100 0 N
P 2 0 1 0 -150 100 20 100 N
P 2 0 1 0 -150 200 -100 200 N
P 2 0 1 0 -150 300 20 300 N
P 2 0 1 0 -150 400 -100 400 N
P 5 0 1 10 -150 -525 -150 525 150 375 150 -375 -150 -525 f
X 1 1 -300 -400 150 R 50 50 1 1 P
X 2 2 -300 -200 150 R 50 50 1 1 P
X 3 3 -300 0 150 R 50 50 1 1 P
X 4 4 -300 200 150 R 50 50 1 1 P
X 5 5 -300 400 150 R 50 50 1 1 P
X 6 6 -300 -300 150 R 50 50 1 1 P
X 7 7 -300 -100 150 R 50 50 1 1 P
X 8 8 -300 100 150 R 50 50 1 1 P
X 9 9 -300 300 150 R 50 50 1 1 P
ENDDRAW
ENDDEF
#
# D_Schottky
#
DEF D_Schottky D 0 40 N N 1 F N
F0 "D" 0 100 50 H V C CNN
F1 "D_Schottky" 0 -100 50 H V C CNN
F2 "" 0 0 50 H I C CNN
F3 "" 0 0 50 H I C CNN
$FPLIST
TO-???*
*SingleDiode
*_Diode_*
*SingleDiode*
D_*
$ENDFPLIST
DRAW
P 2 0 1 0 50 0 -50 0 N
P 4 0 1 8 50 50 50 -50 -50 0 50 50 N
P 6 0 1 8 -75 25 -75 50 -50 50 -50 -50 -25 -50 -25 -25 N
X K 1 -150 0 100 R 50 50 1 1 P
X A 2 150 0 100 L 50 50 1 1 P
ENDDRAW
ENDDEF
#
# D_Zener
#
DEF D_Zener D 0 40 N N 1 F N
F0 "D" 0 100 50 H V C CNN
F1 "D_Zener" 0 -100 50 H V C CNN
F2 "" 0 0 50 H I C CNN
F3 "" 0 0 50 H I C CNN
$FPLIST
TO-???*
*SingleDiode
*_Diode_*
*SingleDiode*
D_*
$ENDFPLIST
DRAW
P 2 0 1 0 50 0 -50 0 N
P 3 0 1 8 -50 -50 -50 50 -30 50 N
P 4 0 1 8 50 -50 50 50 -50 0 50 -50 N
X K 1 -150 0 100 R 50 50 1 1 P
X A 2 150 0 100 L 50 50 1 1 P
ENDDRAW
ENDDEF
#
# GND
#
DEF GND #PWR 0 0 Y Y 1 F P
F0 "#PWR" 0 -250 50 H I C CNN
F1 "GND" 0 -150 50 H V C CNN
F2 "" 0 0 50 H I C CNN
F3 "" 0 0 50 H I C CNN
DRAW
P 6 0 1 0 0 0 0 -50 50 -50 0 -100 -50 -50 0 -50 N
X GND 1 0 0 0 D 50 50 1 1 W N
ENDDRAW
ENDDEF
#
# Jumper_NO_Small
#
DEF Jumper_NO_Small JP 0 30 N N 1 F N
F0 "JP" 0 80 50 H V C CNN
F1 "Jumper_NO_Small" 10 -60 50 H V C CNN
F2 "" 0 0 50 H I C CNN
F3 "" 0 0 50 H I C CNN
DRAW
C -40 0 20 0 1 0 N
C 40 0 20 0 1 0 N
X 1 1 -100 0 40 R 50 50 0 1 P
X 2 2 100 0 40 L 50 50 0 1 P
ENDDRAW
ENDDEF
#
# LED-RESCUE-stm32
#
DEF LED-RESCUE-stm32 D 0 40 Y N 1 F N
F0 "D" 0 100 50 H V C CNN
F1 "LED-RESCUE-stm32" 0 -100 50 H V C CNN
F2 "" 0 0 50 H V C CNN
F3 "" 0 0 50 H V C CNN
$FPLIST
LED*
$ENDFPLIST
DRAW
P 2 0 1 8 -50 -50 -50 50 N
P 2 0 1 0 -50 0 50 0 N
P 4 0 1 8 50 -50 50 50 -50 0 50 -50 N
P 5 0 1 0 -120 -30 -180 -90 -150 -90 -180 -90 -180 -60 N
P 5 0 1 0 -70 -30 -130 -90 -100 -90 -130 -90 -130 -60 N
X K 1 -150 0 100 R 50 50 1 1 P
X A 2 150 0 100 L 50 50 1 1 P
ENDDRAW
ENDDEF
#
# LM1117-3.3-RESCUE-stm32
#
DEF LM1117-3.3-RESCUE-stm32 U 0 30 Y Y 1 F N
F0 "U" 100 -250 50 H V C CNN
F1 "LM1117-3.3-RESCUE-stm32" 0 250 50 H V C CNN
F2 "" 0 0 50 H I C CNN
F3 "" 0 0 50 H I C CNN
$FPLIST
SOT-223*
TO-263*
TO-252*
$ENDFPLIST
DRAW
S -200 -200 200 200 0 1 10 f
X GND/ADJ 1 0 -300 100 U 50 50 1 1 W
X VO 2 300 50 100 L 50 50 1 1 P
X VI 3 -300 0 100 R 50 50 1 1 W
X VO 4 300 -50 100 L 50 50 1 1 w
ENDDRAW
ENDDEF
#
# MAX471-RESCUE-stm32
#
DEF MAX471-RESCUE-stm32 U 0 40 Y Y 1 F N
F0 "U" -300 350 50 H V L CNN
F1 "MAX471-RESCUE-stm32" -300 -350 50 H V L CNN
F2 "" 0 0 50 H I C CNN
F3 "" 0 0 50 H I C CNN
DRAW
S -300 300 300 -300 0 1 10 f
X SHDN 1 -400 -100 100 R 50 50 1 1 I
X RS+ 2 -400 200 100 R 50 50 1 1 W
X RS+ 3 -400 100 100 R 50 50 1 1 P
X GND 4 -400 -200 100 R 50 50 1 1 W
X SIGN 5 400 -100 100 L 50 50 1 1 C
X RS- 6 400 200 100 L 50 50 1 1 w
X RS- 7 400 100 100 L 50 50 1 1 P
X OUT 8 400 -200 100 L 50 50 1 1 O
ENDDRAW
ENDDEF
#
# MCP2551-I_SN
#
DEF MCP2551-I_SN U 0 40 Y Y 1 F N
F0 "U" -400 350 50 H V L CNN
F1 "MCP2551-I_SN" 100 350 50 H V L CNN
F2 "Housings_SOIC:SOIC-8_3.9x4.9mm_Pitch1.27mm" 0 -500 50 H I C CIN
F3 "" 0 0 50 H I C CNN
$FPLIST
SOIC*Pitch1.27mm*
$ENDFPLIST
DRAW
S -400 300 400 -300 0 1 10 f
X TXD 1 -500 200 100 R 50 50 1 1 I
X VSS 2 0 -400 100 U 50 50 1 1 W
X VDD 3 0 400 100 D 50 50 1 1 W
X RXD 4 -500 100 100 R 50 50 1 1 O
X Vref 5 -500 -100 100 R 50 50 1 1 w
X CANL 6 500 -100 100 L 50 50 1 1 B
X CANH 7 500 100 100 L 50 50 1 1 B
X Rs 8 -500 -200 100 R 50 50 1 1 I
ENDDRAW
ENDDEF
#
# PWR_FLAG
#
DEF PWR_FLAG #FLG 0 0 N N 1 F P
F0 "#FLG" 0 75 50 H I C CNN
F1 "PWR_FLAG" 0 150 50 H V C CNN
F2 "" 0 0 50 H I C CNN
F3 "" 0 0 50 H I C CNN
DRAW
P 6 0 1 0 0 0 0 50 -40 75 0 100 40 75 0 50 N
X pwr 1 0 0 0 U 50 50 0 0 w
ENDDRAW
ENDDEF
#
# Q_NMOS_GSD
#
DEF Q_NMOS_GSD Q 0 0 Y N 1 F N
F0 "Q" 200 50 50 H V L CNN
F1 "Q_NMOS_GSD" 200 -50 50 H V L CNN
F2 "" 200 100 50 H I C CNN
F3 "" 0 0 50 H I C CNN
DRAW
C 65 0 111 0 1 10 N
C 100 -70 11 0 1 0 F
C 100 70 11 0 1 0 F
P 2 0 1 0 2 0 10 0 N
P 2 0 1 0 30 -70 100 -70 N
P 2 0 1 10 30 -50 30 -90 N
P 2 0 1 0 30 0 100 0 N
P 2 0 1 10 30 20 30 -20 N
P 2 0 1 0 30 70 100 70 N
P 2 0 1 10 30 90 30 50 N
P 2 0 1 0 100 -70 100 -100 N
P 2 0 1 0 100 -70 100 0 N
P 2 0 1 0 100 100 100 70 N
P 3 0 1 10 10 75 10 -75 10 -75 N
P 4 0 1 0 40 0 80 15 80 -15 40 0 F
P 4 0 1 0 100 -70 130 -70 130 70 100 70 N
P 4 0 1 0 110 20 115 15 145 15 150 10 N
P 4 0 1 0 130 15 115 -10 145 -10 130 15 N
X G 1 -200 0 200 R 50 50 1 1 I
X S 2 100 -200 100 U 50 50 1 1 P
X D 3 100 200 100 D 50 50 1 1 P
ENDDRAW
ENDDEF
#
# Q_PMOS_GSD
#
DEF Q_PMOS_GSD Q 0 0 Y N 1 F N
F0 "Q" 200 50 50 H V L CNN
F1 "Q_PMOS_GSD" 200 -50 50 H V L CNN
F2 "" 200 100 50 H I C CNN
F3 "" 0 0 50 H I C CNN
DRAW
C 65 0 111 0 1 10 N
C 100 -70 11 0 1 0 F
C 100 70 11 0 1 0 F
P 2 0 1 0 2 0 10 0 N
P 2 0 1 0 30 -70 100 -70 N
P 2 0 1 10 30 -50 30 -90 N
P 2 0 1 0 30 0 100 0 N
P 2 0 1 10 30 20 30 -20 N
P 2 0 1 0 30 70 100 70 N
P 2 0 1 10 30 90 30 50 N
P 2 0 1 0 100 -70 100 -100 N
P 2 0 1 0 100 -70 100 0 N
P 2 0 1 0 100 100 100 70 N
P 3 0 1 10 10 75 10 -75 10 -75 N
P 4 0 1 0 90 0 50 -15 50 15 90 0 F
P 4 0 1 0 100 -70 130 -70 130 70 100 70 N
P 4 0 1 0 110 -20 115 -15 145 -15 150 -10 N
P 4 0 1 0 130 -15 115 10 145 10 130 -15 N
X G 1 -200 0 200 R 50 50 1 1 I
X S 2 100 -200 100 U 50 50 1 1 P
X D 3 100 200 100 D 50 50 1 1 P
ENDDRAW
ENDDEF
#
# R
#
DEF R R 0 0 N Y 1 F N
F0 "R" 80 0 50 V V C CNN
F1 "R" 0 0 50 V V C CNN
F2 "" -70 0 50 V I C CNN
F3 "" 0 0 50 H I C CNN
$FPLIST
R_*
R_*
$ENDFPLIST
DRAW
S -40 -100 40 100 0 1 10 N
X ~ 1 0 150 50 D 50 50 1 1 P
X ~ 2 0 -150 50 U 50 50 1 1 P
ENDDRAW
ENDDEF
#
# SP0502BAHT
#
DEF SP0502BAHT D 0 40 Y N 1 F N
F0 "D" 225 100 50 H V L CNN
F1 "SP0502BAHT" 225 25 50 H V L CNN
F2 "TO_SOT_Packages_SMD:SOT-23" 225 -50 50 H I L CNN
F3 "" 125 125 50 H I C CNN
$FPLIST
SOT?23*
$ENDFPLIST
DRAW
S -175 100 175 -100 0 1 10 f
P 2 0 1 0 -100 100 -100 50 N
P 2 0 1 0 0 -50 0 -100 N
P 2 0 1 0 100 100 100 50 N
P 4 0 1 0 -150 75 -125 50 -75 50 -50 25 N
P 4 0 1 0 -100 0 -100 -50 100 -50 100 0 N
P 4 0 1 0 -100 50 -75 0 -125 0 -100 50 F
P 4 0 1 0 50 75 75 50 125 50 150 25 N
P 4 0 1 0 100 50 75 0 125 0 100 50 F
X A 3 0 -200 100 U 50 50 0 0 I
X K 1 -100 200 100 D 50 50 1 1 I
X K 2 100 200 100 D 50 50 1 1 I
ENDDRAW
ENDDEF
#
# STM32F042C6Tx
#
DEF STM32F042C6Tx U 0 40 Y Y 1 L N
F0 "U" -3000 1725 50 H V L BNN
F1 "STM32F042C6Tx" 3000 1725 50 H V R BNN
F2 "LQFP48" 3000 1675 50 H V R TNN
F3 "" 0 0 50 H V C CNN
DRAW
S -3000 -1700 3000 1700 0 1 10 f
X VBAT 1 -3100 1100 100 R 50 50 1 1 W
X ADC_IN0/RTC_TAMP2/SYS_WKUP1/TIM2_CH1/TIM2_ETR/TSC_G1_IO1/USART2_CTS/PA0 10 3100 100 100 L 50 50 1 1 B
X ADC_IN1/TIM2_CH2/TSC_G1_IO2/USART2_DE/USART2_RTS/PA1 11 3100 0 100 L 50 50 1 1 B
X ADC_IN2/SYS_WKUP4/TIM2_CH3/TSC_G1_IO3/USART2_TX/PA2 12 3100 -100 100 L 50 50 1 1 B
X ADC_IN3/TIM2_CH4/TSC_G1_IO4/USART2_RX/PA3 13 3100 -200 100 L 50 50 1 1 B
X ADC_IN4/I2S1_WS/SPI1_NSS/TIM14_CH1/TSC_G2_IO1/USART2_CK/USB_OE/PA4 14 3100 -300 100 L 50 50 1 1 B
X ADC_IN5/CEC/I2S1_CK/SPI1_SCK/TIM2_CH1/TIM2_ETR/TSC_G2_IO2/PA5 15 3100 -400 100 L 50 50 1 1 B
X ADC_IN6/I2S1_MCK/SPI1_MISO/TIM16_CH1/TIM1_BKIN/TIM3_CH1/TSC_G2_IO3/PA6 16 3100 -500 100 L 50 50 1 1 B
X ADC_IN7/I2S1_SD/SPI1_MOSI/TIM14_CH1/TIM17_CH1/TIM1_CH1N/TIM3_CH2/TSC_G2_IO4/PA7 17 3100 -600 100 L 50 50 1 1 B
X PB0/ADC_IN8/TIM1_CH2N/TIM3_CH3/TSC_G3_IO2 18 -3100 100 100 R 50 50 1 1 B
X PB1/ADC_IN9/TIM14_CH1/TIM1_CH3N/TIM3_CH4/TSC_G3_IO3 19 -3100 0 100 R 50 50 1 1 B
X PC13/RTC_OUT_ALARM/RTC_OUT_CALIB/RTC_TAMP1/RTC_TS/SYS_WKUP2 2 -3100 500 100 R 50 50 1 1 B
X PB2/TSC_G3_IO4 20 -3100 -100 100 R 50 50 1 1 B
X PB10/CEC/I2C1_SCL/SPI2_SCK/TIM2_CH3/TSC_SYNC 21 -3100 -900 100 R 50 50 1 1 B
X PB11/I2C1_SDA/TIM2_CH4 22 -3100 -1000 100 R 50 50 1 1 B
X VSS 23 -200 -1800 100 U 50 50 1 1 W
X VDD 24 -200 1800 100 D 50 50 1 1 W
X PB12/SPI2_NSS/TIM1_BKIN 25 -3100 -1100 100 R 50 50 1 1 B
X PB13/I2C1_SCL/SPI2_SCK/TIM1_CH1N 26 -3100 -1200 100 R 50 50 1 1 B
X PB14/I2C1_SDA/SPI2_MISO/TIM1_CH2N 27 -3100 -1300 100 R 50 50 1 1 B
X PB15/RTC_REFIN/SPI2_MOSI/SYS_WKUP7/TIM1_CH3N 28 -3100 -1400 100 R 50 50 1 1 B
X CRS_SYNC/RCC_MCO/TIM1_CH1/USART1_CK/PA8 29 3100 -700 100 L 50 50 1 1 B
X PC14/RCC_OSC32_IN 3 -3100 400 100 R 50 50 1 1 B
X I2C1_SCL/TIM1_CH2/TSC_G4_IO1/USART1_TX/PA9 30 3100 -800 100 L 50 50 1 1 B
X I2C1_SDA/TIM17_BKIN/TIM1_CH3/TSC_G4_IO2/USART1_RX/PA10 31 3100 -900 100 L 50 50 1 1 B
X CAN_RX/I2C1_SCL/TIM1_CH4/TSC_G4_IO3/USART1_CTS/USB_DM/PA11 32 3100 -1000 100 L 50 50 1 1 B
X CAN_TX/I2C1_SDA/TIM1_ETR/TSC_G4_IO4/USART1_DE/USART1_RTS/USB_DP/PA12 33 3100 -1100 100 L 50 50 1 1 B
X IR_OUT/SYS_SWDIO/USB_OE/PA13 34 3100 -1200 100 L 50 50 1 1 B
X VSS 35 -100 -1800 100 U 50 50 1 1 W
X VDDIO2 36 100 1800 100 D 50 50 1 1 W
X SYS_SWCLK/USART2_TX/PA14 37 3100 -1300 100 L 50 50 1 1 B
X I2S1_WS/SPI1_NSS/TIM2_CH1/TIM2_ETR/USART2_RX/USB_OE/PA15 38 3100 -1400 100 L 50 50 1 1 B
X PB3/I2S1_CK/SPI1_SCK/TIM2_CH2/TSC_G5_IO1 39 -3100 -200 100 R 50 50 1 1 B
X PC15/RCC_OSC32_OUT 4 -3100 300 100 R 50 50 1 1 B
X PB4/I2S1_MCK/SPI1_MISO/TIM17_BKIN/TIM3_CH1/TSC_G5_IO2 40 -3100 -300 100 R 50 50 1 1 B
X PB5/I2C1_SMBA/I2S1_SD/SPI1_MOSI/SYS_WKUP6/TIM16_BKIN/TIM3_CH2 41 -3100 -400 100 R 50 50 1 1 B
X PB6/I2C1_SCL/TIM16_CH1N/TSC_G5_IO3/USART1_TX 42 -3100 -500 100 R 50 50 1 1 B
X PB7/I2C1_SDA/TIM17_CH1N/TSC_G5_IO4/USART1_RX 43 -3100 -600 100 R 50 50 1 1 B
X PF11 44 -3100 700 100 R 50 50 1 1 B
X PB8/CAN_RX/CEC/I2C1_SCL/TIM16_CH1/TSC_SYNC 45 -3100 -700 100 R 50 50 1 1 B
X PB9/CAN_TX/I2C1_SDA/IR_OUT/SPI2_NSS/TIM17_CH1 46 -3100 -800 100 R 50 50 1 1 B
X VSS 47 0 -1800 100 U 50 50 1 1 W
X VDD 48 -100 1800 100 D 50 50 1 1 W
X PF0/CRS_SYNC/I2C1_SDA/RCC_OSC_IN 5 -3100 900 100 R 50 50 1 1 I
X PF1/I2C1_SCL/RCC_OSC_OUT 6 -3100 800 100 R 50 50 1 1 I
X NRST 7 -3100 1300 100 R 50 50 1 1 I
X VSSA 8 100 -1800 100 U 50 50 1 1 W
X VDDA 9 0 1800 100 D 50 50 1 1 W
ENDDRAW
ENDDEF
#
# SW_Push
#
DEF SW_Push SW 0 40 N N 1 F N
F0 "SW" 50 100 50 H V L CNN
F1 "SW_Push" 0 -60 50 H V C CNN
F2 "" 0 200 50 H I C CNN
F3 "" 0 200 50 H I C CNN
DRAW
C -80 0 20 0 1 0 N
C 80 0 20 0 1 0 N
P 2 0 1 0 0 50 0 120 N
P 2 0 1 0 100 50 -100 50 N
X 1 1 -200 0 100 R 50 50 0 1 P
X 2 2 200 0 100 L 50 50 0 1 P
ENDDRAW
ENDDEF
#
# USB_A-RESCUE-stm32
#
DEF USB_A-RESCUE-stm32 P 0 40 Y Y 1 F N
F0 "P" 200 -200 50 H V C CNN
F1 "USB_A-RESCUE-stm32" -50 200 50 H V C CNN
F2 "" -50 -100 50 V V C CNN
F3 "" -50 -100 50 V V C CNN
$FPLIST
USB*
$ENDFPLIST
DRAW
S -250 -150 150 150 0 1 0 N
S -205 -150 -195 -120 0 1 0 N
S -105 -150 -95 -120 0 1 0 N
S -5 -150 5 -120 0 1 0 N
S 95 -150 105 -120 0 1 0 N
X VBUS 1 -200 -300 150 U 50 50 1 1 W
X D- 2 -100 -300 150 U 50 50 1 1 P
X D+ 3 0 -300 150 U 50 50 1 1 P
X GND 4 100 -300 150 U 50 50 1 1 W
X shield 5 300 100 150 L 50 50 1 1 P
ENDDRAW
ENDDEF
#
#End Library

View File

@ -0,0 +1,73 @@
"Source:","/home/eddy/Docs/SAO/ELECTRONICS/STM32/F0-srcs/F0_F1_testboard/kicad/stm32.sch"
"Date:","þÔ 16 ÍÁÑ 2019 13:55:26"
"Tool:","Eeschema (6.0.0-rc1-dev-1613-ga55d9819b)"
"Generator:","/usr/local/share/kicad/plugins/bom_csv_grouped_by_value.py"
"Component Count:","35"
"Individual Components:"
"Item","Qty","Reference(s)","Value","LibPart","Footprint","Datasheet"
"","","C1","0.1","stm32-rescue:C","Capacitor_SMD:C_0603_1608Metric_Pad1.05x0.95mm_HandSolder",""
"","","C2","0.1","stm32-rescue:C","Capacitor_SMD:C_0603_1608Metric_Pad1.05x0.95mm_HandSolder",""
"","","C3","0.1","stm32-rescue:C","Capacitor_SMD:C_0603_1608Metric_Pad1.05x0.95mm_HandSolder",""
"","","C4","47u","stm32-rescue:CP","Capacitor_Tantalum_SMD:CP_EIA-3216-18_Kemet-A_Pad1.58x1.35mm_HandSolder",""
"","","C5","12","stm32-rescue:C","Capacitor_SMD:C_0603_1608Metric_Pad1.05x0.95mm_HandSolder",""
"","","C6","12","stm32-rescue:C","Capacitor_SMD:C_0603_1608Metric_Pad1.05x0.95mm_HandSolder",""
"","","C7","0.1","stm32-rescue:C","Capacitor_SMD:C_0603_1608Metric_Pad1.05x0.95mm_HandSolder",""
"","","C8","0.1","stm32-rescue:C","Capacitor_SMD:C_0603_1608Metric_Pad1.05x0.95mm_HandSolder",""
"","","C9","0.1","stm32-rescue:C","Capacitor_SMD:C_0603_1608Metric_Pad1.05x0.95mm_HandSolder",""
"","","C10","0.1","stm32-rescue:C","Capacitor_SMD:C_0603_1608Metric_Pad1.05x0.95mm_HandSolder",""
"","","D1","LED","stm32-rescue:LED-RESCUE-stm32","LED_THT:LED_D3.0mm",""
"","","D2","IP4220CZ6","Power_Protection:SP0505BAHT","TO_SOT_Packages_SMD:SOT-23-6_Handsoldering","http://www.littelfuse.com/~/media/files/littelfuse/technical%20resources/documents/data%20sheets/sp05xxba.pdf"
"","","D3","LED","stm32-rescue:LED-RESCUE-stm32","LED_THT:LED_D5.0mm",""
"","","D4","LED","stm32-rescue:LED-RESCUE-stm32","LED_THT:LED_D5.0mm",""
"","","P1","USART1","stm32-rescue:CONN_01X03","Connector_PinHeader_2.54mm:PinHeader_1x03_P2.54mm_Vertical",""
"","","P2","USB_B","stm32-rescue:USB_A-RESCUE-stm32","Connectors_USB:USB_Micro-B_Wuerth_629105150521",""
"","","Q1","DTA114Y","Transistor_BJT:DTA114Y","TO_SOT_Packages_SMD:SOT-323_SC-70_Handsoldering",""
"","","R1","10k","stm32-rescue:R","Resistor_SMD:R_0603_1608Metric_Pad1.05x0.95mm_HandSolder",""
"","","R2","10k","stm32-rescue:R","Resistor_SMD:R_0603_1608Metric_Pad1.05x0.95mm_HandSolder",""
"","","R3","100k","stm32-rescue:R","Resistor_SMD:R_0603_1608Metric_Pad1.05x0.95mm_HandSolder",""
"","","R4","220","stm32-rescue:R","Resistor_SMD:R_0805_2012Metric_Pad1.15x1.40mm_HandSolder",""
"","","R5","220","stm32-rescue:R","Resistor_SMD:R_0805_2012Metric_Pad1.15x1.40mm_HandSolder",""
"","","R6","220","stm32-rescue:R","Resistor_SMD:R_0805_2012Metric_Pad1.15x1.40mm_HandSolder",""
"","","R7","22","stm32-rescue:R","Resistor_SMD:R_0603_1608Metric_Pad1.05x0.95mm_HandSolder",""
"","","R8","22","stm32-rescue:R","Resistor_SMD:R_0603_1608Metric_Pad1.05x0.95mm_HandSolder",""
"","","R9","1k5","stm32-rescue:R","Resistor_SMD:R_0603_1608Metric_Pad1.05x0.95mm_HandSolder",""
"","","RV1","10k","Device:R_POT","my_footprints:Potentiometer","~"
"","","SW1","Reset","stm32-rescue:SW_Push","Button_Switch_THT:SW_PUSH_6mm",""
"","","SW2","Boot","stm32-rescue:SW_Push","Button_Switch_THT:SW_PUSH_6mm",""
"","","SW3","Button0","stm32-rescue:SW_Push","Button_Switch_THT:SW_PUSH_6mm",""
"","","SW4","Button1","stm32-rescue:SW_Push","Button_Switch_THT:SW_PUSH_6mm",""
"","","U1","LM1117-3.3","stm32-rescue:LM1117-3.3-RESCUE-stm32","TO_SOT_Packages_SMD:SOT-223",""
"","","U2","STM32F042C6Tx","stm32-rescue:STM32F042C6Tx","Package_DIP:DIP-48_W15.24mm_Socket_LongPads",""
"","","U3","USBLC6-2SC6","Power_Protection:USBLC6-2SC6","TO_SOT_Packages_SMD:SOT-23-6_Handsoldering","http://www2.st.com/resource/en/datasheet/CD00050750.pdf"
"","","Y1","8MHz","Device:Crystal","Crystal:Crystal_HC49-U_Vertical","~"
"Collated Components:"
"Item","Qty","Reference(s)","Value","LibPart","Footprint","Datasheet"
"1","7","C1, C2, C3, C7, C8, C9, C10","0.1","stm32-rescue:C","Capacitor_SMD:C_0603_1608Metric_Pad1.05x0.95mm_HandSolder",""
"2","1","C4","47u","stm32-rescue:CP","Capacitor_Tantalum_SMD:CP_EIA-3216-18_Kemet-A_Pad1.58x1.35mm_HandSolder",""
"3","2","C5, C6","12","stm32-rescue:C","Capacitor_SMD:C_0603_1608Metric_Pad1.05x0.95mm_HandSolder",""
"4","1","D1","LED","stm32-rescue:LED-RESCUE-stm32","LED_THT:LED_D3.0mm",""
"5","1","D2","IP4220CZ6","Power_Protection:SP0505BAHT","TO_SOT_Packages_SMD:SOT-23-6_Handsoldering","http://www.littelfuse.com/~/media/files/littelfuse/technical%20resources/documents/data%20sheets/sp05xxba.pdf"
"6","2","D3, D4","LED","stm32-rescue:LED-RESCUE-stm32","LED_THT:LED_D5.0mm",""
"7","1","P1","USART1","stm32-rescue:CONN_01X03","Connector_PinHeader_2.54mm:PinHeader_1x03_P2.54mm_Vertical",""
"8","1","P2","USB_B","stm32-rescue:USB_A-RESCUE-stm32","Connectors_USB:USB_Micro-B_Wuerth_629105150521",""
"9","1","Q1","DTA114Y","Transistor_BJT:DTA114Y","TO_SOT_Packages_SMD:SOT-323_SC-70_Handsoldering",""
"10","2","R1, R2","10k","stm32-rescue:R","Resistor_SMD:R_0603_1608Metric_Pad1.05x0.95mm_HandSolder",""
"11","1","R3","100k","stm32-rescue:R","Resistor_SMD:R_0603_1608Metric_Pad1.05x0.95mm_HandSolder",""
"12","3","R4, R5, R6","220","stm32-rescue:R","Resistor_SMD:R_0805_2012Metric_Pad1.15x1.40mm_HandSolder",""
"13","2","R7, R8","22","stm32-rescue:R","Resistor_SMD:R_0603_1608Metric_Pad1.05x0.95mm_HandSolder",""
"14","1","R9","1k5","stm32-rescue:R","Resistor_SMD:R_0603_1608Metric_Pad1.05x0.95mm_HandSolder",""
"15","1","RV1","10k","Device:R_POT","my_footprints:Potentiometer","~"
"16","1","SW1","Reset","stm32-rescue:SW_Push","Button_Switch_THT:SW_PUSH_6mm",""
"17","1","SW2","Boot","stm32-rescue:SW_Push","Button_Switch_THT:SW_PUSH_6mm",""
"18","1","SW3","Button0","stm32-rescue:SW_Push","Button_Switch_THT:SW_PUSH_6mm",""
"19","1","SW4","Button1","stm32-rescue:SW_Push","Button_Switch_THT:SW_PUSH_6mm",""
"20","1","U1","LM1117-3.3","stm32-rescue:LM1117-3.3-RESCUE-stm32","TO_SOT_Packages_SMD:SOT-223",""
"21","1","U2","STM32F042C6Tx","stm32-rescue:STM32F042C6Tx","Package_DIP:DIP-48_W15.24mm_Socket_LongPads",""
"22","1","U3","USBLC6-2SC6","Power_Protection:USBLC6-2SC6","TO_SOT_Packages_SMD:SOT-23-6_Handsoldering","http://www2.st.com/resource/en/datasheet/CD00050750.pdf"
"23","1","Y1","8MHz","Device:Crystal","Crystal:Crystal_HC49-U_Vertical","~"

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,627 @@
(export (version D)
(design
(source /home/eddy/Docs/SAO/ELECTRONICS/STM32/F0-srcs/F0_F1_testboard/kicad/stm32.sch)
(date "Пт 17 мая 2019 09:59:43")
(tool "Eeschema (6.0.0-rc1-dev-1613-ga55d9819b)")
(sheet (number 1) (name /) (tstamps /)
(title_block
(title)
(company)
(rev)
(date)
(source stm32.sch)
(comment (number 1) (value ""))
(comment (number 2) (value ""))
(comment (number 3) (value ""))
(comment (number 4) (value "")))))
(components
(comp (ref U1)
(value LM1117-3.3)
(footprint TO_SOT_Packages_SMD:SOT-223)
(libsource (lib stm32-rescue) (part LM1117-3.3-RESCUE-stm32) (description ""))
(sheetpath (names /) (tstamps /))
(tstamp 58C431FC))
(comp (ref C4)
(value 47u)
(footprint Capacitor_Tantalum_SMD:CP_EIA-3216-18_Kemet-A_Pad1.58x1.35mm_HandSolder)
(libsource (lib stm32-rescue) (part CP) (description ""))
(sheetpath (names /) (tstamps /))
(tstamp 58C454F6))
(comp (ref D1)
(value LED)
(footprint LED_THT:LED_D3.0mm)
(libsource (lib stm32-rescue) (part LED-RESCUE-stm32) (description ""))
(sheetpath (names /) (tstamps /))
(tstamp 5909BFFC))
(comp (ref R4)
(value 220)
(footprint Resistor_SMD:R_0805_2012Metric_Pad1.15x1.40mm_HandSolder)
(libsource (lib stm32-rescue) (part R) (description ""))
(sheetpath (names /) (tstamps /))
(tstamp 5909C002))
(comp (ref R1)
(value 10k)
(footprint Resistor_SMD:R_0603_1608Metric_Pad1.05x0.95mm_HandSolder)
(libsource (lib stm32-rescue) (part R) (description ""))
(sheetpath (names /) (tstamps /))
(tstamp 590D30C8))
(comp (ref R2)
(value 10k)
(footprint Resistor_SMD:R_0603_1608Metric_Pad1.05x0.95mm_HandSolder)
(libsource (lib stm32-rescue) (part R) (description ""))
(sheetpath (names /) (tstamps /))
(tstamp 590D3334))
(comp (ref C2)
(value 0.1)
(footprint Capacitor_SMD:C_0603_1608Metric_Pad1.05x0.95mm_HandSolder)
(libsource (lib stm32-rescue) (part C) (description ""))
(sheetpath (names /) (tstamps /))
(tstamp 590D4150))
(comp (ref C1)
(value 0.1)
(footprint Capacitor_SMD:C_0603_1608Metric_Pad1.05x0.95mm_HandSolder)
(libsource (lib stm32-rescue) (part C) (description ""))
(sheetpath (names /) (tstamps /))
(tstamp 590D4832))
(comp (ref SW2)
(value Boot)
(footprint Button_Switch_THT:SW_PUSH_6mm)
(libsource (lib stm32-rescue) (part SW_Push) (description ""))
(sheetpath (names /) (tstamps /))
(tstamp 5909F6B6))
(comp (ref SW1)
(value Reset)
(footprint Button_Switch_THT:SW_PUSH_6mm)
(libsource (lib stm32-rescue) (part SW_Push) (description ""))
(sheetpath (names /) (tstamps /))
(tstamp 590A0134))
(comp (ref U2)
(value STM32F042C6Tx)
(footprint Package_DIP:DIP-48_W15.24mm_Socket_LongPads)
(libsource (lib stm32-rescue) (part STM32F042C6Tx) (description ""))
(sheetpath (names /) (tstamps /))
(tstamp 5CDF834A))
(comp (ref C7)
(value 0.1)
(footprint Capacitor_SMD:C_0603_1608Metric_Pad1.05x0.95mm_HandSolder)
(libsource (lib stm32-rescue) (part C) (description ""))
(sheetpath (names /) (tstamps /))
(tstamp 5CE67302))
(comp (ref C8)
(value 0.1)
(footprint Capacitor_SMD:C_0603_1608Metric_Pad1.05x0.95mm_HandSolder)
(libsource (lib stm32-rescue) (part C) (description ""))
(sheetpath (names /) (tstamps /))
(tstamp 5CE67308))
(comp (ref C9)
(value 0.1)
(footprint Capacitor_SMD:C_0603_1608Metric_Pad1.05x0.95mm_HandSolder)
(libsource (lib stm32-rescue) (part C) (description ""))
(sheetpath (names /) (tstamps /))
(tstamp 5CE6730E))
(comp (ref C10)
(value 0.1)
(footprint Capacitor_SMD:C_0603_1608Metric_Pad1.05x0.95mm_HandSolder)
(libsource (lib stm32-rescue) (part C) (description ""))
(sheetpath (names /) (tstamps /))
(tstamp 5CE67321))
(comp (ref P2)
(value USB_B)
(footprint Connectors_USB:USB_Micro-B_Wuerth_629105150521)
(libsource (lib stm32-rescue) (part USB_A-RESCUE-stm32) (description ""))
(sheetpath (names /) (tstamps /))
(tstamp 5CEABE76))
(comp (ref P1)
(value USART1)
(footprint Connector_PinHeader_2.54mm:PinHeader_1x03_P2.54mm_Vertical)
(libsource (lib stm32-rescue) (part CONN_01X03) (description ""))
(sheetpath (names /) (tstamps /))
(tstamp 5CEABE88))
(comp (ref R7)
(value 22)
(footprint Resistor_SMD:R_0603_1608Metric_Pad1.05x0.95mm_HandSolder)
(libsource (lib stm32-rescue) (part R) (description ""))
(sheetpath (names /) (tstamps /))
(tstamp 5CEABEA6))
(comp (ref R8)
(value 22)
(footprint Resistor_SMD:R_0603_1608Metric_Pad1.05x0.95mm_HandSolder)
(libsource (lib stm32-rescue) (part R) (description ""))
(sheetpath (names /) (tstamps /))
(tstamp 5CEABEAC))
(comp (ref D2)
(value IP4220CZ6)
(footprint TO_SOT_Packages_SMD:SOT-23-6_Handsoldering)
(datasheet http://www.littelfuse.com/~/media/files/littelfuse/technical%20resources/documents/data%20sheets/sp05xxba.pdf)
(libsource (lib Power_Protection) (part SP0505BAHT) (description "TVS Diode Array, 5.5V Standoff, 5 Channels, SOT-23-6 package"))
(sheetpath (names /) (tstamps /))
(tstamp 5CEBDB90))
(comp (ref U3)
(value USBLC6-2SC6)
(footprint TO_SOT_Packages_SMD:SOT-23-6_Handsoldering)
(datasheet http://www2.st.com/resource/en/datasheet/CD00050750.pdf)
(libsource (lib Power_Protection) (part USBLC6-2SC6) (description "Bidirectional ESD Protection Diode, SOT-23-6"))
(sheetpath (names /) (tstamps /))
(tstamp 5CED0250))
(comp (ref C3)
(value 0.1)
(footprint Capacitor_SMD:C_0603_1608Metric_Pad1.05x0.95mm_HandSolder)
(libsource (lib stm32-rescue) (part C) (description ""))
(sheetpath (names /) (tstamps /))
(tstamp 5D05A623))
(comp (ref R3)
(value 100k)
(footprint Resistor_SMD:R_0603_1608Metric_Pad1.05x0.95mm_HandSolder)
(libsource (lib stm32-rescue) (part R) (description ""))
(sheetpath (names /) (tstamps /))
(tstamp 5D1076F1))
(comp (ref D4)
(value LED)
(footprint LED_THT:LED_D5.0mm)
(libsource (lib stm32-rescue) (part LED-RESCUE-stm32) (description ""))
(sheetpath (names /) (tstamps /))
(tstamp 5D1AC2F3))
(comp (ref D3)
(value LED)
(footprint LED_THT:LED_D5.0mm)
(libsource (lib stm32-rescue) (part LED-RESCUE-stm32) (description ""))
(sheetpath (names /) (tstamps /))
(tstamp 5D1AD231))
(comp (ref Y1)
(value 8MHz)
(footprint Crystal:Crystal_HC49-U_Vertical)
(datasheet ~)
(libsource (lib Device) (part Crystal) (description "Two pin crystal"))
(sheetpath (names /) (tstamps /))
(tstamp 5D1F4994))
(comp (ref C6)
(value 12)
(footprint Capacitor_SMD:C_0603_1608Metric_Pad1.05x0.95mm_HandSolder)
(libsource (lib stm32-rescue) (part C) (description ""))
(sheetpath (names /) (tstamps /))
(tstamp 5D1F64B1))
(comp (ref C5)
(value 12)
(footprint Capacitor_SMD:C_0603_1608Metric_Pad1.05x0.95mm_HandSolder)
(libsource (lib stm32-rescue) (part C) (description ""))
(sheetpath (names /) (tstamps /))
(tstamp 5D1F7471))
(comp (ref SW3)
(value Button0)
(footprint Button_Switch_THT:SW_PUSH_6mm)
(libsource (lib stm32-rescue) (part SW_Push) (description ""))
(sheetpath (names /) (tstamps /))
(tstamp 5D2D9A50))
(comp (ref SW4)
(value Button1)
(footprint Button_Switch_THT:SW_PUSH_6mm)
(libsource (lib stm32-rescue) (part SW_Push) (description ""))
(sheetpath (names /) (tstamps /))
(tstamp 5D2E5A00))
(comp (ref R5)
(value 220)
(footprint Resistor_SMD:R_0805_2012Metric_Pad1.15x1.40mm_HandSolder)
(libsource (lib stm32-rescue) (part R) (description ""))
(sheetpath (names /) (tstamps /))
(tstamp 5D3F2F98))
(comp (ref R6)
(value 220)
(footprint Resistor_SMD:R_0805_2012Metric_Pad1.15x1.40mm_HandSolder)
(libsource (lib stm32-rescue) (part R) (description ""))
(sheetpath (names /) (tstamps /))
(tstamp 5D3F3639))
(comp (ref R9)
(value 1k5)
(footprint Resistor_SMD:R_0603_1608Metric_Pad1.05x0.95mm_HandSolder)
(libsource (lib stm32-rescue) (part R) (description ""))
(sheetpath (names /) (tstamps /))
(tstamp 5D5EA0B2))
(comp (ref Q1)
(value DTA114Y)
(footprint TO_SOT_Packages_SMD:SOT-323_SC-70_Handsoldering)
(libsource (lib Transistor_BJT) (part DTA114Y) (description "Digital PNP Transistor, 10k/47k, SOT-23"))
(sheetpath (names /) (tstamps /))
(tstamp 5D5EB488))
(comp (ref RV1)
(value 10k)
(footprint my_footprints:Potentiometer)
(datasheet ~)
(libsource (lib Device) (part R_POT) (description Potentiometer))
(sheetpath (names /) (tstamps /))
(tstamp 5D64D13D)))
(libparts
(libpart (lib Device) (part Crystal)
(description "Two pin crystal")
(docs ~)
(footprints
(fp Crystal*))
(fields
(field (name Reference) Y)
(field (name Value) Crystal))
(pins
(pin (num 1) (name 1) (type passive))
(pin (num 2) (name 2) (type passive))))
(libpart (lib Device) (part R_POT)
(description Potentiometer)
(docs ~)
(footprints
(fp Potentiometer*))
(fields
(field (name Reference) RV)
(field (name Value) R_POT))
(pins
(pin (num 1) (name 1) (type passive))
(pin (num 2) (name 2) (type passive))
(pin (num 3) (name 3) (type passive))))
(libpart (lib Power_Protection) (part SP0505BAHT)
(description "TVS Diode Array, 5.5V Standoff, 5 Channels, SOT-23-6 package")
(docs http://www.littelfuse.com/~/media/files/littelfuse/technical%20resources/documents/data%20sheets/sp05xxba.pdf)
(footprints
(fp SOT?23*))
(fields
(field (name Reference) D)
(field (name Value) SP0505BAHT)
(field (name Footprint) Package_TO_SOT_SMD:SOT-23-6))
(pins
(pin (num 1) (name K) (type passive))
(pin (num 2) (name A) (type passive))
(pin (num 3) (name K) (type passive))
(pin (num 4) (name K) (type passive))
(pin (num 5) (name K) (type passive))
(pin (num 6) (name K) (type passive))))
(libpart (lib Power_Protection) (part USBLC6-2SC6)
(description "Bidirectional ESD Protection Diode, SOT-23-6")
(docs http://www2.st.com/resource/en/datasheet/CD00050750.pdf)
(footprints
(fp SOT?23*))
(fields
(field (name Reference) U)
(field (name Value) USBLC6-2SC6)
(field (name Footprint) Package_TO_SOT_SMD:SOT-23-6))
(pins
(pin (num 1) (name IO1) (type passive))
(pin (num 2) (name GND) (type passive))
(pin (num 3) (name IO2) (type passive))
(pin (num 4) (name IO2) (type passive))
(pin (num 5) (name VBUS) (type passive))
(pin (num 6) (name IO1) (type passive))))
(libpart (lib Transistor_BJT) (part DTA114Y)
(description "Digital PNP Transistor, 10k/47k, SOT-23")
(footprints
(fp SOT?23*)
(fp SC?59*))
(fields
(field (name Reference) Q)
(field (name Value) DTA114Y))
(pins
(pin (num 1) (name B) (type input))
(pin (num 2) (name E) (type passive))
(pin (num 3) (name C) (type passive))))
(libpart (lib stm32-rescue) (part C)
(footprints
(fp C_*))
(fields
(field (name Reference) C)
(field (name Value) C))
(pins
(pin (num 1) (name ~) (type passive))
(pin (num 2) (name ~) (type passive))))
(libpart (lib stm32-rescue) (part CONN_01X03)
(footprints
(fp Pin_Header_Straight_1X*)
(fp Pin_Header_Angled_1X*)
(fp Socket_Strip_Straight_1X*)
(fp Socket_Strip_Angled_1X*))
(fields
(field (name Reference) J)
(field (name Value) CONN_01X03))
(pins
(pin (num 1) (name P1) (type passive))
(pin (num 2) (name P2) (type passive))
(pin (num 3) (name P3) (type passive))))
(libpart (lib stm32-rescue) (part CP)
(footprints
(fp CP_*))
(fields
(field (name Reference) C)
(field (name Value) CP))
(pins
(pin (num 1) (name ~) (type passive))
(pin (num 2) (name ~) (type passive))))
(libpart (lib stm32-rescue) (part LED-RESCUE-stm32)
(footprints
(fp LED*))
(fields
(field (name Reference) D)
(field (name Value) LED-RESCUE-stm32))
(pins
(pin (num 1) (name K) (type passive))
(pin (num 2) (name A) (type passive))))
(libpart (lib stm32-rescue) (part LM1117-3.3-RESCUE-stm32)
(footprints
(fp SOT-223*)
(fp TO-263*)
(fp TO-252*))
(fields
(field (name Reference) U)
(field (name Value) LM1117-3.3-RESCUE-stm32))
(pins
(pin (num 1) (name GND/ADJ) (type power_in))
(pin (num 2) (name VO) (type passive))
(pin (num 3) (name VI) (type power_in))
(pin (num 4) (name VO) (type power_out))))
(libpart (lib stm32-rescue) (part R)
(footprints
(fp R_*)
(fp R_*))
(fields
(field (name Reference) R)
(field (name Value) R))
(pins
(pin (num 1) (name ~) (type passive))
(pin (num 2) (name ~) (type passive))))
(libpart (lib stm32-rescue) (part STM32F042C6Tx)
(fields
(field (name Reference) U)
(field (name Value) STM32F042C6Tx)
(field (name Footprint) LQFP48))
(pins
(pin (num 1) (name VBAT) (type power_in))
(pin (num 2) (name PC13/RTC_OUT_ALARM/RTC_OUT_CALIB/RTC_TAMP1/RTC_TS/SYS_WKUP2) (type BiDi))
(pin (num 3) (name PC14/RCC_OSC32_IN) (type BiDi))
(pin (num 4) (name PC15/RCC_OSC32_OUT) (type BiDi))
(pin (num 5) (name PF0/CRS_SYNC/I2C1_SDA/RCC_OSC_IN) (type input))
(pin (num 6) (name PF1/I2C1_SCL/RCC_OSC_OUT) (type input))
(pin (num 7) (name NRST) (type input))
(pin (num 8) (name VSSA) (type power_in))
(pin (num 9) (name VDDA) (type power_in))
(pin (num 10) (name ADC_IN0/RTC_TAMP2/SYS_WKUP1/TIM2_CH1/TIM2_ETR/TSC_G1_IO1/USART2_CTS/PA0) (type BiDi))
(pin (num 11) (name ADC_IN1/TIM2_CH2/TSC_G1_IO2/USART2_DE/USART2_RTS/PA1) (type BiDi))
(pin (num 12) (name ADC_IN2/SYS_WKUP4/TIM2_CH3/TSC_G1_IO3/USART2_TX/PA2) (type BiDi))
(pin (num 13) (name ADC_IN3/TIM2_CH4/TSC_G1_IO4/USART2_RX/PA3) (type BiDi))
(pin (num 14) (name ADC_IN4/I2S1_WS/SPI1_NSS/TIM14_CH1/TSC_G2_IO1/USART2_CK/USB_OE/PA4) (type BiDi))
(pin (num 15) (name ADC_IN5/CEC/I2S1_CK/SPI1_SCK/TIM2_CH1/TIM2_ETR/TSC_G2_IO2/PA5) (type BiDi))
(pin (num 16) (name ADC_IN6/I2S1_MCK/SPI1_MISO/TIM16_CH1/TIM1_BKIN/TIM3_CH1/TSC_G2_IO3/PA6) (type BiDi))
(pin (num 17) (name ADC_IN7/I2S1_SD/SPI1_MOSI/TIM14_CH1/TIM17_CH1/TIM1_CH1N/TIM3_CH2/TSC_G2_IO4/PA7) (type BiDi))
(pin (num 18) (name PB0/ADC_IN8/TIM1_CH2N/TIM3_CH3/TSC_G3_IO2) (type BiDi))
(pin (num 19) (name PB1/ADC_IN9/TIM14_CH1/TIM1_CH3N/TIM3_CH4/TSC_G3_IO3) (type BiDi))
(pin (num 20) (name PB2/TSC_G3_IO4) (type BiDi))
(pin (num 21) (name PB10/CEC/I2C1_SCL/SPI2_SCK/TIM2_CH3/TSC_SYNC) (type BiDi))
(pin (num 22) (name PB11/I2C1_SDA/TIM2_CH4) (type BiDi))
(pin (num 23) (name VSS) (type power_in))
(pin (num 24) (name VDD) (type power_in))
(pin (num 25) (name PB12/SPI2_NSS/TIM1_BKIN) (type BiDi))
(pin (num 26) (name PB13/I2C1_SCL/SPI2_SCK/TIM1_CH1N) (type BiDi))
(pin (num 27) (name PB14/I2C1_SDA/SPI2_MISO/TIM1_CH2N) (type BiDi))
(pin (num 28) (name PB15/RTC_REFIN/SPI2_MOSI/SYS_WKUP7/TIM1_CH3N) (type BiDi))
(pin (num 29) (name CRS_SYNC/RCC_MCO/TIM1_CH1/USART1_CK/PA8) (type BiDi))
(pin (num 30) (name I2C1_SCL/TIM1_CH2/TSC_G4_IO1/USART1_TX/PA9) (type BiDi))
(pin (num 31) (name I2C1_SDA/TIM17_BKIN/TIM1_CH3/TSC_G4_IO2/USART1_RX/PA10) (type BiDi))
(pin (num 32) (name CAN_RX/I2C1_SCL/TIM1_CH4/TSC_G4_IO3/USART1_CTS/USB_DM/PA11) (type BiDi))
(pin (num 33) (name CAN_TX/I2C1_SDA/TIM1_ETR/TSC_G4_IO4/USART1_DE/USART1_RTS/USB_DP/PA12) (type BiDi))
(pin (num 34) (name IR_OUT/SYS_SWDIO/USB_OE/PA13) (type BiDi))
(pin (num 35) (name VSS) (type power_in))
(pin (num 36) (name VDDIO2) (type power_in))
(pin (num 37) (name SYS_SWCLK/USART2_TX/PA14) (type BiDi))
(pin (num 38) (name I2S1_WS/SPI1_NSS/TIM2_CH1/TIM2_ETR/USART2_RX/USB_OE/PA15) (type BiDi))
(pin (num 39) (name PB3/I2S1_CK/SPI1_SCK/TIM2_CH2/TSC_G5_IO1) (type BiDi))
(pin (num 40) (name PB4/I2S1_MCK/SPI1_MISO/TIM17_BKIN/TIM3_CH1/TSC_G5_IO2) (type BiDi))
(pin (num 41) (name PB5/I2C1_SMBA/I2S1_SD/SPI1_MOSI/SYS_WKUP6/TIM16_BKIN/TIM3_CH2) (type BiDi))
(pin (num 42) (name PB6/I2C1_SCL/TIM16_CH1N/TSC_G5_IO3/USART1_TX) (type BiDi))
(pin (num 43) (name PB7/I2C1_SDA/TIM17_CH1N/TSC_G5_IO4/USART1_RX) (type BiDi))
(pin (num 44) (name PF11) (type BiDi))
(pin (num 45) (name PB8/CAN_RX/CEC/I2C1_SCL/TIM16_CH1/TSC_SYNC) (type BiDi))
(pin (num 46) (name PB9/CAN_TX/I2C1_SDA/IR_OUT/SPI2_NSS/TIM17_CH1) (type BiDi))
(pin (num 47) (name VSS) (type power_in))
(pin (num 48) (name VDD) (type power_in))))
(libpart (lib stm32-rescue) (part SW_Push)
(fields
(field (name Reference) SW)
(field (name Value) SW_Push))
(pins
(pin (num 1) (name 1) (type passive))
(pin (num 2) (name 2) (type passive))))
(libpart (lib stm32-rescue) (part USB_A-RESCUE-stm32)
(footprints
(fp USB*))
(fields
(field (name Reference) P)
(field (name Value) USB_A-RESCUE-stm32))
(pins
(pin (num 1) (name VBUS) (type power_in))
(pin (num 2) (name D-) (type passive))
(pin (num 3) (name D+) (type passive))
(pin (num 4) (name GND) (type power_in))
(pin (num 5) (name shield) (type passive)))))
(libraries
(library (logical Device)
(uri /usr/share/kicad/kicad-symbols//Device.lib))
(library (logical Power_Protection)
(uri /usr/share/kicad/kicad-symbols//Power_Protection.lib))
(library (logical Transistor_BJT)
(uri /usr/share/kicad/kicad-symbols//Transistor_BJT.lib))
(library (logical stm32-rescue)
(uri /home/eddy/Docs/SAO/ELECTRONICS/STM32/F0-srcs/F0_F1_testboard/kicad/stm32-rescue.lib)))
(nets
(net (code 1) (name GND)
(node (ref P1) (pin 1))
(node (ref R4) (pin 1))
(node (ref C4) (pin 2))
(node (ref U2) (pin 35))
(node (ref D2) (pin 2))
(node (ref U1) (pin 1))
(node (ref U2) (pin 47))
(node (ref P2) (pin 4))
(node (ref R1) (pin 2))
(node (ref P2) (pin 5))
(node (ref U2) (pin 23))
(node (ref SW4) (pin 2))
(node (ref SW3) (pin 2))
(node (ref C9) (pin 1))
(node (ref C3) (pin 2))
(node (ref R3) (pin 2))
(node (ref RV1) (pin 3))
(node (ref SW1) (pin 2))
(node (ref C7) (pin 1))
(node (ref C1) (pin 2))
(node (ref U3) (pin 2))
(node (ref C8) (pin 1))
(node (ref U2) (pin 8))
(node (ref C6) (pin 2))
(node (ref C10) (pin 1))
(node (ref C5) (pin 2)))
(net (code 2) (name "Net-(R3-Pad1)")
(node (ref U2) (pin 20))
(node (ref R3) (pin 1)))
(net (code 3) (name +3V3)
(node (ref U2) (pin 24))
(node (ref SW2) (pin 2))
(node (ref C7) (pin 2))
(node (ref C2) (pin 2))
(node (ref U2) (pin 36))
(node (ref C10) (pin 2))
(node (ref C9) (pin 2))
(node (ref C8) (pin 2))
(node (ref U2) (pin 1))
(node (ref R2) (pin 2))
(node (ref D1) (pin 2))
(node (ref C4) (pin 1))
(node (ref U1) (pin 4))
(node (ref U1) (pin 2))
(node (ref U2) (pin 48))
(node (ref RV1) (pin 1))
(node (ref U2) (pin 9))
(node (ref Q1) (pin 2))
(node (ref D2) (pin 5))
(node (ref C3) (pin 1))
(node (ref D4) (pin 2))
(node (ref D3) (pin 2)))
(net (code 4) (name +5V)
(node (ref U1) (pin 3))
(node (ref U3) (pin 5))
(node (ref P2) (pin 1)))
(net (code 5) (name /OSC_IN)
(node (ref C5) (pin 1))
(node (ref U2) (pin 5))
(node (ref Y1) (pin 1)))
(net (code 6) (name /OSC_OUT)
(node (ref U2) (pin 6))
(node (ref Y1) (pin 2))
(node (ref C6) (pin 1)))
(net (code 7) (name "Net-(D3-Pad1)")
(node (ref D3) (pin 1))
(node (ref R5) (pin 1)))
(net (code 8) (name "Net-(D4-Pad1)")
(node (ref R6) (pin 1))
(node (ref D4) (pin 1)))
(net (code 9) (name "Net-(R7-Pad1)")
(node (ref R7) (pin 1))
(node (ref U3) (pin 1)))
(net (code 10) (name "Net-(R7-Pad2)")
(node (ref R7) (pin 2))
(node (ref U2) (pin 32)))
(net (code 11) (name /Tx)
(node (ref D2) (pin 3))
(node (ref P1) (pin 2))
(node (ref U2) (pin 30)))
(net (code 12) (name /Rx)
(node (ref P1) (pin 3))
(node (ref U2) (pin 31))
(node (ref D2) (pin 1)))
(net (code 13) (name "Net-(R8-Pad2)")
(node (ref R8) (pin 2))
(node (ref U2) (pin 33)))
(net (code 14) (name "Net-(R8-Pad1)")
(node (ref U3) (pin 3))
(node (ref R8) (pin 1)))
(net (code 15) (name "Net-(P2-Pad3)")
(node (ref U3) (pin 4))
(node (ref P2) (pin 3))
(node (ref R9) (pin 2)))
(net (code 16) (name "Net-(P2-Pad2)")
(node (ref P2) (pin 2))
(node (ref U3) (pin 6)))
(net (code 17) (name "Net-(U2-Pad22)")
(node (ref U2) (pin 22)))
(net (code 18) (name "Net-(Q1-Pad3)")
(node (ref Q1) (pin 3))
(node (ref R9) (pin 1)))
(net (code 19) (name "Net-(U2-Pad19)")
(node (ref U2) (pin 19)))
(net (code 20) (name "Net-(U2-Pad39)")
(node (ref U2) (pin 39)))
(net (code 21) (name "Net-(U2-Pad40)")
(node (ref U2) (pin 40)))
(net (code 22) (name "Net-(U2-Pad41)")
(node (ref U2) (pin 41)))
(net (code 23) (name "Net-(U2-Pad42)")
(node (ref U2) (pin 42)))
(net (code 24) (name "Net-(U2-Pad43)")
(node (ref U2) (pin 43)))
(net (code 25) (name "Net-(U2-Pad45)")
(node (ref U2) (pin 45)))
(net (code 26) (name "Net-(U2-Pad46)")
(node (ref U2) (pin 46)))
(net (code 27) (name "Net-(U2-Pad21)")
(node (ref U2) (pin 21)))
(net (code 28) (name "Net-(U2-Pad25)")
(node (ref U2) (pin 25)))
(net (code 29) (name "Net-(U2-Pad26)")
(node (ref U2) (pin 26)))
(net (code 30) (name "Net-(U2-Pad27)")
(node (ref U2) (pin 27)))
(net (code 31) (name "Net-(U2-Pad28)")
(node (ref U2) (pin 28)))
(net (code 32) (name "Net-(U2-Pad17)")
(node (ref U2) (pin 17)))
(net (code 33) (name "Net-(U2-Pad16)")
(node (ref U2) (pin 16)))
(net (code 34) (name "Net-(U2-Pad15)")
(node (ref U2) (pin 15)))
(net (code 35) (name "Net-(U2-Pad13)")
(node (ref U2) (pin 13)))
(net (code 36) (name "Net-(U2-Pad12)")
(node (ref U2) (pin 12)))
(net (code 37) (name "Net-(U2-Pad11)")
(node (ref U2) (pin 11)))
(net (code 38) (name /Button0)
(node (ref U2) (pin 37))
(node (ref SW4) (pin 1))
(node (ref D2) (pin 6)))
(net (code 39) (name "Net-(U2-Pad29)")
(node (ref U2) (pin 29)))
(net (code 40) (name "Net-(RV1-Pad2)")
(node (ref U2) (pin 18))
(node (ref RV1) (pin 2)))
(net (code 41) (name /Button1)
(node (ref D2) (pin 4))
(node (ref U2) (pin 38))
(node (ref SW3) (pin 1)))
(net (code 42) (name "Net-(U2-Pad4)")
(node (ref U2) (pin 4)))
(net (code 43) (name "Net-(U2-Pad3)")
(node (ref U2) (pin 3)))
(net (code 44) (name "Net-(U2-Pad2)")
(node (ref U2) (pin 2)))
(net (code 45) (name /LED0)
(node (ref U2) (pin 14))
(node (ref R5) (pin 2)))
(net (code 46) (name /LED1)
(node (ref R6) (pin 2))
(node (ref U2) (pin 10)))
(net (code 47) (name "Net-(D1-Pad1)")
(node (ref D1) (pin 1))
(node (ref R4) (pin 2)))
(net (code 48) (name /USB_PU)
(node (ref Q1) (pin 1))
(node (ref U2) (pin 34)))
(net (code 49) (name /NRST)
(node (ref U2) (pin 7))
(node (ref C1) (pin 1))
(node (ref SW1) (pin 1))
(node (ref R2) (pin 1)))
(net (code 50) (name /BOOT0)
(node (ref U2) (pin 44))
(node (ref SW2) (pin 1))
(node (ref C2) (pin 1))
(node (ref R1) (pin 1)))))

View File

@ -0,0 +1,68 @@
update=Ср 15 мая 2019 13:44:34
version=1
last_client=kicad
[cvpcb]
version=1
NetIExt=net
[general]
version=1
[eeschema]
version=1
LibDir=
[pcbnew]
version=1
PageLayoutDescrFile=
LastNetListRead=stm32.net
CopperLayerCount=2
BoardThickness=1.6
AllowMicroVias=0
AllowBlindVias=0
RequireCourtyardDefinitions=0
ProhibitOverlappingCourtyards=1
MinTrackWidth=0.2
MinViaDiameter=1
MinViaDrill=0.6
MinMicroViaDiameter=0.2
MinMicroViaDrill=0.09999999999999999
MinHoleToHole=1
TrackWidth1=0.25
TrackWidth2=0.25
TrackWidth3=0.5
TrackWidth4=1
TrackWidth5=2
ViaDiameter1=2
ViaDrill1=0.6
ViaDiameter2=1.5
ViaDrill2=0.6
ViaDiameter3=2
ViaDrill3=0.8
dPairWidth1=0.2
dPairGap1=0.25
dPairViaGap1=0.25
SilkLineWidth=0.15
SilkTextSizeV=1
SilkTextSizeH=1
SilkTextSizeThickness=0.15
SilkTextItalic=0
SilkTextUpright=1
CopperLineWidth=0.2
CopperTextSizeV=1.5
CopperTextSizeH=1.5
CopperTextThickness=0.3
CopperTextItalic=0
CopperTextUpright=1
EdgeCutLineWidth=0.09999999999999999
CourtyardLineWidth=0.12
OthersLineWidth=0.15
OthersTextSizeV=1
OthersTextSizeH=1
OthersTextSizeThickness=0.15
OthersTextItalic=0
OthersTextUpright=1
SolderMaskClearance=0
SolderMaskMinWidth=0
SolderPasteClearance=0
SolderPasteRatio=-0
[pcbnew/Layer.F.Cu]
Name=F.Cu
Type=3

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,8 @@
(sym_lib_table
(lib (name stm32-rescue)(type Legacy)(uri ${KIPRJMOD}/stm32-rescue.lib)(options "")(descr ""))
(lib (name stm32)(type Legacy)(uri /home/eddy/kicad/Kicad-Libraries/library/stm32.lib)(options "")(descr ""))
(lib (name vreg)(type Legacy)(uri /home/eddy/kicad/Kicad-Libraries/library/vreg.lib)(options "")(descr ""))
(lib (name elements)(type Legacy)(uri ${KIPRJMOD}/elements.lib)(options "")(descr ""))
(lib (name switches)(type Legacy)(uri /home/eddy/kicad/Kicad-Libraries/library/switches.lib)(options "")(descr ""))
(lib (name acs712)(type Legacy)(uri ${KIPRJMOD}/acs712.lib)(options "")(descr ""))
)

View File

@ -0,0 +1,139 @@
BINARY = pl2303
BOOTPORT ?= /dev/ttyUSB0
BOOTSPEED ?= 115200
# MCU FAMILY
FAMILY ?= F1
# MCU code
MCU ?= F103xB
# density (stm32f10x.h, lines 70-84)
DENSITY ?= MD
# change this linking script depending on particular MCU model,
LDSCRIPT ?= stm32f103xB.ld
# debug
DEFS = -DEBUG
INDEPENDENT_HEADERS=
FP_FLAGS ?= -msoft-float
ASM_FLAGS ?= -mthumb -mcpu=cortex-m3
ARCH_FLAGS = $(ASM_FLAGS) $(FP_FLAGS)
###############################################################################
# Executables
#PREFIX ?= arm-none-eabi
# gcc from arm web site
PREFIX ?= /opt/bin/arm-none-eabi
TOOLCHLIB ?= /opt/arm-none-eabi/lib
RM := rm -f
RMDIR := rmdir
CC := $(PREFIX)-gcc
# don't replace ld with gcc: the binary size would be much greater!!
LD := $(PREFIX)-ld
AR := $(PREFIX)-ar
AS := $(PREFIX)-as
SIZE := $(PREFIX)-size
OBJCOPY := $(PREFIX)-objcopy
OBJDUMP := $(PREFIX)-objdump
GDB := $(PREFIX)-gdb
STFLASH := $(shell which st-flash)
STBOOT := $(shell which stm32flash)
DFUUTIL := $(shell which dfu-util)
###############################################################################
# Source files
OBJDIR = mk
#SRC := $(wildcard *.c)
SRC = adc.c hardware.c main.c usart.c
OBJS := $(addprefix $(OBJDIR)/, $(SRC:%.c=%.o))
STARTUP = $(OBJDIR)/startup.o
OBJS += $(STARTUP)
# dependencies: we need them to recompile files if their headers-dependencies changed
DEPS := $(OBJS:.o=.d)
INC_DIR ?= ../inc
INCLUDE := -I$(INC_DIR)/Fx -I$(INC_DIR)/cm
LIB_DIR := $(INC_DIR)/ld
###############################################################################
# C flags
CFLAGS += -O2 -g -D__thumb2__=1 -MD
CFLAGS += -Wall -Werror -Wextra -Wshadow
CFLAGS += -fno-common -ffunction-sections -fdata-sections
###############################################################################
# Linker flags
LDFLAGS += -nostartfiles --static
LDFLAGS += -L$(LIB_DIR) -L$(TOOLCHLIB)
LDFLAGS += -T$(LDSCRIPT)
###############################################################################
# Used libraries
LDLIBS += -lc $(shell $(CC) $(CFLAGS) -print-libgcc-file-name)
DEFS += -DSTM32$(FAMILY) -DSTM32$(MCU) -DSTM32F10X_$(DENSITY)
ELF := $(OBJDIR)/$(BINARY).elf
LIST := $(OBJDIR)/$(BINARY).list
BIN := $(BINARY).bin
HEX := $(BINARY).hex
all: bin list size
elf: $(ELF)
bin: $(BIN)
hex: $(HEX)
list: $(LIST)
ifneq ($(MAKECMDGOALS),clean)
-include $(DEPS)
endif
$(OBJDIR):
mkdir $(OBJDIR)
$(STARTUP): $(INC_DIR)/startup/vector.c
$(CC) $(CFLAGS) $(DEFS) $(INCLUDE) $(ARCH_FLAGS) -o $@ -c $<
$(OBJDIR)/%.o: %.c
@echo " CC $<"
$(CC) $(CFLAGS) $(DEFS) $(INCLUDE) $(ARCH_FLAGS) -o $@ -c $<
$(BIN): $(ELF)
@echo " OBJCOPY $(BIN)"
$(OBJCOPY) -Obinary $(ELF) $(BIN)
$(HEX): $(ELF)
@echo " OBJCOPY $(HEX)"
$(OBJCOPY) -Oihex $(ELF) $(HEX)
$(LIST): $(ELF)
@echo " OBJDUMP $(LIST)"
$(OBJDUMP) -S $(ELF) > $(LIST)
$(ELF): $(OBJDIR) $(OBJS)
@echo " LD $(ELF)"
$(LD) $(LDFLAGS) $(OBJS) $(LDLIBS) -o $(ELF)
size: $(ELF)
$(SIZE) $(ELF)
clean:
@echo " CLEAN"
$(RM) $(OBJS) $(DEPS) $(ELF) $(HEX) $(LIST)
@rmdir $(OBJDIR) 2>/dev/null || true
flash: $(BIN)
@echo " FLASH $(BIN)"
$(STFLASH) write $(BIN) 0x8000000
boot: $(BIN)
@echo " LOAD $(BIN) through bootloader"
$(STBOOT) -b$(BOOTSPEED) $(BOOTPORT) -w $(BIN)
dfuboot: $(BIN)
@echo " LOAD $(BIN) THROUGH DFU"
$(DFUUTIL) -a0 -D $(BIN) -s 0x08000000
.PHONY: clean flash boot

View File

@ -0,0 +1 @@
Simple test for STM32F103, blinking PA0/PA1, two user buttons (PA14 and PA15) and USB (PL2303 emulator) <> USART1 echo.

72
F1-nolib/F1_testbrd/adc.c Normal file
View File

@ -0,0 +1,72 @@
/*
* This file is part of the Chiller project.
* Copyright 2018 Edward V. Emelianov <edward.emelianoff@gmail.com>.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "adc.h"
/**
* @brief ADC_array - array for ADC channels with median filtering:
* 0 - Rvar
* 1 - internal Tsens
* 2 - Vref
*/
uint16_t ADC_array[NUMBER_OF_ADC_CHANNELS*9];
/**
* @brief getADCval - calculate median value for `nch` channel
* @param nch - number of channel
* @return
*/
uint16_t getADCval(int nch){
int i, addr = nch;
register uint16_t temp;
#define PIX_SORT(a,b) { if ((a)>(b)) PIX_SWAP((a),(b)); }
#define PIX_SWAP(a,b) { temp=(a);(a)=(b);(b)=temp; }
uint16_t p[9];
for(i = 0; i < 9; ++i, addr += NUMBER_OF_ADC_CHANNELS) // first we should prepare array for optmed
p[i] = ADC_array[addr];
PIX_SORT(p[1], p[2]) ; PIX_SORT(p[4], p[5]) ; PIX_SORT(p[7], p[8]) ;
PIX_SORT(p[0], p[1]) ; PIX_SORT(p[3], p[4]) ; PIX_SORT(p[6], p[7]) ;
PIX_SORT(p[1], p[2]) ; PIX_SORT(p[4], p[5]) ; PIX_SORT(p[7], p[8]) ;
PIX_SORT(p[0], p[3]) ; PIX_SORT(p[5], p[8]) ; PIX_SORT(p[4], p[7]) ;
PIX_SORT(p[3], p[6]) ; PIX_SORT(p[1], p[4]) ; PIX_SORT(p[2], p[5]) ;
PIX_SORT(p[4], p[7]) ; PIX_SORT(p[4], p[2]) ; PIX_SORT(p[6], p[4]) ;
PIX_SORT(p[4], p[2]) ;
return p[4];
#undef PIX_SORT
#undef PIX_SWAP
}
// return MCU temperature (degrees of celsius * 10)
int32_t getMCUtemp(){
// Temp = (V25 - Vsense)/Avg_Slope + 25
// V_25 = 1.45V, Slope = 4.3e-3
int32_t Vsense = getVdd() * getADCval(1);
Vsense /= 4096;
int32_t temperature = 145 - Vsense;
temperature *= 233;
temperature /= 10; // convert from *100 to *10
temperature += 250;
return(temperature);
}
// return Vdd * 100 (V)
uint32_t getVdd(){
uint32_t vdd = ((uint32_t) *VREFINT_CAL_ADDR) * (uint32_t)300; // 3.0V
vdd /= getADCval(2);
return vdd;
}

29
F1-nolib/F1_testbrd/adc.h Normal file
View File

@ -0,0 +1,29 @@
/*
* This file is part of the Chiller project.
* Copyright 2018 Edward V. Emelianov <edward.emelianoff@gmail.com>.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef ADC_H
#define ADC_H
#include "stm32f1.h"
#define NUMBER_OF_ADC_CHANNELS (3)
extern uint16_t ADC_array[];
int32_t getMCUtemp();
uint32_t getVdd();
uint16_t getADCval(int nch);
#endif // ADC_H

View File

@ -0,0 +1,76 @@
/*
* geany_encoding=koi8-r
* hardware.c - hardware-dependent macros & functions
*
* Copyright 2018 Edward V. Emelianov <eddy@sao.ru, edward.emelianoff@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*
*/
#include "adc.h"
#include "hardware.h"
#include "usart.h"
static inline void gpio_setup(){
// Enable clocks to the GPIO subsystems (PB for ADC), turn on AFIO clocking to disable SWD/JTAG
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN | RCC_APB2ENR_AFIOEN;
// turn off SWJ/JTAG
AFIO->MAPR = AFIO_MAPR_SWJ_CFG_DISABLE;
// turn off USB pullup
GPIOA->ODR = (1<<13)|(1<<14)|(1<<15); // turn off usb pullup & turn on pullups for buttons
// Set leds (PA0/PA4) as opendrain output
GPIOA->CRL = CRL(0, CNF_ODOUTPUT|MODE_SLOW) | CRL(4, CNF_ODOUTPUT|MODE_SLOW);
// Set buttons (PA14/15) as inputs with weak pullups, USB pullup (PA13) - opendrain output
GPIOA->CRH = CRH(13, CNF_ODOUTPUT|MODE_SLOW) | CRH(14, CNF_PUDINPUT|MODE_INPUT)
| CRH(15, CNF_PUDINPUT|MODE_INPUT);
}
static inline void adc_setup(){
GPIOB->CRL |= CRL(0, CNF_ANALOG|MODE_INPUT);
uint16_t ctr = 0; // 0xfff0 - more than 1.3ms
// Enable clocking
RCC->APB2ENR |= RCC_APB2ENR_ADC1EN;
RCC->CFGR &= ~(RCC_CFGR_ADCPRE);
RCC->CFGR |= RCC_CFGR_ADCPRE_1;
// sampling time - 239.5 cycles for channels 8, 16 and 17
ADC1->SMPR2 = ADC_SMPR2_SMP8;
ADC1->SMPR1 = ADC_SMPR1_SMP16 | ADC_SMPR1_SMP17;
// wake up ADC
ADC1->CR2 |= ADC_CR2_ADON;
// we have three conversions in group -> ADC1->SQR1[L] = 2, order: 8->16->17
ADC1->SQR3 = 8 | (16<<5)| (17<<10);
ADC1->SQR1 = ADC_SQR1_L_1;
// calibration
ADC1->CR2 |= ADC_CR2_CAL;
while((ADC1->CR2 & ADC_CR2_CAL) && ++ctr < 0xfff0);
// DMA configuration
RCC->AHBENR |= RCC_AHBENR_DMA1EN;
DMA1_Channel1->CPAR = (uint32_t) (&(ADC1->DR));
DMA1_Channel1->CMAR = (uint32_t)(ADC_array);
DMA1_Channel1->CNDTR = NUMBER_OF_ADC_CHANNELS * 9;
DMA1_Channel1->CCR |= DMA_CCR_MINC | DMA_CCR_MSIZE_0 | DMA_CCR_PSIZE_0 | DMA_CCR_CIRC;
DMA1_Channel1->CCR |= DMA_CCR_EN;
// continuous mode & DMA; enable vref & Tsens; start
ADC1->CR2 |= ADC_CR2_CONT | ADC_CR2_DMA | ADC_CR2_TSVREFE | ADC_CR2_SWSTART;
// turn ON ADC
ADC1->CR2 |= ADC_CR2_ADON;
}
void hw_setup(){
gpio_setup();
adc_setup();
}

View File

@ -0,0 +1,51 @@
/*
* geany_encoding=koi8-r
* hardware.h
*
* Copyright 2018 Edward V. Emelianov <eddy@sao.ru, edward.emelianoff@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*
*/
#pragma once
#ifndef __HARDWARE_H__
#define __HARDWARE_H__
#include "stm32f1.h"
// LEDS: 0 - PA0, 1 - PA4
// LED0 - blinking each second
#define LED0_port GPIOA
#define LED0_pin (1<<0)
// LED1 - PWM
#define LED1_port GPIOA
#define LED1_pin (1<<4)
// Buttons' state: PA14 (1)/PA15 (0)
#define GET_BTN0() ((GPIOA->IDR & (1<<15)) ? 0 : 1)
#define GET_BTN1() ((GPIOA->IDR & (1<<14)) ? 0 : 1)
// USB pullup (not used in STM32F0x2!) - PA13
#define USBPU_port GPIOA
#define USBPU_pin (1<<13)
#define LED_blink(x) pin_toggle(x ## _port, x ## _pin)
#define LED_on(x) pin_clear(x ## _port, x ## _pin)
#define LED_off(x) pin_set(x ## _port, x ## _pin)
void hw_setup();
#endif // __HARDWARE_H__

228
F1-nolib/F1_testbrd/main.c Normal file
View File

@ -0,0 +1,228 @@
/*
* main.c
*
* Copyright 2017 Edward V. Emelianoff <eddy@sao.ru, edward.emelianoff@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
#include "adc.h"
#include "hardware.h"
#include "usart.h"
#include "usb.h"
#include "usb_lib.h"
#include <string.h> // memcpy
volatile uint32_t Tms = 0;
#define USB_send(x) do{}while(0)
/* Called when systick fires */
void sys_tick_handler(void){
++Tms;
}
void iwdg_setup(){
uint32_t tmout = 16000000;
/* Enable the peripheral clock RTC */
/* (1) Enable the LSI (40kHz) */
/* (2) Wait while it is not ready */
RCC->CSR |= RCC_CSR_LSION; /* (1) */
while((RCC->CSR & RCC_CSR_LSIRDY) != RCC_CSR_LSIRDY){if(--tmout == 0) break;} /* (2) */
/* Configure IWDG */
/* (1) Activate IWDG (not needed if done in option bytes) */
/* (2) Enable write access to IWDG registers */
/* (3) Set prescaler by 64 (1.6ms for each tick) */
/* (4) Set reload value to have a rollover each 2s */
/* (5) Check if flags are reset */
/* (6) Refresh counter */
IWDG->KR = IWDG_START; /* (1) */
IWDG->KR = IWDG_WRITE_ACCESS; /* (2) */
IWDG->PR = IWDG_PR_PR_1; /* (3) */
IWDG->RLR = 1250; /* (4) */
tmout = 16000000;
while(IWDG->SR){if(--tmout == 0) break;} /* (5) */
IWDG->KR = IWDG_REFRESH; /* (6) */
}
char *parse_cmd(char *buf){
static char btns[] = "BTN0=0, BTN1=0\n";
if(buf[1] != '\n') return buf;
switch(*buf){
case '0':
pin_set(GPIOA, 1<<4);
break;
case '1':
pin_clear(GPIOA, 1<<4);
break;
case 'a':
printu(getADCval(0)); newline();
printu(getADCval(1)); newline();
printu(getADCval(2)); newline();
break;
case 'b':
btns[5] = GET_BTN0() + '0';
btns[13] = GET_BTN1() + '0';
return btns;
break;
case 'c':
printu((uint32_t) *VREFINT_CAL_ADDR);
newline();
break;
case 'p':
pin_toggle(USBPU_port, USBPU_pin);
SEND("USB pullup is ");
if(pin_read(USBPU_port, USBPU_pin)) SEND("off");
else SEND("on");
newline();
break;
case 'A':
return u2str(getADCval(0));
break;
case 'L':
USB_send("Very long test string for USB (it's length is more than 64 bytes).\n"
"This is another part of the string! Can you see all of this?\n");
return "Long test sent\n";
break;
case 'R':
USB_send("Soft reset\n");
SEND("Soft reset\n");
NVIC_SystemReset();
break;
case 'S':
USB_send("Test string for USB\n");
return "Short test sent\n";
break;
case 'T':
return u2str(getMCUtemp());
break;
case 'V':
return u2str(getVdd());
break;
case 'W':
USB_send("Wait for reboot\n");
SEND("Wait for reboot\n");
while(1){nop();};
break;
default: // help
return
"0/1 - turn on/off LED1"
"'b' - get buttons's state\n"
"'p' - toggle USB pullup\n"
"'A' - get ADC8 value\n"
"'L' - send long string over USB\n"
"'R' - software reset\n"
"'S' - send short string over USB\n"
"'T' - MCU temperature\n"
"'V' - Vdd\n"
"'W' - test watchdog\n"
;
break;
}
return NULL;
}
/*
// usb getline
char *get_USB(){
static char tmpbuf[129], *curptr = tmpbuf;
static int rest = 128;
int x = USB_receive(curptr, rest);
curptr[x] = 0;
if(!x) return NULL;
SEND("got: ");
SEND(curptr);
newline();
if(curptr[x-1] == '\n'){
curptr = tmpbuf;
rest = 128;
return tmpbuf;
}
curptr += x; rest -= x;
if(rest <= 0){ // buffer overflow
curptr = tmpbuf;
rest = 128;
}
return NULL;
}*/
int main(void){
uint32_t lastT = 0, lastB = 0, LEDperiod = 499;
sysreset();
StartHSE();
hw_setup();
usart_setup();
SysTick_Config(72000);
SEND("Hello! I'm ready.\n");
if(RCC->CSR & RCC_CSR_IWDGRSTF){ // watchdog reset occured
SEND("WDGRESET=1\n");
}
if(RCC->CSR & RCC_CSR_SFTRSTF){ // software reset occured
SEND("SOFTRESET=1\n");
}
RCC->CSR |= RCC_CSR_RMVF; // remove reset flags
//USB_setup();
iwdg_setup();
while (1){
IWDG->KR = IWDG_REFRESH; // refresh watchdog
if(lastT > Tms || Tms - lastT > LEDperiod){
LED_blink(LED0);
lastT = Tms;
transmit_tbuf(); // non-blocking transmission of data from UART buffer every 0.5s
}
//usb_proc();
int r = 0;
char *txt, *ans;
/*if((txt = get_USB())){
ans = parse_cmd(txt);
SEND("Received data over USB:\n");
SEND(txt);
newline();
if(ans) USB_send(ans);
}*/
if(usartrx()){ // usart1 received data, store in in buffer
r = usart_getline(&txt);
if(r){
txt[r] = 0;
ans = parse_cmd(txt);
if(ans){
usart_send(ans);
transmit_tbuf();
}
}
}
// check buttons - each 50ms (increase / decrease LED blinking period by 10)
if(Tms - lastB > 49){
lastB = Tms;
uint8_t btn0 = GET_BTN0(), btn1 = GET_BTN1();
// both: set to default
if(btn0 && btn1){
LEDperiod = 499;
}else if(btn0){
if(LEDperiod < 1989) LEDperiod += 10;
}else if(btn1){
if(LEDperiod > 29) LEDperiod -= 10;
}
}
}
return 0;
}

BIN
F1-nolib/F1_testbrd/pl2303.bin Executable file

Binary file not shown.

217
F1-nolib/F1_testbrd/usart.c Normal file
View File

@ -0,0 +1,217 @@
/*
* usart.c
*
* Copyright 2018 Edward V. Emelianoff <eddy@sao.ru, edward.emelianoff@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
#include "stm32f1.h"
#include "usart.h"
extern volatile uint32_t Tms;
static volatile int idatalen[2] = {0,0}; // received data line length (including '\n')
static volatile int odatalen[2] = {0,0};
volatile int linerdy = 0, // received data ready
dlen = 0, // length of data (including '\n') in current buffer
bufovr = 0, // input buffer overfull
txrdy = 1 // transmission done
;
int rbufno = 0, tbufno = 0; // current rbuf/tbuf numbers
static char rbuf[2][UARTBUFSZI], tbuf[2][UARTBUFSZO]; // receive & transmit buffers
static char *recvdata = NULL;
/**
* return length of received data (without trailing zero)
*/
int usart_getline(char **line){
if(bufovr){
bufovr = 0;
linerdy = 0;
return 0;
}
*line = recvdata;
linerdy = 0;
return dlen;
}
// transmit current tbuf and swap buffers
void transmit_tbuf(){
uint32_t tmout = 16000000;
while(!txrdy){if(--tmout == 0) return;}; // wait for previos buffer transmission
register int l = odatalen[tbufno];
if(!l) return;
txrdy = 0;
odatalen[tbufno] = 0;
DMA1_Channel4->CCR &= ~DMA_CCR_EN;
DMA1_Channel4->CMAR = (uint32_t) tbuf[tbufno]; // mem
DMA1_Channel4->CNDTR = l;
DMA1_Channel4->CCR |= DMA_CCR_EN;
tbufno = !tbufno;
}
void usart_putchar(const char ch){
if(odatalen[tbufno] == UARTBUFSZO) transmit_tbuf();
tbuf[tbufno][odatalen[tbufno]++] = ch;
}
void usart_send(const char *str){
uint32_t x = 512;
while(*str && --x){
if(odatalen[tbufno] == UARTBUFSZO) transmit_tbuf();
tbuf[tbufno][odatalen[tbufno]++] = *str++;
}
}
void newline(){
usart_putchar('\n');
transmit_tbuf();
}
/*
* USART speed: baudrate = Fck/(USARTDIV)
* USARTDIV stored in USART->BRR
*
* for 72MHz USARTDIV=72000/f(kboud); so for 115200 USARTDIV=72000/115.2=625 -> BRR=0x271
* 9600: BRR = 7500 (0x1D4C)
*/
void usart_setup(){
uint32_t tmout = 16000000;
// PA9 - Tx, PA10 - Rx
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_USART1EN;
RCC->AHBENR |= RCC_AHBENR_DMA1EN;
GPIOA->CRH |= CRH(9, CNF_AFPP|MODE_NORMAL) | CRH(10, CNF_FLINPUT|MODE_INPUT);
// USART1 Tx DMA - Channel4 (Rx - channel 5)
DMA1_Channel4->CPAR = (uint32_t) &USART1->DR; // periph
DMA1_Channel4->CCR |= DMA_CCR_MINC | DMA_CCR_DIR | DMA_CCR_TCIE; // 8bit, mem++, mem->per, transcompl irq
// Tx CNDTR set @ each transmission due to data size
NVIC_SetPriority(DMA1_Channel4_IRQn, 3);
NVIC_EnableIRQ(DMA1_Channel4_IRQn);
NVIC_SetPriority(USART1_IRQn, 0);
// setup usart1
USART1->BRR = 72000000 / 115200;
USART1->CR1 = USART_CR1_TE | USART_CR1_RE | USART_CR1_UE; // 1start,8data,nstop; enable Rx,Tx,USART
while(!(USART1->SR & USART_SR_TC)){if(--tmout == 0) break;} // polling idle frame Transmission
USART1->SR = 0; // clear flags
USART1->CR1 |= USART_CR1_RXNEIE; // allow Rx IRQ
USART1->CR3 = USART_CR3_DMAT; // enable DMA Tx
NVIC_EnableIRQ(USART1_IRQn);
}
void usart1_isr(){
#ifdef CHECK_TMOUT
static uint32_t tmout = 0;
#endif
if(USART1->SR & USART_SR_RXNE){ // RX not emty - receive next char
#ifdef CHECK_TMOUT
if(tmout && Tms >= tmout){ // set overflow flag
bufovr = 1;
idatalen[rbufno] = 0;
}
tmout = Tms + TIMEOUT_MS;
if(!tmout) tmout = 1; // prevent 0
#endif
uint8_t rb = USART1->DR;
if(idatalen[rbufno] < UARTBUFSZI){ // put next char into buf
rbuf[rbufno][idatalen[rbufno]++] = rb;
if(rb == '\n'){ // got newline - line ready
linerdy = 1;
dlen = idatalen[rbufno];
recvdata = rbuf[rbufno];
// prepare other buffer
rbufno = !rbufno;
idatalen[rbufno] = 0;
#ifdef CHECK_TMOUT
// clear timeout at line end
tmout = 0;
#endif
}
}else{ // buffer overrun
bufovr = 1;
idatalen[rbufno] = 0;
#ifdef CHECK_TMOUT
tmout = 0;
#endif
}
}
}
// return string buffer with val
char *u2str(uint32_t val){
static char bufa[11];
char bufb[10];
int l = 0, bpos = 0;
if(!val){
bufa[0] = '0';
l = 1;
}else{
while(val){
bufb[l++] = val % 10 + '0';
val /= 10;
}
int i;
bpos += l;
for(i = 0; i < l; ++i){
bufa[--bpos] = bufb[i];
}
}
bufa[l + bpos] = 0;
return bufa;
}
// print 32bit unsigned int
void printu(uint32_t val){
usart_send(u2str(val));
}
// print 32bit unsigned int as hex
void printuhex(uint32_t val){
usart_send("0x");
uint8_t *ptr = (uint8_t*)&val + 3;
int i, j;
for(i = 0; i < 4; ++i, --ptr){
for(j = 1; j > -1; --j){
register uint8_t half = (*ptr >> (4*j)) & 0x0f;
if(half < 10) usart_putchar(half + '0');
else usart_putchar(half - 10 + 'a');
}
}
}
// dump memory buffer
void hexdump(uint8_t *arr, uint16_t len){
for(uint16_t l = 0; l < len; ++l, ++arr){
for(int16_t j = 1; j > -1; --j){
register uint8_t half = (*arr >> (4*j)) & 0x0f;
if(half < 10) usart_putchar(half + '0');
else usart_putchar(half - 10 + 'a');
}
if(l % 16 == 15) usart_putchar('\n');
else if(l & 1) usart_putchar(' ');
}
}
void dma1_channel4_isr(){
if(DMA1->ISR & DMA_ISR_TCIF4){ // Tx
DMA1->IFCR = DMA_IFCR_CTCIF4; // clear TC flag
txrdy = 1;
}
}

View File

@ -0,0 +1,61 @@
/*
* usart.h
*
* Copyright 2017 Edward V. Emelianoff <eddy@sao.ru, edward.emelianoff@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
#pragma once
#ifndef __USART_H__
#define __USART_H__
// input and output buffers size
#define UARTBUFSZI (32)
#define UARTBUFSZO (512)
// timeout between data bytes
#ifndef TIMEOUT_MS
#define TIMEOUT_MS (1500)
#endif
// macro for static strings
#define SEND(str) usart_send(str)
#define STR_HELPER(s) #s
#define STR(s) STR_HELPER(s)
#ifdef EBUG
#define MSG(str) do{SEND(__FILE__ " (L" STR(__LINE__) "): " str);}while(0)
#else
#define MSG(str)
#endif
#define usartrx() (linerdy)
#define usartovr() (bufovr)
extern volatile int linerdy, bufovr, txrdy;
void transmit_tbuf();
void usart_setup();
int usart_getline(char **line);
void usart_send(const char *str);
void newline();
void usart_putchar(const char ch);
char *u2str(uint32_t val);
void printu(uint32_t val);
void printuhex(uint32_t val);
void hexdump(uint8_t *arr, uint16_t len);
#endif // __USART_H__

158
F1-nolib/F1_testbrd/usb.c Normal file
View File

@ -0,0 +1,158 @@
/*
* geany_encoding=koi8-r
* usb.c - base functions for different USB types
*
* Copyright 2018 Edward V. Emelianov <eddy@sao.ru, edward.emelianoff@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*
*/
#include "usb.h"
#include "usb_lib.h"
#include "usart.h"
#include <string.h> // memcpy, memmove
// incoming buffer size
#define IDATASZ (256)
static uint8_t incoming_data[IDATASZ];
static uint8_t ovfl = 0;
static uint16_t idatalen = 0;
static volatile uint8_t tx_succesfull = 0;
static int8_t usbON = 0; // ==1 when USB fully configured
// interrupt IN handler (never used?)
static uint16_t EP1_Handler(ep_t ep){
if (ep.rx_flag){
ep.status = SET_VALID_TX(ep.status);
ep.status = KEEP_STAT_RX(ep.status);
}else if (ep.tx_flag){
ep.status = SET_VALID_RX(ep.status);
ep.status = SET_STALL_TX(ep.status);
}
return ep.status;
}
// data IN/OUT handler
static uint16_t EP23_Handler(ep_t ep){
if(ep.rx_flag){
int rd = ep.rx_cnt, rest = IDATASZ - idatalen;
if(rd){
if(rd <= rest){
idatalen += EP_Read(2, &incoming_data[idatalen]);
ovfl = 0;
}else{
ep.status = SET_NAK_RX(ep.status);
ovfl = 1;
return ep.status;
}
}
// end of transaction: clear DTOGs
ep.status = CLEAR_DTOG_RX(ep.status);
ep.status = CLEAR_DTOG_TX(ep.status);
ep.status = SET_STALL_TX(ep.status);
}else if (ep.tx_flag){
ep.status = KEEP_STAT_TX(ep.status);
tx_succesfull = 1;
}
ep.status = SET_VALID_RX(ep.status);
return ep.status;
}
void USB_setup(){
RCC->APB1ENR |= RCC_APB1ENR_CRSEN | RCC_APB1ENR_USBEN; // enable CRS (hsi48 sync) & USB
RCC->CFGR3 &= ~RCC_CFGR3_USBSW; // reset USB
RCC->CR2 |= RCC_CR2_HSI48ON; // turn ON HSI48
uint32_t tmout = 16000000;
while(!(RCC->CR2 & RCC_CR2_HSI48RDY)){if(--tmout == 0) break;}
FLASH->ACR = FLASH_ACR_PRFTBE | FLASH_ACR_LATENCY;
CRS->CFGR &= ~CRS_CFGR_SYNCSRC;
CRS->CFGR |= CRS_CFGR_SYNCSRC_1; // USB SOF selected as sync source
CRS->CR |= CRS_CR_AUTOTRIMEN; // enable auto trim
CRS->CR |= CRS_CR_CEN; // enable freq counter & block CRS->CFGR as read-only
RCC->CFGR |= RCC_CFGR_SW;
// allow RESET and CTRM interrupts
USB->CNTR = USB_CNTR_RESETM | USB_CNTR_CTRM;
// clear flags
USB->ISTR = 0;
// and activate pullup
USB->BCDR |= USB_BCDR_DPPU;
NVIC_EnableIRQ(USB_IRQn);
}
void usb_proc(){
if(USB_GetState() == USB_CONFIGURE_STATE){ // USB configured - activate other endpoints
if(!usbON){ // endpoints not activated
// make new BULK endpoint
// Buffer have 1024 bytes, but last 256 we use for CAN bus (30.2 of RM: USB main features)
EP_Init(1, EP_TYPE_INTERRUPT, 10, 0, EP1_Handler); // IN1 - transmit
EP_Init(2, EP_TYPE_BULK, 0, USB_RXBUFSZ, EP23_Handler); // OUT2 - receive data
EP_Init(3, EP_TYPE_BULK, USB_TXBUFSZ, 0, EP23_Handler); // IN3 - transmit data
usbON = 1;
}
}else{
usbON = 0;
}
}
void USB_send(char *buf){
uint16_t l = 0, ctr = 0;
char *p = buf;
while(*p++) ++l;
while(l){
uint16_t s = (l > USB_TXBUFSZ) ? USB_TXBUFSZ : l;
tx_succesfull = 0;
EP_Write(3, (uint8_t*)&buf[ctr], s);
uint32_t ctra = 1000000;
while(--ctra && tx_succesfull == 0);
l -= s;
ctr += s;
}
}
/**
* @brief USB_receive
* @param buf (i) - buffer for received data
* @param bufsize - its size
* @return amount of received bytes
*/
int USB_receive(char *buf, int bufsize){
if(!bufsize || !idatalen) return 0;
USB->CNTR = 0;
int sz = (idatalen > bufsize) ? bufsize : idatalen, rest = idatalen - sz;
memcpy(buf, incoming_data, sz);
if(rest > 0){
memmove(incoming_data, &incoming_data[sz], rest);
idatalen = rest;
}else idatalen = 0;
if(ovfl){
EP23_Handler(endpoints[2]);
uint16_t epstatus = USB->EPnR[2];
epstatus = CLEAR_DTOG_RX(epstatus);
epstatus = SET_VALID_RX(epstatus);
USB->EPnR[2] = epstatus;
}
USB->CNTR = USB_CNTR_RESETM | USB_CNTR_CTRM;
return sz;
}
/**
* @brief USB_configured
* @return 1 if USB is in configured state
*/
int USB_configured(){
return usbON;
}

37
F1-nolib/F1_testbrd/usb.h Normal file
View File

@ -0,0 +1,37 @@
/*
* geany_encoding=koi8-r
* usb.h
*
* Copyright 2018 Edward V. Emelianov <eddy@sao.ru, edward.emelianoff@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*
*/
#pragma once
#ifndef __USB_H__
#define __USB_H__
#include "hardware.h"
#define BUFFSIZE (64)
void USB_setup();
void usb_proc();
void USB_send(char *buf);
int USB_receive(char *buf, int bufsize);
int USB_configured();
#endif // __USB_H__

View File

@ -0,0 +1,106 @@
/*
* geany_encoding=koi8-r
* usb_defs.h
*
* Copyright 2018 Edward V. Emelianov <eddy@sao.ru, edward.emelianoff@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*
*/
#pragma once
#ifndef __USB_DEFS_H__
#define __USB_DEFS_H__
#include <stm32f1.h>
/**
* Buffers size definition
**/
// !!! when working with CAN bus change USB_BTABLE_SIZE to 768 !!!
#define USB_BTABLE_SIZE 1024
// first 64 bytes of USB_BTABLE are registers!
#define USB_EP0_BASEADDR 64
// for USB FS EP0 buffers are from 8 to 64 bytes long (64 for PL2303)
#define USB_EP0_BUFSZ 64
// USB transmit buffer size (64 for PL2303)
#define USB_TXBUFSZ 64
// USB receive buffer size (64 for PL2303)
#define USB_RXBUFSZ 64
#define USB_BTABLE_BASE 0x40006000
#undef USB_BTABLE
#define USB_BTABLE ((USB_BtableDef *)(USB_BTABLE_BASE))
#define USB_ISTR_EPID 0x0000000F
#define USB_FNR_LSOF_0 0x00000800
#define USB_FNR_lSOF_1 0x00001000
#define USB_LPMCSR_BESL_0 0x00000010
#define USB_LPMCSR_BESL_1 0x00000020
#define USB_LPMCSR_BESL_2 0x00000040
#define USB_LPMCSR_BESL_3 0x00000080
#define USB_EPnR_CTR_RX 0x00008000
#define USB_EPnR_DTOG_RX 0x00004000
#define USB_EPnR_STAT_RX 0x00003000
#define USB_EPnR_STAT_RX_0 0x00001000
#define USB_EPnR_STAT_RX_1 0x00002000
#define USB_EPnR_SETUP 0x00000800
#define USB_EPnR_EP_TYPE 0x00000600
#define USB_EPnR_EP_TYPE_0 0x00000200
#define USB_EPnR_EP_TYPE_1 0x00000400
#define USB_EPnR_EP_KIND 0x00000100
#define USB_EPnR_CTR_TX 0x00000080
#define USB_EPnR_DTOG_TX 0x00000040
#define USB_EPnR_STAT_TX 0x00000030
#define USB_EPnR_STAT_TX_0 0x00000010
#define USB_EPnR_STAT_TX_1 0x00000020
#define USB_EPnR_EA 0x0000000F
#define USB_COUNTn_RX_BLSIZE 0x00008000
#define USB_COUNTn_NUM_BLOCK 0x00007C00
#define USB_COUNTn_RX 0x0000003F
#define USB_TypeDef USB_TypeDef_custom
typedef struct{
__IO uint32_t EPnR[8];
__IO uint32_t RESERVED1;
__IO uint32_t RESERVED2;
__IO uint32_t RESERVED3;
__IO uint32_t RESERVED4;
__IO uint32_t RESERVED5;
__IO uint32_t RESERVED6;
__IO uint32_t RESERVED7;
__IO uint32_t RESERVED8;
__IO uint32_t CNTR;
__IO uint32_t ISTR;
__IO uint32_t FNR;
__IO uint32_t DADDR;
__IO uint32_t BTABLE;
__IO uint32_t LPMCSR;
__IO uint32_t BCDR;
} USB_TypeDef;
typedef struct{
__IO uint16_t USB_ADDR_TX;
__IO uint16_t USB_COUNT_TX;
__IO uint16_t USB_ADDR_RX;
__IO uint16_t USB_COUNT_RX;
} USB_EPDATA_TypeDef;
typedef struct{
__IO USB_EPDATA_TypeDef EP[8];
} USB_BtableDef;
#endif // __USB_DEFS_H__

View File

@ -0,0 +1,484 @@
/*
* geany_encoding=koi8-r
* usb_lib.c
*
* Copyright 2018 Edward V. Emelianov <eddy@sao.ru, edward.emelianoff@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*
*/
#include <stdint.h>
#include "usb_lib.h"
#include <string.h> // memcpy
#include "usart.h"
ep_t endpoints[ENDPOINTS_NUM];
static usb_dev_t USB_Dev;
static usb_LineCoding lineCoding = {115200, 0, 0, 8};
static config_pack_t setup_packet;
static uint8_t ep0databuf[EP0DATABUF_SIZE];
static uint8_t ep0dbuflen = 0;
usb_LineCoding getLineCoding(){return lineCoding;}
// definition of parts common for USB_DeviceDescriptor & USB_DeviceQualifierDescriptor
#define bcdUSB_L 0x10
#define bcdUSB_H 0x01
#define bDeviceClass 0
#define bDeviceSubClass 0
#define bDeviceProtocol 0
#define bNumConfigurations 1
static const uint8_t USB_DeviceDescriptor[] = {
18, // bLength
0x01, // bDescriptorType - Device descriptor
bcdUSB_L, // bcdUSB_L - 1.10
bcdUSB_H, // bcdUSB_H
bDeviceClass, // bDeviceClass - USB_COMM
bDeviceSubClass, // bDeviceSubClass
bDeviceProtocol, // bDeviceProtocol
USB_EP0_BUFSZ, // bMaxPacketSize
0x7b, // idVendor_L PL2303: VID=0x067b, PID=0x2303
0x06, // idVendor_H
0x03, // idProduct_L
0x23, // idProduct_H
0x00, // bcdDevice_Ver_L
0x03, // bcdDevice_Ver_H
0x01, // iManufacturer
0x02, // iProduct
0x00, // iSerialNumber
bNumConfigurations // bNumConfigurations
};
static const uint8_t USB_DeviceQualifierDescriptor[] = {
10, //bLength
0x06, // bDescriptorType - Device qualifier
bcdUSB_L, // bcdUSB_L
bcdUSB_H, // bcdUSB_H
bDeviceClass, // bDeviceClass
bDeviceSubClass, // bDeviceSubClass
bDeviceProtocol, // bDeviceProtocol
USB_EP0_BUFSZ, // bMaxPacketSize0
bNumConfigurations, // bNumConfigurations
0x00 // Reserved
};
static const uint8_t USB_ConfigDescriptor[] = {
/*Configuration Descriptor*/
0x09, /* bLength: Configuration Descriptor size */
0x02, /* bDescriptorType: Configuration */
39, /* wTotalLength:no of returned bytes */
0x00,
0x01, /* bNumInterfaces: 1 interface */
0x01, /* bConfigurationValue: Configuration value */
0x00, /* iConfiguration: Index of string descriptor describing the configuration */
0xa0, /* bmAttributes - Bus powered, Remote wakeup */
0x32, /* MaxPower 100 mA */
/*---------------------------------------------------------------------------*/
/*Interface Descriptor */
0x09, /* bLength: Interface Descriptor size */
0x04, /* bDescriptorType: Interface */
0x00, /* bInterfaceNumber: Number of Interface */
0x00, /* bAlternateSetting: Alternate setting */
0x03, /* bNumEndpoints: 3 endpoints used */
0xff, /* bInterfaceClass */
0x00, /* bInterfaceSubClass */
0x00, /* bInterfaceProtocol */
0x00, /* iInterface: */
///////////////////////////////////////////////////
/*Endpoint 1 Descriptor*/
0x07, /* bLength: Endpoint Descriptor size */
0x05, /* bDescriptorType: Endpoint */
0x81, /* bEndpointAddress IN1 */
0x03, /* bmAttributes: Interrupt */
0x0a, /* wMaxPacketSize LO: */
0x00, /* wMaxPacketSize HI: */
0x01, /* bInterval: */
/*Endpoint OUT2 Descriptor*/
0x07, /* bLength: Endpoint Descriptor size */
0x05, /* bDescriptorType: Endpoint */
0x02, /* bEndpointAddress: OUT2 */
0x02, /* bmAttributes: Bulk */
(USB_RXBUFSZ & 0xff), /* wMaxPacketSize: 64 */
(USB_RXBUFSZ >> 8),
0x00, /* bInterval: ignore for Bulk transfer */
/*Endpoint IN3 Descriptor*/
0x07, /* bLength: Endpoint Descriptor size */
0x05, /* bDescriptorType: Endpoint */
0x83, /* bEndpointAddress IN3 */
0x02, /* bmAttributes: Bulk */
(USB_TXBUFSZ & 0xff), /* wMaxPacketSize: 64 */
(USB_TXBUFSZ >> 8),
0x00, /* bInterval: ignore for Bulk transfer */
};
_USB_LANG_ID_(USB_StringLangDescriptor, LANG_US);
// these descriptors are not used in PL2303 emulator!
_USB_STRING_(USB_StringSerialDescriptor, u"0");
_USB_STRING_(USB_StringManufacturingDescriptor, u"Prolific Technology Inc.");
_USB_STRING_(USB_StringProdDescriptor, u"USB-Serial Controller");
/*
* default handlers
*/
// SET_LINE_CODING
void WEAK linecoding_handler(usb_LineCoding __attribute__((unused)) *lc){
}
// SET_CONTROL_LINE_STATE
void WEAK clstate_handler(uint16_t __attribute__((unused)) val){
}
// SEND_BREAK
void WEAK break_handler(){
}
// handler of vendor requests
void WEAK vendor_handler(config_pack_t *packet){
if(packet->bmRequestType & 0x80){ // read
uint8_t c;
switch(packet->wValue){
case 0x8484:
c = 2;
break;
case 0x0080:
c = 1;
break;
case 0x8686:
c = 0xaa;
break;
default:
c = 0;
}
EP_WriteIRQ(0, &c, 1);
}else{ // write ZLP
EP_WriteIRQ(0, (uint8_t *)0, 0);
}
}
static void wr0(const uint8_t *buf, uint16_t size){
if(setup_packet.wLength < size) size = setup_packet.wLength;
EP_WriteIRQ(0, buf, size);
}
static inline void get_descriptor(){
switch(setup_packet.wValue){
case DEVICE_DESCRIPTOR:
wr0(USB_DeviceDescriptor, sizeof(USB_DeviceDescriptor));
break;
case CONFIGURATION_DESCRIPTOR:
wr0(USB_ConfigDescriptor, sizeof(USB_ConfigDescriptor));
break;
case STRING_LANG_DESCRIPTOR:
wr0((const uint8_t *)&USB_StringLangDescriptor, STRING_LANG_DESCRIPTOR_SIZE_BYTE);
break;
case STRING_MAN_DESCRIPTOR:
wr0((const uint8_t *)&USB_StringManufacturingDescriptor, USB_StringManufacturingDescriptor.bLength);
break;
case STRING_PROD_DESCRIPTOR:
wr0((const uint8_t *)&USB_StringProdDescriptor, USB_StringProdDescriptor.bLength);
break;
case STRING_SN_DESCRIPTOR:
wr0((const uint8_t *)&USB_StringSerialDescriptor, USB_StringSerialDescriptor.bLength);
break;
case DEVICE_QUALIFIER_DESCRIPTOR:
wr0(USB_DeviceQualifierDescriptor, USB_DeviceQualifierDescriptor[0]);
break;
default:
break;
}
}
static uint8_t configuration = 0; // reply for GET_CONFIGURATION (==1 if configured)
static inline void std_d2h_req(){
uint16_t status = 0; // bus powered
switch(setup_packet.bRequest){
case GET_DESCRIPTOR:
get_descriptor();
break;
case GET_STATUS:
EP_WriteIRQ(0, (uint8_t *)&status, 2); // send status: Bus Powered
break;
case GET_CONFIGURATION:
EP_WriteIRQ(0, &configuration, 1);
break;
default:
break;
}
}
static inline void std_h2d_req(){
switch(setup_packet.bRequest){
case SET_ADDRESS:
// new address will be assigned later - after acknowlegement or request to host
USB_Dev.USB_Addr = setup_packet.wValue;
break;
case SET_CONFIGURATION:
// Now device configured
USB_Dev.USB_Status = USB_CONFIGURE_STATE;
configuration = setup_packet.wValue;
break;
default:
break;
}
}
/*
bmRequestType: 76543210
7 direction: 0 - host->device, 1 - device->host
65 type: 0 - standard, 1 - class, 2 - vendor
4..0 getter: 0 - device, 1 - interface, 2 - endpoint, 3 - other
*/
/**
* Endpoint0 (control) handler
* @param ep - endpoint state
* @return data written to EP0R
*/
static uint16_t EP0_Handler(ep_t ep){
uint16_t epstatus = ep.status; // EP0R on input -> return this value after modifications
uint8_t reqtype = setup_packet.bmRequestType & 0x7f;
uint8_t dev2host = (setup_packet.bmRequestType & 0x80) ? 1 : 0;
if ((ep.rx_flag) && (ep.setup_flag)){
switch(reqtype){
case STANDARD_DEVICE_REQUEST_TYPE: // standard device request
if(dev2host){
std_d2h_req();
}else{
std_h2d_req();
// send ZLP
EP_WriteIRQ(0, (uint8_t *)0, 0);
}
epstatus = SET_NAK_RX(epstatus);
epstatus = SET_VALID_TX(epstatus);
break;
case STANDARD_ENDPOINT_REQUEST_TYPE: // standard endpoint request
if(setup_packet.bRequest == CLEAR_FEATURE){
// send ZLP
EP_WriteIRQ(0, (uint8_t *)0, 0);
epstatus = SET_NAK_RX(epstatus);
epstatus = SET_VALID_TX(epstatus);
}
break;
case VENDOR_REQUEST_TYPE:
vendor_handler(&setup_packet);
epstatus = SET_NAK_RX(epstatus);
epstatus = SET_VALID_TX(epstatus);
break;
case CONTROL_REQUEST_TYPE:
switch(setup_packet.bRequest){
case GET_LINE_CODING:
EP_WriteIRQ(0, (uint8_t*)&lineCoding, sizeof(lineCoding));
break;
case SET_LINE_CODING: // omit this for next stage, when data will come
break;
case SET_CONTROL_LINE_STATE:
clstate_handler(setup_packet.wValue);
break;
case SEND_BREAK:
break_handler();
break;
default:
break;
}
if(!dev2host) EP_WriteIRQ(0, (uint8_t *)0, 0); // write acknowledgement
epstatus = SET_VALID_RX(epstatus);
epstatus = SET_VALID_TX(epstatus);
break;
default:
EP_WriteIRQ(0, (uint8_t *)0, 0);
epstatus = SET_NAK_RX(epstatus);
epstatus = SET_VALID_TX(epstatus);
}
}else if (ep.rx_flag){ // got data over EP0 or host acknowlegement
if(ep.rx_cnt){
EP_WriteIRQ(0, (uint8_t *)0, 0);
if(setup_packet.bRequest == SET_LINE_CODING){
linecoding_handler((usb_LineCoding*)ep0databuf);
}
}
// Close transaction
epstatus = CLEAR_DTOG_RX(epstatus);
epstatus = CLEAR_DTOG_TX(epstatus);
// wait for new data from host
epstatus = SET_VALID_RX(epstatus);
epstatus = SET_STALL_TX(epstatus);
} else if (ep.tx_flag){ // package transmitted
// now we can change address after enumeration
if ((USB->DADDR & USB_DADDR_ADD) != USB_Dev.USB_Addr){
USB->DADDR = USB_DADDR_EF | USB_Dev.USB_Addr;
// change state to ADRESSED
USB_Dev.USB_Status = USB_ADRESSED_STATE;
}
// end of transaction
epstatus = CLEAR_DTOG_RX(epstatus);
epstatus = CLEAR_DTOG_TX(epstatus);
epstatus = SET_VALID_RX(epstatus);
epstatus = SET_VALID_TX(epstatus);
}
return epstatus;
}
static uint16_t lastaddr = USB_EP0_BASEADDR;
/**
* Endpoint initialisation
* !!! when working with CAN bus change USB_BTABLE_SIZE to 768 !!!
* @param number - EP num (0...7)
* @param type - EP type (EP_TYPE_BULK, EP_TYPE_CONTROL, EP_TYPE_ISO, EP_TYPE_INTERRUPT)
* @param txsz - transmission buffer size @ USB/CAN buffer
* @param rxsz - reception buffer size @ USB/CAN buffer
* @param uint16_t (*func)(ep_t *ep) - EP handler function
* @return 0 if all OK
*/
int EP_Init(uint8_t number, uint8_t type, uint16_t txsz, uint16_t rxsz, uint16_t (*func)(ep_t ep)){
if(number >= ENDPOINTS_NUM) return 4; // out of configured amount
if(txsz > USB_BTABLE_SIZE || rxsz > USB_BTABLE_SIZE) return 1; // buffer too large
if(lastaddr + txsz + rxsz >= USB_BTABLE_SIZE) return 2; // out of btable
USB->EPnR[number] = (type << 9) | (number & USB_EPnR_EA);
USB->EPnR[number] ^= USB_EPnR_STAT_RX | USB_EPnR_STAT_TX_1;
if(rxsz & 1 || rxsz > 992) return 3; // wrong rx buffer size
uint16_t countrx = 0;
if(rxsz < 64) countrx = rxsz / 2;
else{
if(rxsz & 0x1f) return 3; // should be multiple of 32
countrx = 31 + rxsz / 32;
}
USB_BTABLE->EP[number].USB_ADDR_TX = lastaddr;
endpoints[number].tx_buf = (uint16_t *)(USB_BTABLE_BASE + lastaddr);
lastaddr += txsz;
USB_BTABLE->EP[number].USB_COUNT_TX = 0;
USB_BTABLE->EP[number].USB_ADDR_RX = lastaddr;
endpoints[number].rx_buf = (uint8_t *)(USB_BTABLE_BASE + lastaddr);
lastaddr += rxsz;
// buffer size: Table127 of RM
USB_BTABLE->EP[number].USB_COUNT_RX = countrx << 10;
endpoints[number].func = func;
return 0;
}
// standard IRQ handler
void usb_isr(){
if (USB->ISTR & USB_ISTR_RESET){
// Reinit registers
USB->CNTR = USB_CNTR_RESETM | USB_CNTR_CTRM;
USB->ISTR = 0;
// Endpoint 0 - CONTROL
// ON USB LS size of EP0 may be 8 bytes, but on FS it should be 64 bytes!
lastaddr = USB_EP0_BASEADDR; // roll back to beginning of buffer
EP_Init(0, EP_TYPE_CONTROL, USB_EP0_BUFSZ, USB_EP0_BUFSZ, EP0_Handler);
// clear address, leave only enable bit
USB->DADDR = USB_DADDR_EF;
// state is default - wait for enumeration
USB_Dev.USB_Status = USB_DEFAULT_STATE;
}
if(USB->ISTR & USB_ISTR_CTR){
// EP number
uint8_t n = USB->ISTR & USB_ISTR_EPID;
// copy status register
uint16_t epstatus = USB->EPnR[n];
// Calculate flags
endpoints[n].rx_flag = (epstatus & USB_EPnR_CTR_RX) ? 1 : 0;
endpoints[n].setup_flag = (epstatus & USB_EPnR_SETUP) ? 1 : 0;
endpoints[n].tx_flag = (epstatus & USB_EPnR_CTR_TX) ? 1 : 0;
// copy received bytes amount
endpoints[n].rx_cnt = USB_BTABLE->EP[n].USB_COUNT_RX & 0x3FF; // low 10 bits is counter
// check direction
if(USB->ISTR & USB_ISTR_DIR){ // OUT interrupt - receive data, CTR_RX==1 (if CTR_TX == 1 - two pending transactions: receive following by transmit)
if(n == 0){ // control endpoint
if(epstatus & USB_EPnR_SETUP){ // setup packet -> copy data to conf_pack
memcpy(&setup_packet, endpoints[0].rx_buf, sizeof(setup_packet));
ep0dbuflen = 0;
// interrupt handler will be called later
}else if(epstatus & USB_EPnR_CTR_RX){ // data packet -> push received data to ep0databuf
ep0dbuflen = endpoints[0].rx_cnt;
memcpy(ep0databuf, endpoints[0].rx_buf, ep0dbuflen);
}
}
}else{ // IN interrupt - transmit data, only CTR_TX == 1
// enumeration end could be here (if EP0)
}
// prepare status field for EP handler
endpoints[n].status = epstatus;
// call EP handler (even if it will change EPnR, it should return new status)
epstatus = endpoints[n].func(endpoints[n]);
// keep DTOG state
epstatus = KEEP_DTOG_TX(epstatus);
epstatus = KEEP_DTOG_RX(epstatus);
// clear all RX/TX flags
epstatus = CLEAR_CTR_RX(epstatus);
epstatus = CLEAR_CTR_TX(epstatus);
// refresh EPnR
USB->EPnR[n] = epstatus;
}
}
/**
* Write data to EP buffer (called from IRQ handler)
* @param number - EP number
* @param *buf - array with data
* @param size - its size
*/
void EP_WriteIRQ(uint8_t number, const uint8_t *buf, uint16_t size){
uint8_t i;
if(size > USB_TXBUFSZ) size = USB_TXBUFSZ;
uint16_t N2 = (size + 1) >> 1;
// the buffer is 16-bit, so we should copy data as it would be uint16_t
uint16_t *buf16 = (uint16_t *)buf;
for (i = 0; i < N2; i++){
endpoints[number].tx_buf[i] = buf16[i];
}
USB_BTABLE->EP[number].USB_COUNT_TX = size;
}
/**
* Write data to EP buffer (called outside IRQ handler)
* @param number - EP number
* @param *buf - array with data
* @param size - its size
*/
void EP_Write(uint8_t number, const uint8_t *buf, uint16_t size){
uint16_t status = USB->EPnR[number];
EP_WriteIRQ(number, buf, size);
status = SET_NAK_RX(status);
status = SET_VALID_TX(status);
status = KEEP_DTOG_TX(status);
status = KEEP_DTOG_RX(status);
USB->EPnR[number] = status;
}
/*
* Copy data from EP buffer into user buffer area
* @param *buf - user array for data
* @return amount of data read
*/
int EP_Read(uint8_t number, uint8_t *buf){
int n = endpoints[number].rx_cnt;
if(n){
for(int i = 0; i < n; ++i)
buf[i] = endpoints[number].rx_buf[i];
}
return n;
}
// USB status
uint8_t USB_GetState(){
return USB_Dev.USB_Status;
}

View File

@ -0,0 +1,202 @@
/*
* geany_encoding=koi8-r
* usb_lib.h
*
* Copyright 2018 Edward V. Emelianov <eddy@sao.ru, edward.emelianoff@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*
*/
#pragma once
#ifndef __USB_LIB_H__
#define __USB_LIB_H__
#include <wchar.h>
#include "usb_defs.h"
#define EP0DATABUF_SIZE (64)
// Max EP amount (EP0 + other used)
#define ENDPOINTS_NUM 4
// bmRequestType & 0x7f
#define STANDARD_DEVICE_REQUEST_TYPE 0
#define STANDARD_ENDPOINT_REQUEST_TYPE 2
#define VENDOR_REQUEST_TYPE 0x40
#define CONTROL_REQUEST_TYPE 0x21
// bRequest, standard; for bmRequestType == 0x80
#define GET_STATUS 0x00
#define GET_DESCRIPTOR 0x06
#define GET_CONFIGURATION 0x08
// for bmRequestType == 0
#define CLEAR_FEATURE 0x01
#define SET_FEATURE 0x03 // unused
#define SET_ADDRESS 0x05
#define SET_DESCRIPTOR 0x07 // unused
#define SET_CONFIGURATION 0x09
// for bmRequestType == 0x81, 1 or 0xB2
#define GET_INTERFACE 0x0A // unused
#define SET_INTERFACE 0x0B // unused
#define SYNC_FRAME 0x0C // unused
#define VENDOR_REQUEST 0x01 // unused
// Class-Specific Control Requests
#define SEND_ENCAPSULATED_COMMAND 0x00 // unused
#define GET_ENCAPSULATED_RESPONSE 0x01 // unused
#define SET_COMM_FEATURE 0x02 // unused
#define GET_COMM_FEATURE 0x03 // unused
#define CLEAR_COMM_FEATURE 0x04 // unused
#define SET_LINE_CODING 0x20
#define GET_LINE_CODING 0x21
#define SET_CONTROL_LINE_STATE 0x22
#define SEND_BREAK 0x23
// control line states
#define CONTROL_DTR 0x01
#define CONTROL_RTS 0x02
// wValue
#define DEVICE_DESCRIPTOR 0x100
#define CONFIGURATION_DESCRIPTOR 0x200
#define STRING_LANG_DESCRIPTOR 0x300
#define STRING_MAN_DESCRIPTOR 0x301
#define STRING_PROD_DESCRIPTOR 0x302
#define STRING_SN_DESCRIPTOR 0x303
#define DEVICE_QUALIFIER_DESCRIPTOR 0x600
// EPnR bits manipulation
#define CLEAR_DTOG_RX(R) (R & USB_EPnR_DTOG_RX) ? R : (R & (~USB_EPnR_DTOG_RX))
#define SET_DTOG_RX(R) (R & USB_EPnR_DTOG_RX) ? (R & (~USB_EPnR_DTOG_RX)) : R
#define TOGGLE_DTOG_RX(R) (R | USB_EPnR_DTOG_RX)
#define KEEP_DTOG_RX(R) (R & (~USB_EPnR_DTOG_RX))
#define CLEAR_DTOG_TX(R) (R & USB_EPnR_DTOG_TX) ? R : (R & (~USB_EPnR_DTOG_TX))
#define SET_DTOG_TX(R) (R & USB_EPnR_DTOG_TX) ? (R & (~USB_EPnR_DTOG_TX)) : R
#define TOGGLE_DTOG_TX(R) (R | USB_EPnR_DTOG_TX)
#define KEEP_DTOG_TX(R) (R & (~USB_EPnR_DTOG_TX))
#define SET_VALID_RX(R) ((R & USB_EPnR_STAT_RX) ^ USB_EPnR_STAT_RX) | (R & (~USB_EPnR_STAT_RX))
#define SET_NAK_RX(R) ((R & USB_EPnR_STAT_RX) ^ USB_EPnR_STAT_RX_1) | (R & (~USB_EPnR_STAT_RX))
#define SET_STALL_RX(R) ((R & USB_EPnR_STAT_RX) ^ USB_EPnR_STAT_RX_0) | (R & (~USB_EPnR_STAT_RX))
#define KEEP_STAT_RX(R) (R & (~USB_EPnR_STAT_RX))
#define SET_VALID_TX(R) ((R & USB_EPnR_STAT_TX) ^ USB_EPnR_STAT_TX) | (R & (~USB_EPnR_STAT_TX))
#define SET_NAK_TX(R) ((R & USB_EPnR_STAT_TX) ^ USB_EPnR_STAT_TX_1) | (R & (~USB_EPnR_STAT_TX))
#define SET_STALL_TX(R) ((R & USB_EPnR_STAT_TX) ^ USB_EPnR_STAT_TX_0) | (R & (~USB_EPnR_STAT_TX))
#define KEEP_STAT_TX(R) (R & (~USB_EPnR_STAT_TX))
#define CLEAR_CTR_RX(R) (R & (~USB_EPnR_CTR_RX))
#define CLEAR_CTR_TX(R) (R & (~USB_EPnR_CTR_TX))
#define CLEAR_CTR_RX_TX(R) (R & (~(USB_EPnR_CTR_TX | USB_EPnR_CTR_RX)))
// USB state: uninitialized, addressed, ready for use
#define USB_DEFAULT_STATE 0
#define USB_ADRESSED_STATE 1
#define USB_CONFIGURE_STATE 2
// EP types
#define EP_TYPE_BULK 0x00
#define EP_TYPE_CONTROL 0x01
#define EP_TYPE_ISO 0x02
#define EP_TYPE_INTERRUPT 0x03
#define LANG_US (uint16_t)0x0409
#define _USB_STRING_(name, str) \
static const struct name \
{ \
uint8_t bLength; \
uint8_t bDescriptorType; \
uint16_t bString[(sizeof(str) - 2) / 2]; \
\
} \
name = {sizeof(name), 0x03, str}
#define _USB_LANG_ID_(name, lng_id) \
\
static const struct name \
{ \
uint8_t bLength; \
uint8_t bDescriptorType; \
uint16_t bString; \
\
} \
name = {0x04, 0x03, lng_id}
#define STRING_LANG_DESCRIPTOR_SIZE_BYTE (4)
// EP0 configuration packet
typedef struct {
uint8_t bmRequestType;
uint8_t bRequest;
uint16_t wValue;
uint16_t wIndex;
uint16_t wLength;
} config_pack_t;
// endpoints state
typedef struct __ep_t{
uint16_t *tx_buf; // transmission buffer address
uint8_t *rx_buf; // reception buffer address
uint16_t (*func)(); // endpoint action function
uint16_t status; // status flags
unsigned rx_cnt : 10; // received data counter
unsigned tx_flag : 1; // transmission flag
unsigned rx_flag : 1; // reception flag
unsigned setup_flag : 1; // this is setup packet (only for EP0)
} ep_t;
// USB status & its address
typedef struct {
uint8_t USB_Status;
uint16_t USB_Addr;
}usb_dev_t;
typedef struct {
uint32_t dwDTERate;
uint8_t bCharFormat;
#define USB_CDC_1_STOP_BITS 0
#define USB_CDC_1_5_STOP_BITS 1
#define USB_CDC_2_STOP_BITS 2
uint8_t bParityType;
#define USB_CDC_NO_PARITY 0
#define USB_CDC_ODD_PARITY 1
#define USB_CDC_EVEN_PARITY 2
#define USB_CDC_MARK_PARITY 3
#define USB_CDC_SPACE_PARITY 4
uint8_t bDataBits;
} __attribute__ ((packed)) usb_LineCoding;
typedef struct {
uint8_t bmRequestType;
uint8_t bNotificationType;
uint16_t wValue;
uint16_t wIndex;
uint16_t wLength;
} __attribute__ ((packed)) usb_cdc_notification;
extern ep_t endpoints[];
void USB_Init();
uint8_t USB_GetState();
int EP_Init(uint8_t number, uint8_t type, uint16_t txsz, uint16_t rxsz, uint16_t (*func)(ep_t ep));
void EP_WriteIRQ(uint8_t number, const uint8_t *buf, uint16_t size);
void EP_Write(uint8_t number, const uint8_t *buf, uint16_t size);
int EP_Read(uint8_t number, uint8_t *buf);
usb_LineCoding getLineCoding();
void WEAK linecoding_handler(usb_LineCoding *lc);
void WEAK clstate_handler(uint16_t val);
void WEAK break_handler();
void WEAK vendor_handler(config_pack_t *packet);
#endif // __USB_LIB_H__

View File

@ -179,6 +179,16 @@ IDR - input, ODR - output (or pullups management),
#define CRH(pin, cnfmode) ((cnfmode) << ((pin-8)*4)) #define CRH(pin, cnfmode) ((cnfmode) << ((pin-8)*4))
/************************* ADC *************************/
/* inner termometer calibration values
* Temp = (V25 - Vsense)/Avg_Slope + 25
*/
#define VREFINT_CAL_ADDR ((uint16_t*) ((uint32_t) 0x1FFFF7BA))
/************************* IWDG *************************/
#define IWDG_REFRESH (uint32_t)(0x0000AAAA)
#define IWDG_WRITE_ACCESS (uint32_t)(0x00005555)
#define IWDG_START (uint32_t)(0x0000CCCC)
#if 0 #if 0
@ -190,7 +200,6 @@ IDR - input, ODR - output (or pullups management),
#define TEMP110_CAL_ADDR ((uint16_t*) ((uint32_t) 0x1FFFF7C2)) #define TEMP110_CAL_ADDR ((uint16_t*) ((uint32_t) 0x1FFFF7C2))
#define TEMP30_CAL_ADDR ((uint16_t*) ((uint32_t) 0x1FFFF7B8)) #define TEMP30_CAL_ADDR ((uint16_t*) ((uint32_t) 0x1FFFF7B8))
// VDDA_Actual = 3.3V * VREFINT_CAL / average vref value // VDDA_Actual = 3.3V * VREFINT_CAL / average vref value
#define VREFINT_CAL_ADDR ((uint16_t*) ((uint32_t) 0x1FFFF7BA))
#define VDD_CALIB ((uint16_t) (330)) #define VDD_CALIB ((uint16_t) (330))
#define VDD_APPLI ((uint16_t) (300)) #define VDD_APPLI ((uint16_t) (300))
@ -200,11 +209,6 @@ IDR - input, ODR - output (or pullups management),
// set address/character match value // set address/character match value
#define USART_CR2_ADD_VAL(x) ((x) << USART_CR2_ADD_SHIFT) #define USART_CR2_ADD_VAL(x) ((x) << USART_CR2_ADD_SHIFT)
/************************* IWDG *************************/
#define IWDG_REFRESH (uint32_t)(0x0000AAAA)
#define IWDG_WRITE_ACCESS (uint32_t)(0x00005555)
#define IWDG_START (uint32_t)(0x0000CCCC)
//#define do{}while(0) //#define do{}while(0)