starting development of F0 for new devboard

This commit is contained in:
Edward Emelianov 2021-06-27 20:26:49 +03:00
parent e432492281
commit 20f4205459
18 changed files with 700 additions and 511 deletions

View File

@ -32,7 +32,7 @@ void spi_setup(){
/* (2) AF0 for SPI1 signals */
GPIOA->MODER = (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;

View File

@ -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

View File

@ -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.

View File

@ -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;
}

View File

@ -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

View File

@ -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(){

View File

@ -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__

View File

@ -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);
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;
ans = parse_cmd(txt);
if(ans){
usart_send(ans);
transmit_tbuf();
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;
}

Binary file not shown.

355
F0-nolib/F0_testbrd/proto.c Normal file
View File

@ -0,0 +1,355 @@
/*
* This file is part of the F0testbrd project.
* Copyright 2021 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"
#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(&reg[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;
}

View File

@ -0,0 +1,34 @@
/*
* This file is part of the F0testbrd project.
* Copyright 2021 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/>.
*/
#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__

View File

@ -20,240 +20,232 @@
*/
#include "stm32f0.h"
#include "hardware.h"
#include "proto.h"
#include "usart.h"
#include "usb.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};
// 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->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);
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
}
#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
}

View File

@ -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__

View File

@ -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

View File

@ -22,7 +22,6 @@
*/
#include <stdint.h>
#include "usart.h"
#include "usb_lib.h"

View File

@ -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",""

View File

@ -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",""