From 20f4205459e641943d8c1c204f6e7360a22f704b Mon Sep 17 00:00:00 2001 From: Edward Emelianov Date: Sun, 27 Jun 2021 20:26:49 +0300 Subject: [PATCH] starting development of F0 for new devboard --- F0-nolib/CANbus_stepper/src/canstepper.bin | Bin 18204 -> 16972 bytes F0-nolib/CANbus_stepper/src/spi.c | 2 +- F0-nolib/F0_testbrd/Makefile | 1 - F0-nolib/F0_testbrd/Readme.md | 3 +- F0-nolib/F0_testbrd/adc.c | 23 +- F0-nolib/F0_testbrd/adc.h | 3 +- F0-nolib/F0_testbrd/hardware.c | 87 +++-- F0-nolib/F0_testbrd/hardware.h | 41 +-- F0-nolib/F0_testbrd/main.c | 167 +--------- F0-nolib/F0_testbrd/pl2303.bin | Bin 7312 -> 9152 bytes F0-nolib/F0_testbrd/proto.c | 355 +++++++++++++++++++++ F0-nolib/F0_testbrd/proto.h | 34 ++ F0-nolib/F0_testbrd/usart.c | 330 ++++++++++--------- F0-nolib/F0_testbrd/usart.h | 29 +- F0-nolib/F0_testbrd/usb.c | 2 - F0-nolib/F0_testbrd/usb_lib.c | 1 - F0_F1_F3-LQFP48_testboard/stm32 | 30 -- F0_F1_F3-LQFP48_testboard/stm32.bom | 103 ++---- 18 files changed, 700 insertions(+), 511 deletions(-) create mode 100644 F0-nolib/F0_testbrd/proto.c create mode 100644 F0-nolib/F0_testbrd/proto.h delete mode 100644 F0_F1_F3-LQFP48_testboard/stm32 diff --git a/F0-nolib/CANbus_stepper/src/canstepper.bin b/F0-nolib/CANbus_stepper/src/canstepper.bin index 0a5b9491e82dfb210ada178ca0fd3350fb13c647..7ddd110ef6eda842a848fb7742edf1f54be17917 100755 GIT binary patch delta 4706 zcmcJSe{d7moxs0uSF&UaY}pbZOSW09Y-218{)PEr1F~c)a7zB`PIwXrZ+a^QuRtun~-K_LLyt1 zwf9})TuB<*{&A<7&wk(cz3;yLzVG|KA3F6<xxF_ZQ|`B(y!-n3BW0ln|XLk0Z7qB7Ag ziqeX#uRri`W*zSc4;ns_4W)!plV8iM;nxHzci4sV;Ue!1xzZ2H^YhyCx%snU$OXlm zS%up7HI34AW2O}Kf1W=dc4QZMNK@9D@+l|(EX4PMa(sRzw)INC&uaXe4>RWy1^#IS zln3UoC-PAS=ig13QQkNIp9wgC8Bh(LbLRj&bznSzJc{%q3~~VxMG?SEc~n)MZ$e#0 zUPfN5lO8ubO{Hsxmm33w?2v-lmS|Hw7?qJHUQm<$^STm7_8rzAChih>J>L+p3sAK} z*7uMqL58ZmGF9b~>8jjuHF-MyHSQo+9C>2Mk+UnZhVP5mW3)5GsmULy^b5-9YTnTU z?pe8lw}n87rnO+?riETm2GeC&Hl~Hcpgf#*MNy&BP-T*#+26nbtLpuYeP(dg@LTw)KcK#QsGYJmT5y%f` zXSG}=&h~&DBHr}492(17f4QEK1#|eCjrh#2{9wKFBu7^1%9*mGoR9ZK1N|sYw4CC$ z@y(pT8HN0qQ=AUv;p@|(T<<}AF7>A6yE&?MTA=Drw0@LV)?Iy!f>vaMrZC7Y;E@np7O%* zYF}ZnD_9t=LCI{@EYtFIs0LjzJKqh}c!$Re!_Q-z=zJZHaa}Esdnd=i6;2T5R01O% zWwbDBVF!j*XTH3qFS6k2be)LOi3RD_EnL)Ts#V!#q13MJ(ge1&=~ zBRyEaQvaTkjuvdpKaufqO@&3mZxT*i#zfgHO%{AB?@ESjsjgWaVIapzlpRvovWx25 zHvEdEfe>~06Kjx=1yyy3;$xCyYB$Jk8dnHvqFQx4z(Vep&TpQywU$rqj zi~b%!N+@9ZHe!|`_1KnC)o2TrZ*IU70^4q&1ReMlv^|CO+K%S&=0QKkUjv=} zJCsi%`;i04A!IjFiqs=Zwn(2k){>8}50t>~IFXjUz9j9@`=f6gg?yVUk`c>WgOK3eOJ}diC<%A(L;HKv)XrNn0ZTlxF~6 z)?te3-SiY4*a!Vxk?p{w6U7)Rs|Sn}PX`=5+8zfB4F_3rj@!nX1Q-D)zK5!q&bf(&%)nO3}^8GG-Aqg{_j zz5FCz)gED=kl;u^#k4Z(3ZA*&slbY;DIEVEB44lAt{R0xyFVl5AFGd!TqZ~ zr^vjnj|HI;-(wl)g#JVj+*`&)wqoHkndJMbn)IuSeFjCABcp5tn7M==NBmS`vE%NE#7Z>yhgpjGLxQkY-qtqI-RIg?d&|Mw-FpE)IuH~# z58y|#wT}nK5?Ir%b1gd7J+v?po!HlF2`v{e_58S3_=}^Of*Y;27PX{NX;r;}Nil<5 zK;A;uwM9m9dhooe)X9d;gdvqM9T^38hg{jthMFc%ztbU7N4M40QM9SpuF=mWl7oiHDS?KQFiOES{p`Kb`uObJj~G`=AKE^DZv<5}+Gd+u-1 zj$6WBCC7r=G7(vmP_wX<`dsFP90yl`tBcTrB{Gqy=zvu(M!5&Ls?e&AvnZ2$wzsSk zC^swTPt)#8vd%p<&hl>@bi@X2&cNVMK}_;GCTW+Sqa$x%b`ke$Ijp!!vvOL?!1x2?v9jTk%Ae{=9&H9Ajmg=E@-%W80WY2qD0epxf4a7T zP&IC8ZS_0Wn`#EP9rzI9ek~giop-pT<|w_D!oPkR*9>5MA5oB-$P97;Nh8vKuY!qI~Ije04w{%Evi=RF%Y)~<)<`b~HU0qox4tF5W4#@)^c zr8ayOx%~e}^snyx(*J=I7qO3l&-D|hpS}xc4nKjSV_nzGlRRlp@tg6VigTH%srg9F|JCmq?5BF1Pi60Ix-@ AWdHyG delta 5903 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 = (GPIOA->MODER & ~(GPIO_MODER_MODER5 | GPIO_MODER_MODER6 | GPIO_MODER_MODER7)) | (GPIO_MODER_MODER5_AF | GPIO_MODER_MODER6_AF | GPIO_MODER_MODER7_AF); /* (1) */ - GPIOA->AFR[0] = (GPIOA->AFR[0] & (GPIO_AFRL_AFRL5 | GPIO_AFRL_AFRL6 | GPIO_AFRL_AFRL7)); /* (2) */ + GPIOA->AFR[0] = (GPIOA->AFR[0] & ~(GPIO_AFRL_AFRL5 | GPIO_AFRL_AFRL6 | GPIO_AFRL_AFRL7)); /* (2) */ // Configure DMA SPI /* Enable the peripheral clock DMA11 */ RCC->AHBENR |= RCC_AHBENR_DMA1EN; diff --git a/F0-nolib/F0_testbrd/Makefile b/F0-nolib/F0_testbrd/Makefile index ccda417..0e07fa0 100644 --- a/F0-nolib/F0_testbrd/Makefile +++ b/F0-nolib/F0_testbrd/Makefile @@ -7,7 +7,6 @@ FAMILY = F0 #MCU = F042x6 MCU = F072xB # hardware definitions -DEFS += -DUSARTNUM=1 #DEFS += -DCHECK_TMOUT #DEFS += -DEBUG # change this linking script depending on particular MCU model diff --git a/F0-nolib/F0_testbrd/Readme.md b/F0-nolib/F0_testbrd/Readme.md index 50ad9db..91f95ee 100644 --- a/F0-nolib/F0_testbrd/Readme.md +++ b/F0-nolib/F0_testbrd/Readme.md @@ -1 +1,2 @@ -Simple test for STM32F0x2, blinking PA0, PWM for TIM14CH1, two user buttons (PA14 and PA15) and USB (PL2303 emulator) <> USART1 echo. +Simple test for STM32F0x2, PWM for all 4 channels of TIM3, USB (PL2303 emulator); USART1/2/3, SPI1/2, +I2C1 tests, ADC1 IN0/1 connected to variable resistor. diff --git a/F0-nolib/F0_testbrd/adc.c b/F0-nolib/F0_testbrd/adc.c index 65880fc..fa786bb 100644 --- a/F0-nolib/F0_testbrd/adc.c +++ b/F0-nolib/F0_testbrd/adc.c @@ -21,9 +21,12 @@ /** * @brief ADC_array - array for ADC channels with median filtering: * 0 - Rvar - * 1 - internal Tsens - * 2 - Vref + * 1 - Rvar/2 + * 2 - internal Tsens + * 3 - Vref */ +#define CHTSENS (2) +#define CHVREF (3) uint16_t ADC_array[NUMBER_OF_ADC_CHANNELS*9]; /** @@ -51,12 +54,20 @@ uint16_t getADCval(int nch){ #undef PIX_SWAP } +// get voltage @input nch (1/100V) +uint32_t getADCvoltate(int nch){ + uint32_t v = getADCval(nch); + v *= getVdd(); + v /= 0xfff; // 12bit ADC + return v; +} + // return MCU temperature (degrees of celsius * 10) int32_t getMCUtemp(){ - getVdd(); +// getVdd(); // make correction on Vdd value // int32_t temperature = (int32_t)ADC_array[4] * VddValue / 330; - int32_t ADval = getADCval(1); + int32_t ADval = getADCval(CHTSENS); int32_t temperature = (int32_t) *TEMP30_CAL_ADDR - ADval; temperature *= (int32_t)(1100 - 300); temperature /= (int32_t)(*TEMP30_CAL_ADDR - *TEMP110_CAL_ADDR); @@ -64,9 +75,9 @@ int32_t getMCUtemp(){ return(temperature); } -// return Vdd * 100 (V) +// return Vdd (1/100V) uint32_t getVdd(){ uint32_t vdd = ((uint32_t) *VREFINT_CAL_ADDR) * (uint32_t)330; // 3.3V - vdd /= getADCval(2); + vdd /= getADCval(CHVREF); return vdd; } diff --git a/F0-nolib/F0_testbrd/adc.h b/F0-nolib/F0_testbrd/adc.h index fe26926..d797087 100644 --- a/F0-nolib/F0_testbrd/adc.h +++ b/F0-nolib/F0_testbrd/adc.h @@ -19,11 +19,12 @@ #define ADC_H #include "stm32f0.h" -#define NUMBER_OF_ADC_CHANNELS (3) +#define NUMBER_OF_ADC_CHANNELS (4) extern uint16_t ADC_array[]; int32_t getMCUtemp(); uint32_t getVdd(); uint16_t getADCval(int nch); +uint32_t getADCvoltate(int nch); #endif // ADC_H diff --git a/F0-nolib/F0_testbrd/hardware.c b/F0-nolib/F0_testbrd/hardware.c index 716eb3c..021ed31 100644 --- a/F0-nolib/F0_testbrd/hardware.c +++ b/F0-nolib/F0_testbrd/hardware.c @@ -23,28 +23,49 @@ #include "adc.h" #include "hardware.h" -#include "usart.h" + +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) */ +} 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)) ; + // Set LEDS (PA6-8, PB0/1) as Oun & AF (PWM) + GPIOA->MODER = (GPIOA->MODER & ~(GPIO_MODER_MODER6 | GPIO_MODER_MODER7 | GPIO_MODER_MODER8)) | + GPIO_MODER_MODER6_AF | GPIO_MODER_MODER7_AF | GPIO_MODER_MODER8_AF; + GPIOB->MODER = (GPIOB->MODER & ~(GPIO_MODER_MODER0 | GPIO_MODER_MODER1)) | + GPIO_MODER_MODER0_AF | GPIO_MODER_MODER1_AF; + // alternate functions: PA6-8: TIM3CH1,2 and TIM1_CH1 (AF1, AF1, AF2) + // PB0-1: TIM3CH3,4 (AF1, AF1) + GPIOA->AFR[0] = (GPIOA->AFR[0] & ~(GPIO_AFRL_AFRL6 | GPIO_AFRL_AFRL7)) | + (1 << (6 * 4)) | (1 << (7 * 4)); + GPIOA->AFR[1] = (GPIOA->AFR[1] & ~(GPIO_AFRH_AFRH0)) | + (2 << (0 * 4)); + GPIOB->AFR[0] = (GPIOB->AFR[0] & ~(GPIO_AFRL_AFRL0 | GPIO_AFRL_AFRL1)) | + (1 << (0 * 4)) | (1 << (1 * 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 */ @@ -72,12 +93,12 @@ static inline void adc_setup(){ // 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 */ + /* (3) Select CHSEL0,1 - 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->CHSELR = ADC_CHSELR_CHSEL0 | ADC_CHSELR_CHSEL1 | 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 @@ -100,16 +121,32 @@ static inline void adc_setup(){ } static inline void pwm_setup(){ - RCC->APB1ENR |= RCC_APB1ENR_TIM14EN; // enable clocking for tim14 + // enable clocking for tim1 & tim3 + RCC->APB1ENR |= RCC_APB1ENR_TIM3EN; + RCC->APB2ENR |= RCC_APB2ENR_TIM1EN; // 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 + TIM1->CCMR1 = TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_0; + TIM3->CCMR1 = TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_0 | + TIM_CCMR1_OC2M_2 | TIM_CCMR1_OC2M_1 | TIM_CCMR1_OC2M_0; + TIM3->CCMR2 = TIM_CCMR2_OC3M_2 | TIM_CCMR2_OC3M_1 | TIM_CCMR2_OC3M_0 | + TIM_CCMR2_OC4M_2 | TIM_CCMR2_OC4M_1 | TIM_CCMR2_OC4M_0; + // frequency - 8MHz for 31kHz PWM + TIM1->PSC = 5; + TIM3->PSC = 5; // 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 + TIM1->ARR = 254; + TIM3->ARR = 254; + TIM1->CCR1 = 127; + TIM3->CCR1 = 63; TIM3->CCR2 = 127; TIM3->CCR3 = 191; TIM3->CCR4 = 250; + // enable main output + TIM1->BDTR |= TIM_BDTR_MOE; + TIM3->BDTR |= TIM_BDTR_MOE; + // enable PWM outputs + TIM1->CCER = TIM_CCER_CC1E; + TIM3->CCER = TIM_CCER_CC1E | TIM_CCER_CC2E | TIM_CCER_CC3E | TIM_CCER_CC4E; + // start timers + TIM1->CR1 |= TIM_CR1_CEN; + TIM3->CR1 |= TIM_CR1_CEN; } void hw_setup(){ diff --git a/F0-nolib/F0_testbrd/hardware.h b/F0-nolib/F0_testbrd/hardware.h index 09b8b45..5c37479 100644 --- a/F0-nolib/F0_testbrd/hardware.h +++ b/F0-nolib/F0_testbrd/hardware.h @@ -30,42 +30,17 @@ #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 +// PWM LEDS +#define SET_LED_PWM3(ch, N) do{TIM3->CCR ## ch = (uint32_t)N;}while(0) +#define GET_LED_PWM3(ch) (uint8_t)(TIM3->CCR ## ch) +#define SET_LED_PWM1(N) do{TIM1->CCR1 = (uint32_t)N;}while(0) +#define GET_LED_PWM1() (uint8_t)(TIM1->CCR1) -// 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 +// USB pullup (not used in STM32F0x2!) - PA15 #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) +#define USBPU_pin (1<<15) +void iwdg_setup(); void hw_setup(); #endif // __HARDWARE_H__ diff --git a/F0-nolib/F0_testbrd/main.c b/F0-nolib/F0_testbrd/main.c index 2d862ae..ca228e1 100644 --- a/F0-nolib/F0_testbrd/main.c +++ b/F0-nolib/F0_testbrd/main.c @@ -22,6 +22,7 @@ #include "adc.h" #include "hardware.h" #include "usart.h" +#include "proto.h" #include "usb.h" #include "usb_lib.h" @@ -32,138 +33,13 @@ 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) */ -} - -#define USND(str) do{USB_send((uint8_t*)str, sizeof(str)-1);}while(0) -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': - USND("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': - USND("Soft reset\n"); - SEND("Soft reset\n"); - NVIC_SystemReset(); - break; - case 'S': - USND("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': - USND("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((uint8_t*)curptr); - curptr[x] = 0; - if(!x) return NULL; - 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; + uint32_t lastT = 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(); @@ -172,49 +48,30 @@ int main(void){ 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; + char *txt; if((txt = get_USB())){ - ans = parse_cmd(txt); - SEND("Received data over USB:\n"); - SEND(txt); - newline(); + const char *ans = parse_cmd(txt); if(ans){ - uint16_t l = 0; char *p = ans; + uint16_t l = 0; const char *p = ans; while(*p++) l++; USB_send((uint8_t*)ans, l); if(ans[l-1] != '\n') USND("\n"); } } - 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(); + for(int n = 1; n <= USARTNUM; ++n){ + if(usartrx(n)){ // usart1 received data, store in in buffer + int r = usart_getline(n, &txt); + if(r){ + txt[r] = 0; + USND("Got string over USART"); USB_sendstr(u2str(n)); + USND(":\n"); USB_sendstr(txt); } } } - // check buttons - each 50ms - if(Tms - lastB > 49){ - 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; } diff --git a/F0-nolib/F0_testbrd/pl2303.bin b/F0-nolib/F0_testbrd/pl2303.bin index 46628c0cf4dc5d5c160d83be680dad737f367bae..72d91b76ad30b05a2d0d19e4160e8a3c8d203a90 100755 GIT binary patch delta 5149 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 UBexF=9zOt(+rR<5O(h!mKcL<}r2qf` delta 3324 zcmb_e4Qx}_6+ZX*Cyq_QKO}QrvgFxL^Mm&pr1}HVoZo1{Rp@1z>1KYD79=DUN|UfG_@3`M28Jld8d2 zQMKu-ZT>UHN-*p+{xitSwi9pCM1SJC9IFCg%t^v1*~gVUzG%=y55uJWNhBT5lH$R4 zX_AS|t??)x^TcaerR*Y79&b+4gA^mdsC^eHDN?e#lx`rv0Li>NYo2%mZMN~PfrlcV zq|p}&4>>REEMl{tlpENlM&h#wX2&V!x$uc_Iwnr)@=1O^@udYzFXuO~amTw9nsjO$ zTLKm#5xG^P)L48Y;ZPstaQZ@B4+JzbWYftpSVg6ReZ-qf5oaAgA{xC^YD7HY8xi8p zdwHuKHNJ$f;Y-#dB2?$5*YTbJVGyHkbPU|m!y0p}nm|6_TbeV*qy2&F!kTdSM ztg}V(DHHpUm#=sDJ+;0^ZIQV1GO@8CZ(BW%`(Kqy{O4tb(Xb>|*Vfgxl;`I8v$s{X zcQhO3Uy^N2rlla!r6619F8poVvn%)&fhj?iZpo9}kR1;gu0pB^3^!>oEFh(jo+$>y z4D!>+0axl8&c{{xQ<%}hoQ?|EL{e+C3DJg0PCx^xmFhN{la?k%gv_%G(hdFnd(5a` ziPVim9GT<|?m@1F+sX~`Gf7$;@*91$5E7q0N3kJ+7LWTWmPY=}5)X;Tkgs4u!c^}M zd{dot-=M1R0%t-9^&Q1>emY>Tv7rA`(zJFRc~mm#ied)>{d~W_P0;k_>x-#kqsgb~ z1eYXeYHfm&{df^FiP^n=$n2c$>Kz5RdVc2Hd`IszO5-zeS4W^jyS;a)(&TIFgv^I? zO14@7*Dx36p(4Qve7Jc8Wkom2@mz?b1-Cfv)m^#ibc@RR(PGJKid~O84@Y)TCasMn z&Z9n??^ofqxE_~ska>Jw$!<`zrJAAgl<$zy{Xl9PCSsY@3`1u5EM&M@!Z;6gl}ysG zsyp?Toz#X(t%r`_Y0ahiQX;8k;+!X=f81qsYf{8fkKXir8&@oXdsW)Yxy4aBR^uMS z6x`y*$S_wIQLAQSV0+*DW1wAo72K!Ou==HxQd`85`?hzzfYoTfrG>Q!bSbB%@gAnB znT6GFq;JE1kkXui%(rq-_4^dKGznX~W>`&KlUB0xi%|8O6l8vhKHte*kiku*V{5Vc z4#>)CNbi>w7lx_X-qkA;SBIBK;CN9k#84wSPA)+H<6MKZPQNDh6jqj2?SLL&)k1pZ z6@c@o%VG7Yl{t*^X(R(y9Juq+c>$|P33&mVkjLA_Xal%xf+hfrO~}bN(Z3zBRJywp#F z9hAT1RI5I4#lE{eI-z7=S8Bxsd@kSdSABEI*d?xki(?N0cSWjzk5`P~j%wj~&c@rC zhq*2;z9j+HZLh*zGd~ORC1+c^IOb3XHE$2LccIU+6xpz4Ykul%aNPSDZp#l99{r!^ z5+KXVem%sEaJdOJph5uDq}8D2q!F9eX+_CK6>|*#vmw{CjutB$FESSPl=Gx!>0I`f zH^#xj4mx)LcJ$7;%Mq9+Cn6@_Nrx0Jr8@;r)FZe_vUvIvv)SdI+pWvF9Kj! zXYNyh9J3X&h9k2^|4fDf-raSb^%<+T5~d~F!80r zk)Vk$5={Kp1)n!q4=zTC!;`I_$ZC*QT*3vc12b~9;O-QgT6oc<4xTy(Re5QTi0&u%(RJt&SLr|qnEpG2)OF_}N%+~;4+FCf?d4++x$!uB*`_Dp2)$TZl*gt5N7rt>^Z>fZ1ZkHFM#IyphFcZ-IePq*HlVz zN5Qt%2b-DB!%U5_va^y|!|dr9U^*Wg7}&qBzp|g{9|#Zh7%TVOnQ7X(g;5<2hW9>( z`uaQi`YpbVx0TY@oIy!)-c#MQf8QQvpr?O;>F?P$fO(4h4-9-+q2|-r;xI}{=7RKB i=ea6xdy8kYXElSoX0yi#>KiDIR%D4-fQzbRfWHGXq|hD! diff --git a/F0-nolib/F0_testbrd/proto.c b/F0-nolib/F0_testbrd/proto.c new file mode 100644 index 0000000..b0dbad4 --- /dev/null +++ b/F0-nolib/F0_testbrd/proto.c @@ -0,0 +1,355 @@ +/* + * This file is part of the F0testbrd project. + * Copyright 2021 Edward V. Emelianov . + * + * 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 . + */ + +#include "adc.h" +#include "proto.h" +#include "usart.h" +#include "usb.h" +#include "usb_lib.h" + +void USB_sendstr(const char *str){ + uint16_t l = 0; + const char *b = str; + while(*b++) ++l; + USB_send((const uint8_t*)str, l); +} + +static char *chPWM(volatile uint32_t *reg, char *buf){ + char *lbuf = buf; + lbuf = omit_spaces(lbuf); + char cmd = *lbuf; + lbuf = omit_spaces(lbuf + 1); + uint32_t N; + if(getnum(lbuf, &N) == lbuf) N = 1; + uint32_t oldval = *reg; + if(cmd == '-'){ // decrement + if(oldval < N) return "Already at minimum"; + else *reg -= N; + }else if(cmd == '+'){ // increment + if(oldval + N > 255) return "Already at maximum"; + else *reg += N; + }else{ + USND("Wrong command: "); + return buf; + } + return "OK"; +} + +static char *TIM3pwm(char *buf){ + uint8_t channel = *buf - '1'; + if(channel > 3) return "Wrong channel number"; + volatile uint32_t *reg = &TIM3->CCR1; + return chPWM(®[channel], buf+1); +} + +static char *getPWMvals(){ + USND("TIM1CH1: "); USB_sendstr(u2str(TIM1->CCR1)); + USND("\nTIM3CH1: "); USB_sendstr(u2str(TIM3->CCR1)); + USND("\nTIM3CH2: "); USB_sendstr(u2str(TIM3->CCR2)); + USND("\nTIM3CH3: "); USB_sendstr(u2str(TIM3->CCR3)); + USND("\nTIM3CH4: "); USB_sendstr(u2str(TIM3->CCR4)); + USND("\n"); + return NULL; +} + +static char *USARTsend(char *buf){ + uint32_t N; + if(buf == getnum(buf, &N)) return "Point number of USART"; + if(N < 1 || N > USARTNUM) return "Wrong USART number"; + buf = omit_spaces(buf + 1); + usart_send(N, buf); + transmit_tbuf(); + return "OK"; +} + +const char *helpstring = + "'+'/'-'[num] - increase/decrease TIM1ch1 PWM by 1 or `num`\n" + "1..4'+'/'-'[num] - increase/decrease TIM3chN PWM by 1 or `num`\n" + "'g' - get PWM values\n" + "'A' - get ADC values\n" + "'L' - send long string over USB\n" + "'R' - software reset\n" + "'S' - send short string over USB\n" + "'Ux' - send string to USARTx (1..3)\n" + "'T' - MCU temperature\n" + "'V' - Vdd\n" + "'W' - test watchdog\n" +; + +const char *parse_cmd(char *buf){ + // "long" commands + switch(*buf){ + case '+': + case '-': + return chPWM(&TIM1->CCR1, buf); + break; + case '1': + case '2': + case '3': + case '4': + return TIM3pwm(buf); + case 'U': + return USARTsend(buf + 1); + break; + } + // "short" commands + if(buf[1] != '\n') return buf; + switch(*buf){ + case 'g': + return getPWMvals(); + break; + case 'A': + USND("ADC0: "); USB_sendstr(u2str(getADCval(0))); + USND(" ("); USB_sendstr(u2str(getADCvoltate(0))); + USND("/100 V)\nADC1: "); USB_sendstr(u2str(getADCval(1))); + USND(" ("); USB_sendstr(u2str(getADCvoltate(1))); + USND("/100 V)\n"); + break; + case 'L': + USND("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"; + break; + case 'R': + USND("Soft reset\n"); + //SEND("Soft reset\n"); + NVIC_SystemReset(); + break; + case 'S': + USND("Test string for USB\n"); + return "Short test sent"; + break; + case 'T': + return u2str(getMCUtemp()); + break; + case 'V': + return u2str(getVdd()); + break; + case 'W': + USND("Wait for reboot\n"); + //SEND("Wait for reboot\n"); + while(1){nop();}; + break; + default: // help + return helpstring; + break; + } + return NULL; +} + +// usb getline +char *get_USB(){ + static char tmpbuf[129], *curptr = tmpbuf; + static int rest = 128; + int x = USB_receive((uint8_t*)curptr); + curptr[x] = 0; + if(!x) return NULL; + 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; +} + + +static char *_2str(uint32_t val, uint8_t minus){ + static char strbuf[12]; + char *bufptr = &strbuf[11]; + *bufptr = 0; + if(!val){ + *(--bufptr) = '0'; + }else{ + while(val){ + *(--bufptr) = val % 10 + '0'; + val /= 10; + } + } + if(minus) *(--bufptr) = '-'; + return bufptr; +} + +// return string with number `val` +char *u2str(uint32_t val){ + return _2str(val, 0); +} +char *i2str(int32_t i){ + uint8_t minus = 0; + uint32_t val; + if(i < 0){ + minus = 1; + val = -i; + }else val = i; + return _2str(val, minus); +} +// print 32bit unsigned int as hex +char *uhex2str(uint32_t val){ + static char buf[12] = "0x"; + int npos = 2; + uint8_t *ptr = (uint8_t*)&val + 3; + int8_t i, j, z=1; + for(i = 0; i < 4; ++i, --ptr){ + if(*ptr == 0){ // omit leading zeros + if(i == 3) z = 0; + if(z) continue; + } + else z = 0; + for(j = 1; j > -1; --j){ + uint8_t half = (*ptr >> (4*j)) & 0x0f; + if(half < 10) buf[npos++] = half + '0'; + else buf[npos++] = half - 10 + 'a'; + } + } + buf[npos] = 0; + return buf; +} + +char *omit_spaces(const char *buf){ + while(*buf){ + if(*buf > ' ') break; + ++buf; + } + return (char*)buf; +} + +// In case of overflow return `buf` and N==0xffffffff +// read decimal number & return pointer to next non-number symbol +static char *getdec(const char *buf, uint32_t *N){ + char *start = (char*)buf; + uint32_t num = 0; + while(*buf){ + char c = *buf; + if(c < '0' || c > '9'){ + break; + } + if(num > 429496729 || (num == 429496729 && c > '5')){ // overflow + *N = 0xffffff; + return start; + } + num *= 10; + num += c - '0'; + ++buf; + } + *N = num; + return (char*)buf; +} +// read hexadecimal number (without 0x prefix!) +static char *gethex(const char *buf, uint32_t *N){ + char *start = (char*)buf; + uint32_t num = 0; + while(*buf){ + char c = *buf; + uint8_t M = 0; + if(c >= '0' && c <= '9'){ + M = '0'; + }else if(c >= 'A' && c <= 'F'){ + M = 'A' - 10; + }else if(c >= 'a' && c <= 'f'){ + M = 'a' - 10; + } + if(M){ + if(num & 0xf0000000){ // overflow + *N = 0xffffff; + return start; + } + num <<= 4; + num += c - M; + }else{ + break; + } + ++buf; + } + *N = num; + return (char*)buf; +} +// read octal number (without 0 prefix!) +static char *getoct(const char *buf, uint32_t *N){ + char *start = (char*)buf; + uint32_t num = 0; + while(*buf){ + char c = *buf; + if(c < '0' || c > '7'){ + break; + } + if(num & 0xe0000000){ // overflow + *N = 0xffffff; + return start; + } + num <<= 3; + num += c - '0'; + ++buf; + } + *N = num; + return (char*)buf; +} +// read binary number (without b prefix!) +static char *getbin(const char *buf, uint32_t *N){ + char *start = (char*)buf; + uint32_t num = 0; + while(*buf){ + char c = *buf; + if(c < '0' || c > '1'){ + break; + } + if(num & 0x80000000){ // overflow + *N = 0xffffff; + return start; + } + num <<= 1; + if(c == '1') num |= 1; + ++buf; + } + *N = num; + return (char*)buf; +} + +/** + * @brief getnum - read uint32_t from string (dec, hex or bin: 127, 0x7f, 0b1111111) + * @param buf - buffer with number and so on + * @param N - the number read + * @return pointer to first non-number symbol in buf + * (if it is == buf, there's no number or if *N==0xffffffff there was overflow) + */ +char *getnum(const char *txt, uint32_t *N){ + char *nxt = NULL; + char *s = omit_spaces(txt); + if(*s == '0'){ // hex, oct or 0 + if(s[1] == 'x' || s[1] == 'X'){ // hex + nxt = gethex(s+2, N); + if(nxt == s+2) nxt = (char*)txt; + }else if(s[1] > '0'-1 && s[1] < '8'){ // oct + nxt = getoct(s+1, N); + if(nxt == s+1) nxt = (char*)txt; + }else{ // 0 + nxt = s+1; + *N = 0; + } + }else if(*s == 'b' || *s == 'B'){ + nxt = getbin(s+1, N); + if(nxt == s+1) nxt = (char*)txt; + }else{ + nxt = getdec(s, N); + if(nxt == s) nxt = (char*)txt; + } + return nxt; +} diff --git a/F0-nolib/F0_testbrd/proto.h b/F0-nolib/F0_testbrd/proto.h new file mode 100644 index 0000000..0318b36 --- /dev/null +++ b/F0-nolib/F0_testbrd/proto.h @@ -0,0 +1,34 @@ +/* + * This file is part of the F0testbrd project. + * Copyright 2021 Edward V. Emelianov . + * + * 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 . + */ +#pragma once +#ifndef PROTO_H__ +#define PROTO_H__ + +#define USND(str) do{USB_send((uint8_t*)str, sizeof(str)-1);}while(0) + +void USB_sendstr(const char *str); +char *get_USB(); +const char *parse_cmd(char *buf); + +char *u2str(uint32_t val); +char *i2str(int32_t i); +char *uhex2str(uint32_t val); +char *getnum(const char *txt, uint32_t *N); +char *omit_spaces(const char *buf); + +#endif // PROTO_H__ diff --git a/F0-nolib/F0_testbrd/usart.c b/F0-nolib/F0_testbrd/usart.c index 4915aba..8c612cd 100644 --- a/F0-nolib/F0_testbrd/usart.c +++ b/F0-nolib/F0_testbrd/usart.c @@ -20,240 +20,232 @@ */ #include "stm32f0.h" #include "hardware.h" +#include "proto.h" #include "usart.h" +#include "usb.h" #include 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}; +// USART tx DMA 1: DMA1_Channel2, 2: DMA1_Channel4, 3: DMA1_Channel7 +static DMA_Channel_TypeDef *USARTDMA[USARTNUM] = { + DMA1_Channel2, DMA1_Channel4 +#ifdef USART3 + ,DMA1_Channel7 +#endif +}; +static USART_TypeDef *USARTs[USARTNUM] = { + USART1, USART2 +#ifdef USART3 + ,USART3 +#endif +}; -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 +static volatile int idatalen[USARTNUM][2] = {0}; // received data line length (including '\n') +static volatile int odatalen[USARTNUM][2] = {0}; + +volatile int linerdy[USARTNUM] = {0}, // received data ready + dlen[USARTNUM] = {0}, // length of data (including '\n') in current buffer + bufovr[USARTNUM] = {0}, // input buffer overfull + txrdy[USARTNUM] = {1,1 // transmission done +#ifdef USART3 + ,1 +#endif + } ; -int rbufno = 0, tbufno = 0; // current rbuf/tbuf numbers -static char rbuf[2][UARTBUFSZI], tbuf[2][UARTBUFSZO]; // receive & transmit buffers -static char *recvdata = NULL; +int rbufno[USARTNUM] = {0}, tbufno[USARTNUM] = {0}; // current rbuf/tbuf numbers +static char rbuf[USARTNUM][2][UARTBUFSZI], tbuf[USARTNUM][2][UARTBUFSZO]; // receive & transmit buffers +static char *recvdata[USARTNUM] = {0}; /** * return length of received data (without trailing zero + * usartno: 1, 2 or 3 */ -int usart_getline(char **line){ - if(bufovr){ - bufovr = 0; - linerdy = 0; +int usart_getline(int usartno, char **line){ + --usartno; + if(bufovr[usartno]){ + bufovr[usartno] = 0; + linerdy[usartno] = 0; return 0; } - *line = recvdata; - linerdy = 0; - return dlen; + *line = recvdata[usartno]; + linerdy[usartno] = 0; + return dlen[usartno]; } -// transmit current tbuf and swap buffers +// transmit current tbuf for all USARTs 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++; + for(int usartno = 0; usartno < USARTNUM; ++usartno){ + uint32_t p = 1000000; + while(!txrdy[usartno] && --p); + if(!txrdy[usartno]) continue; + register int l = odatalen[usartno][tbufno[usartno]]; + if(!l) continue; + txrdy[usartno] = 0; + odatalen[usartno][tbufno[usartno]] = 0; + USARTDMA[usartno]->CCR &= ~DMA_CCR_EN; + USARTDMA[usartno]->CMAR = (uint32_t) tbuf[usartno][tbufno[usartno]]; // mem + USARTDMA[usartno]->CNDTR = l; + USARTDMA[usartno]->CCR |= DMA_CCR_EN; + tbufno[usartno] = !tbufno[usartno]; } } -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 usart_putchar(int usartno, const char ch){ + --usartno; + if(odatalen[usartno][tbufno[usartno]] == UARTBUFSZO) transmit_tbuf(); + tbuf[usartno][tbufno[usartno]][odatalen[usartno][tbufno[usartno]]++] = ch; +} + +void usart_send(int usartno, const char *str){ + --usartno; + while(*str){ + if(odatalen[usartno][tbufno[usartno]] == UARTBUFSZO) transmit_tbuf(); + tbuf[usartno][tbufno[usartno]][odatalen[usartno][tbufno[usartno]]++] = *str++; } } -void newline(){ - usart_putchar('\n'); +void usart_sendn(int usartno, const char *str, uint32_t L){ + --usartno; + for(uint32_t i = 0; i < L; ++i){ + if(odatalen[usartno][tbufno[usartno]] == UARTBUFSZO) transmit_tbuf(); + tbuf[usartno][tbufno[usartno]][odatalen[usartno][tbufno[usartno]]++] = *str++; + } +} + +void newline(int usartno){ + usart_putchar(usartno, '\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); + // USART1: Rx - PA10, Tx - PA9 (AF1) + // USART2: Rx - PA3, Tx - PA2 (AF1) + // USART3: Rx - PB11, Tx - PB10 (AF4) + // setup pins: + GPIOA->MODER = (GPIOA->MODER & ~(GPIO_MODER_MODER2|GPIO_MODER_MODER3|GPIO_MODER_MODER9 | GPIO_MODER_MODER10)) | + GPIO_MODER_MODER2_AF | GPIO_MODER_MODER3_AF | GPIO_MODER_MODER9_AF | GPIO_MODER_MODER10_AF; + GPIOA->AFR[0] = (GPIOA->AFR[0] & ~(GPIO_AFRL_AFRL2 | GPIO_AFRL_AFRL3)) | + 1 << (2 * 4) | 1 << (3 * 4); // PA2,3 GPIOA->AFR[1] = (GPIOA->AFR[1] & ~(GPIO_AFRH_AFRH1 | GPIO_AFRH_AFRH2)) | 1 << (1 * 4) | 1 << (2 * 4); // PA9, PA10 + // clock RCC->APB2ENR |= RCC_APB2ENR_USART1EN; -#else -#error "Wrong USARTNUM" + RCC->APB1ENR |= RCC_APB1ENR_USART2EN; +#ifdef USART3 + GPIOB->MODER = (GPIOB->MODER & ~(GPIO_MODER_MODER10 | GPIO_MODER_MODER11)) | + GPIO_MODER_MODER10_AF | GPIO_MODER_MODER11_AF; + GPIOB->AFR[1] = (GPIOB->AFR[1] & ~(GPIO_AFRH_AFRH2 | GPIO_AFRH_AFRH3)) | + 4 << (2 * 4) | 4 << (3 * 4); // PB10, PB11 +#endif + for(int i = 0; i < USARTNUM; ++i){ + USARTs[i]->ICR = 0xffffffff; // clear all flags + // USARTX Tx DMA + USARTDMA[i]->CPAR = (uint32_t) &USARTs[i]->TDR; // periph + USARTDMA[i]->CCR |= DMA_CCR_MINC | DMA_CCR_DIR | DMA_CCR_TCIE; // 8bit, mem++, mem->per, transcompl irq + // setup usarts + USARTs[i]->BRR = 480000 / 1152; + USARTs[i]->CR3 = USART_CR3_DMAT; // enable DMA Tx + USARTs[i]->CR1 = USART_CR1_TE | USART_CR1_RE | USART_CR1_UE | USART_CR1_RXNEIE; // 1start,8data,nstop; enable Rx,Tx,USART + uint32_t tmout = 16000000; + while(!(USARTs[i]->ISR & USART_ISR_TC)){if(--tmout == 0) break;} // polling idle frame Transmission + USARTs[i]->ICR = 0xffffffff; // clear all flags again + } + NVIC_SetPriority(DMA1_Channel2_3_IRQn, 3); + NVIC_EnableIRQ(DMA1_Channel2_3_IRQn); + NVIC_SetPriority(USART1_IRQn, 0); + NVIC_EnableIRQ(USART1_IRQn); + NVIC_SetPriority(DMA1_Channel4_5_6_7_IRQn, 3); + NVIC_EnableIRQ(DMA1_Channel4_5_6_7_IRQn); + NVIC_SetPriority(USART2_IRQn, 0); + NVIC_EnableIRQ(USART2_IRQn); +#ifdef USART3 + NVIC_SetPriority(USART3_4_IRQn, 0); + NVIC_EnableIRQ(USART3_4_IRQn); #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 + +static void usart_IRQ(int usartno){ + USART_TypeDef *USARTX = USARTs[usartno]; + //USND("USART"); USB_sendstr(u2str(usartno+1)); USND(" IRQ, ISR="); + //USB_sendstr(uhex2str(USARTX->ISR)); USND("\n"); #ifdef CHECK_TMOUT - static uint32_t tmout = 0; + static uint32_t tmout[USARTNUM] = {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; + if(tmout[usartno] && Tms >= tmout[usartno]){ // set overflow flag + bufovr[usartno] = 1; + idatalen[usartno][rbufno[usartno]] = 0; } - tmout = Tms + TIMEOUT_MS; - if(!tmout) tmout = 1; // prevent 0 + tmout[usartno] = Tms + TIMEOUT_MS; + if(!tmout[usartno]) tmout[usartno] = 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; + //USND("RB="); USB_sendstr(uhex2str(rb)); USND("\n"); + if(idatalen[usartno][rbufno[usartno]] < UARTBUFSZI){ // put next char into buf + rbuf[usartno][rbufno[usartno]][idatalen[usartno][rbufno[usartno]]++] = rb; if(rb == '\n'){ // got newline - line ready - linerdy = 1; - dlen = idatalen[rbufno]; - recvdata = rbuf[rbufno]; + //USND("Newline\n"); + linerdy[usartno] = 1; + dlen[usartno] = idatalen[usartno][rbufno[usartno]]; + recvdata[usartno] = rbuf[usartno][rbufno[usartno]]; // prepare other buffer - rbufno = !rbufno; - idatalen[rbufno] = 0; + rbufno[usartno] = !rbufno[usartno]; + idatalen[usartno][rbufno[usartno]] = 0; #ifdef CHECK_TMOUT // clear timeout at line end - tmout = 0; + tmout[usartno] = 0; #endif } }else{ // buffer overrun - bufovr = 1; - idatalen[rbufno] = 0; + bufovr[usartno] = 1; + idatalen[usartno][rbufno[usartno]] = 0; #ifdef CHECK_TMOUT - tmout = 0; + tmout[usartno] = 0; #endif } } + USARTX->ICR = 0xffffffff; } -// 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)); +void usart1_isr(){ + usart_IRQ(0); } -// 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'); - } +void usart2_isr(){ + usart_IRQ(1); } -// 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; - } +// work with USART3 only @ boards that have it +#ifdef USART3 +void usart3_4_isr(){ + usart_IRQ(2); } +#endif + // 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; + txrdy[0] = 1; } } -#else -#error "Wrong USARTNUM" +// USART2 + USART3 +void dma1_channel4_5_isr(){ + if(DMA1->ISR & DMA_ISR_TCIF4){ // Tx + DMA1->IFCR |= DMA_IFCR_CTCIF4; // clear TC flag + txrdy[1] = 1; + } +#ifdef USART3 + if(DMA1->ISR & DMA_ISR_TCIF7){ // Tx + DMA1->IFCR |= DMA_IFCR_CTCIF7; // clear TC flag + txrdy[2] = 1; + } #endif +} diff --git a/F0-nolib/F0_testbrd/usart.h b/F0-nolib/F0_testbrd/usart.h index ae4f618..32e758f 100644 --- a/F0-nolib/F0_testbrd/usart.h +++ b/F0-nolib/F0_testbrd/usart.h @@ -24,6 +24,13 @@ #include "hardware.h" +#ifdef USART3 +#define USARTNUM (3) +#else +#define USARTNUM (2) +#endif + + // input and output buffers size #define UARTBUFSZI (32) #define UARTBUFSZO (512) @@ -33,23 +40,19 @@ #endif // macro for static strings -#define SEND(str) usart_send(str) +#define SEND(n, str) usart_send(n, str) -#define usartrx() (linerdy) -#define usartovr() (bufovr) +#define usartrx(n) (linerdy[n-1]) +#define usartovr(n) (bufovr[n-1]) -extern volatile int linerdy, bufovr, txrdy; +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); +int usart_getline(int usartno, char **line); +void usart_send(int usartno, const char *str); +void usart_sendn(int usartno, const char *str, uint32_t L); +void newline(int usartno); +void usart_putchar(int usartno, const char ch); #endif // __USART_H__ diff --git a/F0-nolib/F0_testbrd/usb.c b/F0-nolib/F0_testbrd/usb.c index aed0e0f..57872ab 100644 --- a/F0-nolib/F0_testbrd/usb.c +++ b/F0-nolib/F0_testbrd/usb.c @@ -23,7 +23,6 @@ #include "usb.h" #include "usb_lib.h" -#include "usart.h" static volatile uint8_t tx_succesfull = 1; static volatile uint8_t rxNE = 0; @@ -162,7 +161,6 @@ void usb_proc(){ */ uint8_t USB_receive(uint8_t *buf){ if(!usbON || !rxNE) return 0; - SEND((char*)buf); newline(); uint8_t sz = EP_Read(2, buf); uint16_t epstatus = KEEP_DTOG(USB->EPnR[2]); // keep stat_tx & set ACK rx diff --git a/F0-nolib/F0_testbrd/usb_lib.c b/F0-nolib/F0_testbrd/usb_lib.c index 187c84b..d99f687 100644 --- a/F0-nolib/F0_testbrd/usb_lib.c +++ b/F0-nolib/F0_testbrd/usb_lib.c @@ -22,7 +22,6 @@ */ #include -#include "usart.h" #include "usb_lib.h" diff --git a/F0_F1_F3-LQFP48_testboard/stm32 b/F0_F1_F3-LQFP48_testboard/stm32 deleted file mode 100644 index e7214dd..0000000 --- a/F0_F1_F3-LQFP48_testboard/stm32 +++ /dev/null @@ -1,30 +0,0 @@ -"Source:","/Big/Data/00__Electronics/STM32/F0_F1_F3-LQFP48_testboard/stm32.sch" -"Date:","óÒ 23 ÉÀÎ 2021 22:52:44" -"Tool:","Eeschema 5.1.10" -"Generator:","/usr/share/kicad/plugins/bom_csv_grouped_by_value_with_fp.py" -"Component Count:","54" -"Ref","Qnty","Value","Cmp name","Footprint","Description","Vendor" -"C1, C2, C3, C7, C8, C9, C10, ","7","0.1","C","Capacitor_SMD:C_0603_1608Metric_Pad1.05x0.95mm_HandSolder","","" -"C4, ","1","47u","CP","Capacitor_Tantalum_SMD:CP_EIA-6032-28_Kemet-C_Pad2.25x2.35mm_HandSolder","","" -"C5, C6, ","2","12","C","Capacitor_SMD:C_0603_1608Metric_Pad1.05x0.95mm_HandSolder","","" -"D1, D2, D3, D4, D5, D6, ","6","LED","LED-RESCUE-stm32","LED_THT:LED_D3.0mm","","" -"J1, J5, J6, J7, J8, J9, J11, ","7","Conn_01x04_Female","Conn_01x04_Female","Connector_PinSocket_2.54mm:PinSocket_1x04_P2.54mm_Vertical","Generic connector, single row, 01x04, script generated (kicad-library-utils/schlib/autogen/connector/)","" -"J2, J4, J10, J12, ","4","Conn_01x01_Female","Conn_01x01_Female","Connector_PinSocket_2.54mm:PinSocket_1x01_P2.54mm_Vertical","Generic connector, single row, 01x01, script generated (kicad-library-utils/schlib/autogen/connector/)","" -"J3, ","1","Conn_01x02_Female","Conn_01x02_Female","Connector_PinSocket_2.54mm:PinSocket_1x02_P2.54mm_Vertical","Generic connector, single row, 01x02, script generated (kicad-library-utils/schlib/autogen/connector/)","" -"P1, ","1","USART1","Conn_01x03_Female","Connector_PinSocket_2.54mm:PinSocket_1x03_P2.54mm_Vertical","Generic connector, single row, 01x03, script generated (kicad-library-utils/schlib/autogen/connector/)","" -"P2, ","1","USART2/3","Conn_01x03_Female","Connector_PinSocket_2.54mm:PinSocket_1x03_P2.54mm_Vertical","Generic connector, single row, 01x03, script generated (kicad-library-utils/schlib/autogen/connector/)","" -"P3, ","1","USB_B","USB_A-RESCUE-stm32","Connector_USB:USB_B_OST_USB-B1HSxx_Horizontal","","" -"Q1, ","1","DTA114Y","DTA114Y","Package_TO_SOT_SMD:SOT-323_SC-70_Handsoldering","Digital PNP Transistor, 10k/47k, SOT-23","" -"R1, R2, R14, R15, ","4","4k7","R","Resistor_SMD:R_0805_2012Metric_Pad1.15x1.40mm_HandSolder","","" -"R3, ","1","10k","R","Resistor_SMD:R_0603_1608Metric_Pad1.05x0.95mm_HandSolder","","" -"R5, ","1","100k","R","Resistor_SMD:R_0603_1608Metric_Pad1.05x0.95mm_HandSolder","","" -"R6, R7, R8, R9, R10, R11, ","6","220","R","Resistor_SMD:R_0805_2012Metric_Pad1.15x1.40mm_HandSolder","","" -"R12, R13, ","2","22","R","Resistor_SMD:R_0603_1608Metric_Pad1.05x0.95mm_HandSolder","","" -"R16, ","1","1k5","R","Resistor_SMD:R_0603_1608Metric_Pad1.05x0.95mm_HandSolder","","" -"RV1, ","1","20k","R_POT","my_footprints:Potentiometer","Potentiometer","" -"SW1, ","1","Reset","SW_Push","Button_Switch_THT:SW_PUSH_6mm","","" -"SW2, ","1","Boot","SW_Push","Button_Switch_THT:SW_PUSH_6mm","","" -"U1, ","1","LM1117-3.3","LM1117-3.3-RESCUE-stm32","Package_TO_SOT_SMD:SOT-223","","" -"U2, ","1","STM32LQFP48","STM32F042C6Tx","Package_DIP:DIP-48_W15.24mm_Socket_LongPads","","" -"U3, ","1","USBLC6-2SC6","USBLC6-2SC6","Package_TO_SOT_SMD:SOT-23-6_Handsoldering","Bidirectional ESD Protection Diode, SOT-23-6","" -"Y1, ","1","8MHz","Crystal","Crystal:Crystal_HC49-U_Vertical","Two pin crystal","" diff --git a/F0_F1_F3-LQFP48_testboard/stm32.bom b/F0_F1_F3-LQFP48_testboard/stm32.bom index 6015de6..0893acb 100644 --- a/F0_F1_F3-LQFP48_testboard/stm32.bom +++ b/F0_F1_F3-LQFP48_testboard/stm32.bom @@ -1,73 +1,30 @@ -"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","~" +"Source:","/Big/Data/00__Electronics/STM32/F0_F1_F3-LQFP48_testboard/stm32.sch" +"Date:","þÔ 24 ÉÀÎ 2021 22:21:07" +"Tool:","Eeschema 5.1.10" +"Generator:","/usr/share/kicad/plugins/bom_csv_grouped_by_value_with_fp.py" +"Component Count:","54" +"Ref","Qnty","Value","Cmp name","Footprint","Description","Vendor" +"C1, C2, C3, C7, C8, C9, C10, ","7","0.1","C","Capacitor_SMD:C_0603_1608Metric_Pad1.05x0.95mm_HandSolder","","" +"C4, ","1","47u","CP","Capacitor_Tantalum_SMD:CP_EIA-6032-28_Kemet-C_Pad2.25x2.35mm_HandSolder","","" +"C5, C6, ","2","12","C","Capacitor_SMD:C_0603_1608Metric_Pad1.05x0.95mm_HandSolder","","" +"D1, D2, D3, D4, D5, D6, ","6","LED","LED-RESCUE-stm32","LED_THT:LED_D3.0mm","","" +"J1, J5, J6, J7, J8, J9, J11, ","7","Conn_01x04_Female","Conn_01x04_Female","Connector_PinSocket_2.54mm:PinSocket_1x04_P2.54mm_Vertical","Generic connector, single row, 01x04, script generated (kicad-library-utils/schlib/autogen/connector/)","" +"J2, J4, J10, J12, ","4","Conn_01x01_Female","Conn_01x01_Female","Connector_PinSocket_2.54mm:PinSocket_1x01_P2.54mm_Vertical","Generic connector, single row, 01x01, script generated (kicad-library-utils/schlib/autogen/connector/)","" +"J3, ","1","Conn_01x02_Female","Conn_01x02_Female","Connector_PinSocket_2.54mm:PinSocket_1x02_P2.54mm_Vertical","Generic connector, single row, 01x02, script generated (kicad-library-utils/schlib/autogen/connector/)","" +"P1, ","1","USART1","Conn_01x03_Female","Connector_PinSocket_2.54mm:PinSocket_1x03_P2.54mm_Vertical","Generic connector, single row, 01x03, script generated (kicad-library-utils/schlib/autogen/connector/)","" +"P2, ","1","USART2/3","Conn_01x03_Female","Connector_PinSocket_2.54mm:PinSocket_1x03_P2.54mm_Vertical","Generic connector, single row, 01x03, script generated (kicad-library-utils/schlib/autogen/connector/)","" +"P3, ","1","USB_B","USB_A-RESCUE-stm32","Connector_USB:USB_B_OST_USB-B1HSxx_Horizontal","","" +"Q1, ","1","DTA114Y","DTA114Y","Package_TO_SOT_SMD:SOT-323_SC-70_Handsoldering","Digital PNP Transistor, 10k/47k, SOT-23","" +"R1, R2, R14, R15, ","4","4k7","R","Resistor_SMD:R_0805_2012Metric_Pad1.15x1.40mm_HandSolder","","" +"R3, ","1","10k","R","Resistor_SMD:R_0603_1608Metric_Pad1.05x0.95mm_HandSolder","","" +"R5, ","1","100k","R","Resistor_SMD:R_0603_1608Metric_Pad1.05x0.95mm_HandSolder","","" +"R6, R7, R8, R9, R10, R11, ","6","220","R","Resistor_SMD:R_0805_2012Metric_Pad1.15x1.40mm_HandSolder","","" +"R12, R13, ","2","22","R","Resistor_SMD:R_0603_1608Metric_Pad1.05x0.95mm_HandSolder","","" +"R16, ","1","1k5","R","Resistor_SMD:R_0603_1608Metric_Pad1.05x0.95mm_HandSolder","","" +"RV1, ","1","20k","R_POT","my_footprints:Potentiometer","Potentiometer","" +"SW1, ","1","Reset","SW_Push","Button_Switch_THT:SW_PUSH_6mm","","" +"SW2, ","1","Boot","SW_Push","Button_Switch_THT:SW_PUSH_6mm","","" +"U1, ","1","LM1117-3.3","LM1117-3.3-RESCUE-stm32","Package_TO_SOT_SMD:SOT-223","","" +"U2, ","1","STM32LQFP48","STM32F042C6Tx","Package_DIP:DIP-48_W15.24mm_Socket_LongPads","","" +"U3, ","1","USBLC6-2SC6","USBLC6-2SC6","Package_TO_SOT_SMD:SOT-23-6_Handsoldering","Bidirectional ESD Protection Diode, SOT-23-6","" +"Y1, ","1","8MHz","Crystal","Crystal:Crystal_HC49-U_Vertical","Two pin crystal",""