Fixed USB, problems with CAN

This commit is contained in:
Edward Emelianov 2023-02-07 01:15:28 +03:00
parent daf17a651e
commit 2ecd2d188e
20 changed files with 111 additions and 80 deletions

View File

@ -1,8 +1,9 @@
BINARY := canusb BINARY := multistepper
# MCU code # MCU code
MCU := F303xd MCU := F303xd
# change this linking script depending on particular MCU model, # change this linking script depending on particular MCU model,
LDSCRIPT := stm32f303xD.ld LDSCRIPT := stm32f303xD.ld
DEFINES := -DUSB2_16
include ../makefile.f3 include ../makefile.f3
include ../../makefile.stm32 include ../../makefile.stm32

View File

@ -77,12 +77,12 @@ Eighth stepper could be changed to 8 dependent multiplexed. Based on STM32F303VD
| 64 | PC7 | M4 L0 | slow in PU | | | 64 | PC7 | M4 L0 | slow in PU | |
| 65 | PC8 | M4 DIR | slow out | | | 65 | PC8 | M4 DIR | slow out | |
| 66 | PC9 | M4 EN | slow out | | | 66 | PC9 | M4 EN | slow out | |
| 67 | PA8 | BTN0 | slow in PU | Buttons/joystick | | 67 | PA8 | USBpu | slow out PP | USB DP pullup |
| 68 | PA9 | BTN1 | slow in PU | to operate with | | 68 | PA9 | BTN1 | slow in PU | buttons to operate |
| 69 | PA10 | BTN2 (SDA) | slow in PU/AF | screen | | 69 | PA10 | BTN2 (SDA) | slow in PU/AF | with screen |
| 70 | PA11 | USB DM | AF | USB | | 70 | PA11 | USB DM | AF | USB |
| 71 | PA12 | USB DP | AF | | | 71 | PA12 | USB DP | AF | |
| 72 | PA13 | SWDIO/USBpu | dflt/slow out | USB pullup or dbg | | 72 | PA13 | SWDIO | dflt | dbg/flash |
| 73 | PF6 | BTN3 (SCL) | slow in PU/AF | (possible I2C2) | | 73 | PF6 | BTN3 (SCL) | slow in PU/AF | (possible I2C2) |
| 74 | (VSS) | | | | | 74 | (VSS) | | | |
| 75 | (VDD) | | | | | 75 | (VDD) | | | |

View File

@ -116,7 +116,7 @@ void CAN_setup(uint16_t speed){
else if(speed < 50) speed = 50; else if(speed < 50) speed = 50;
else if(speed > 3000) speed = 3000; else if(speed > 3000) speed = 3000;
oldspeed = speed; oldspeed = speed;
uint32_t tmout = 16000000; uint32_t tmout = 10000;
/* Enable the peripheral clock CAN */ /* Enable the peripheral clock CAN */
RCC->APB1ENR |= RCC_APB1ENR_CANEN; RCC->APB1ENR |= RCC_APB1ENR_CANEN;
/* Configure CAN */ /* Configure CAN */
@ -135,14 +135,16 @@ void CAN_setup(uint16_t speed){
CAN->MCR |= CAN_MCR_INRQ; /* (1) */ CAN->MCR |= CAN_MCR_INRQ; /* (1) */
while((CAN->MSR & CAN_MSR_INAK) != CAN_MSR_INAK) /* (2) */ while((CAN->MSR & CAN_MSR_INAK) != CAN_MSR_INAK) /* (2) */
if(--tmout == 0) break; if(--tmout == 0) break;
if(tmout==0){ DBG("timeout!\n");}
CAN->MCR &=~ CAN_MCR_SLEEP; /* (3) */ CAN->MCR &=~ CAN_MCR_SLEEP; /* (3) */
CAN->MCR |= CAN_MCR_ABOM; /* allow automatically bus-off */ CAN->MCR |= CAN_MCR_ABOM; /* allow automatically bus-off */
CAN->BTR = 2 << 20 | 3 << 16 | (4500/speed - 1); //| CAN_BTR_SILM | CAN_BTR_LBKM; /* (4) */ CAN->BTR = 2 << 20 | 3 << 16 | (4500/speed - 1); //| CAN_BTR_SILM | CAN_BTR_LBKM; /* (4) */
CAN->MCR &= ~CAN_MCR_INRQ; /* (5) */ CAN->MCR &= ~CAN_MCR_INRQ; /* (5) */
tmout = 16000000; tmout = 10000;
while((CAN->MSR & CAN_MSR_INAK) == CAN_MSR_INAK) /* (6) */ while((CAN->MSR & CAN_MSR_INAK) == CAN_MSR_INAK) /* (6) */
if(--tmout == 0) break; if(--tmout == 0) break;
if(tmout==0){ DBG("timeout!\n");}
// accept ALL // accept ALL
CAN->FMR = CAN_FMR_FINIT; /* (7) */ CAN->FMR = CAN_FMR_FINIT; /* (7) */
CAN->FA1R = CAN_FA1R_FACT0 | CAN_FA1R_FACT1; /* (8) */ CAN->FA1R = CAN_FA1R_FACT0 | CAN_FA1R_FACT1; /* (8) */
@ -164,7 +166,7 @@ void CAN_setup(uint16_t speed){
can_status = CAN_READY; can_status = CAN_READY;
} }
void printCANerr(){ void CAN_printerr(){
if(!last_err_code) last_err_code = CAN->ESR; if(!last_err_code) last_err_code = CAN->ESR;
if(!last_err_code){ if(!last_err_code){
USB_sendstr("No errors\n"); USB_sendstr("No errors\n");
@ -194,7 +196,7 @@ void printCANerr(){
USB_putbyte('\n'); USB_putbyte('\n');
} }
void can_proc(){ void CAN_proc(){
#ifdef EBUG #ifdef EBUG
if(last_err_code){ if(last_err_code){
USB_sendstr("Error, ESR="); USB_sendstr("Error, ESR=");
@ -213,7 +215,7 @@ void can_proc(){
IWDG->KR = IWDG_REFRESH; IWDG->KR = IWDG_REFRESH;
if(CAN->ESR & (CAN_ESR_BOFF | CAN_ESR_EPVF | CAN_ESR_EWGF)){ // much errors - restart CAN BUS if(CAN->ESR & (CAN_ESR_BOFF | CAN_ESR_EPVF | CAN_ESR_EWGF)){ // much errors - restart CAN BUS
USB_sendstr("\nToo much errors, restarting CAN!\n"); USB_sendstr("\nToo much errors, restarting CAN!\n");
printCANerr(); CAN_printerr();
// request abort for all mailboxes // request abort for all mailboxes
CAN->TSR |= CAN_TSR_ABRQ0 | CAN_TSR_ABRQ1 | CAN_TSR_ABRQ2; CAN->TSR |= CAN_TSR_ABRQ0 | CAN_TSR_ABRQ1 | CAN_TSR_ABRQ2;
// reset CAN bus // reset CAN bus
@ -225,14 +227,14 @@ void can_proc(){
static uint32_t incrmessagectr = 0; static uint32_t incrmessagectr = 0;
if(flood_msg && (Tms - lastFloodTime) >= floodT){ // flood every ~5ms if(flood_msg && (Tms - lastFloodTime) >= floodT){ // flood every ~5ms
lastFloodTime = Tms; lastFloodTime = Tms;
can_send(flood_msg->data, flood_msg->length, flood_msg->ID); CAN_send(flood_msg->data, flood_msg->length, flood_msg->ID);
}else if(incrflood && (Tms - lastFloodTime) >= floodT){ }else if(incrflood && (Tms - lastFloodTime) >= floodT){
lastFloodTime = Tms; lastFloodTime = Tms;
if(CAN_OK == can_send((uint8_t*)&incrmessagectr, 4, flood_msg->ID)) ++incrmessagectr; if(CAN_OK == CAN_send((uint8_t*)&incrmessagectr, 4, flood_msg->ID)) ++incrmessagectr;
} }
} }
CAN_status can_send(uint8_t *msg, uint8_t len, uint16_t target_id){ CAN_status CAN_send(uint8_t *msg, uint8_t len, uint16_t target_id){
uint8_t mailbox = 0; uint8_t mailbox = 0;
// check first free mailbox // check first free mailbox
if(CAN->TSR & (CAN_TSR_TME)){ if(CAN->TSR & (CAN_TSR_TME)){
@ -286,7 +288,7 @@ CAN_status can_send(uint8_t *msg, uint8_t len, uint16_t target_id){
return CAN_OK; return CAN_OK;
} }
void set_flood(CAN_message *msg, int incr){ void CAN_flood(CAN_message *msg, int incr){
if(incr){ incrflood = 1; return; } if(incr){ incrflood = 1; return; }
incrflood = 0; incrflood = 0;
if(!msg) flood_msg = NULL; if(!msg) flood_msg = NULL;
@ -296,6 +298,10 @@ void set_flood(CAN_message *msg, int incr){
} }
} }
uint32_t CAN_speed(){
return oldspeed;
}
static void can_process_fifo(uint8_t fifo_num){ static void can_process_fifo(uint8_t fifo_num){
if(fifo_num > 1) return; if(fifo_num > 1) return;
CAN_FIFOMailBox_TypeDef *box = &CAN->sFIFOMailBox[fifo_num]; CAN_FIFOMailBox_TypeDef *box = &CAN->sFIFOMailBox[fifo_num];

View File

@ -50,10 +50,11 @@ CAN_status CAN_get_status();
void CAN_reinit(uint16_t speed); void CAN_reinit(uint16_t speed);
void CAN_setup(uint16_t speed); void CAN_setup(uint16_t speed);
CAN_status can_send(uint8_t *msg, uint8_t len, uint16_t target_id); CAN_status CAN_send(uint8_t *msg, uint8_t len, uint16_t target_id);
void can_proc(); void CAN_proc();
void printCANerr(); void CAN_printerr();
CAN_message *CAN_messagebuf_pop(); CAN_message *CAN_messagebuf_pop();
void set_flood(CAN_message *msg, int incr); void CAN_flood(CAN_message *msg, int incr);
uint32_t CAN_speed();

Binary file not shown.

View File

@ -18,9 +18,9 @@
#include "hardware.h" #include "hardware.h"
// Buttons: PA8, PA9, PA10, PF6, PD3, PD4, PD5, pullup (active - 0) // Buttons: PA9, PA10, PF6, PD3, PD4, PD5, pullup (active - 0)
volatile GPIO_TypeDef* const BTNports[BTNSNO] = {GPIOA, GPIOA, GPIOA, GPIOF, GPIOD, GPIOD, GPIOD}; volatile GPIO_TypeDef* const BTNports[BTNSNO] = {GPIOA, GPIOA, GPIOF, GPIOD, GPIOD, GPIOD};
const uint32_t BTNpins[BTNSNO] = {1<<8, 1<<9, 1<<10, 1<<6, 1<<3, 1<<4, 1<<5}; const uint32_t BTNpins[BTNSNO] = {1<<9, 1<<10, 1<<6, 1<<3, 1<<4, 1<<5};
// setup here ALL GPIO pins (due to table in Readme.md) // setup here ALL GPIO pins (due to table in Readme.md)
// leave SWD as default AF; high speed for CLK and some other AF; med speed for some another AF // leave SWD as default AF; high speed for CLK and some other AF; med speed for some another AF
@ -30,9 +30,9 @@ TRUE_INLINE void gpio_setup(){
for(int i = 0; i < 10000; ++i) nop(); for(int i = 0; i < 10000; ++i) nop();
GPIOA->ODR = 0; GPIOA->ODR = 0;
GPIOA->AFR[0] = AFRf(5, 5) | AFRf(5, 6) | AFRf(5, 7); GPIOA->AFR[0] = AFRf(5, 5) | AFRf(5, 6) | AFRf(5, 7);
GPIOA->AFR[1] = /*AFRf(4, 10) |*/ AFRf(14, 11) | AFRf(14,12) | AFRf(1, 15); GPIOA->AFR[1] = /*AFRf(4, 10) |*/ /*AFRf(14, 11) | AFRf(14,12) |*/ AFRf(1, 15);
GPIOA->MODER = MODER_AF(5) | MODER_AF(6) | MODER_AF(7) | MODER_I(8) | MODER_I(9) | MODER_I(10) /*MODER_AF(10)*/ GPIOA->MODER = MODER_AF(5) | MODER_AF(6) | MODER_AF(7) | MODER_O(8) | MODER_I(9) | MODER_I(10) /*MODER_AF(10)*/
| MODER_AF(11) | MODER_AF(12) | MODER_O(13) | MODER_AF(14) | MODER_AF(15); | /*MODER_AF(11) | MODER_AF(12) |*/ MODER_AF(13) | MODER_AF(14) | MODER_AF(15);
GPIOA->OSPEEDR = OSPEED_MED(5) | OSPEED_MED(6) | OSPEED_MED(7) | OSPEED_HI(11) | OSPEED_HI(12) GPIOA->OSPEEDR = OSPEED_MED(5) | OSPEED_MED(6) | OSPEED_MED(7) | OSPEED_HI(11) | OSPEED_HI(12)
| OSPEED_HI(13) | OSPEED_HI(15); | OSPEED_HI(13) | OSPEED_HI(15);
GPIOA->OTYPER = 0; GPIOA->OTYPER = 0;
@ -84,8 +84,6 @@ TRUE_INLINE void gpio_setup(){
GPIOF->OSPEEDR = OSPEED_HI(9); GPIOF->OSPEEDR = OSPEED_HI(9);
GPIOF->OTYPER = 0; GPIOF->OTYPER = 0;
GPIOF->PUPDR = PUPD_PU(6); GPIOF->PUPDR = PUPD_PU(6);
USBPU_OFF();
} }
#ifndef EBUG #ifndef EBUG

View File

@ -20,13 +20,17 @@
#include <stm32f3.h> #include <stm32f3.h>
// USB pullup: PA8
#define USBPU_port GPIOA #define USBPU_port GPIOA
#define USBPU_pin (1<<13) #define USBPU_pin (1<<8)
#define USBPU_ON() pin_set(USBPU_port, USBPU_pin) #define USBPU_ON() pin_clear(USBPU_port, USBPU_pin)
#define USBPU_OFF() pin_clear(USBPU_port, USBPU_pin) #define USBPU_OFF() pin_set(USBPU_port, USBPU_pin)
// temporary LED: PD9
#define LED_blink() pin_toggle(GPIOD, 1<<9)
// Buttons amount // Buttons amount
#define BTNSNO (7) #define BTNSNO (6)
// Buttons ports & pins // Buttons ports & pins
extern volatile GPIO_TypeDef* const BTNports[BTNSNO]; extern volatile GPIO_TypeDef* const BTNports[BTNSNO];
extern const uint32_t BTNpins[BTNSNO]; extern const uint32_t BTNpins[BTNSNO];

View File

@ -16,7 +16,7 @@
"canspeed - GS CAN speed (reinit if setter)\n" "canspeed - GS CAN speed (reinit if setter)\n"
"canstat - G CAN status\n" "canstat - G CAN status\n"
"delignlist* - delete ignore list\n" "delignlist* - delete ignore list\n"
"diagn[N] - G DIAG state of motor N (or all)\n" "diagn[N]* - G DIAG state of motor N (or all)\n"
"dumperr* - dump error codes\n" "dumperr* - dump error codes\n"
"dumpcmd* - dump command codes\n" "dumpcmd* - dump command codes\n"
"dumpconf* - dump current configuration\n" "dumpconf* - dump current configuration\n"
@ -44,13 +44,13 @@
"ping* - echo given command back\n" "ping* - echo given command back\n"
"relposN* - GS relative move (get remaining)\n" "relposN* - GS relative move (get remaining)\n"
"relslowN* - GS like 'relpos' but with slowest speed\n" "relslowN* - GS like 'relpos' but with slowest speed\n"
"reset* - software reset\n" "reset - software reset\n"
"saveconf* - save current configuration\n" "saveconf* - save current configuration\n"
"screen* - GS screen enable (1) or disable (0)\n" "screen* - GS screen enable (1) or disable (0)\n"
"speedlimit* - G limiting speed for current microsteps setting\n" "speedlimit* - G limiting speed for current microsteps setting\n"
"stateN* - G motor state (0-relax, 1-accel, 2-move, 3-mvslow, 4-decel, 5-stall, 6-err)\n" "stateN* - G motor state (0-relax, 1-accel, 2-move, 3-mvslow, 4-decel, 5-stall, 6-err)\n"
"stopN* - stop motor with deceleration\n" "stopN* - stop motor with deceleration\n"
"time* - G time from start (ms)\n" "time - G time from start (ms)\n"
"tmcbus* - GS TMC control bus (0 - USART, 1 - SPI)\n" "tmcbus* - GS TMC control bus (0 - USART, 1 - SPI)\n"
"udata - GS data by usart in slave mode (text strings, '\\n'-terminated)\n" "udata* - GS data by usart in slave mode (text strings, '\\n'-terminated)\n"
"usartstatus* - GS status of USART1 (0 - off, 1 - master, 2 - slave)\n" "usartstatus* - GS status of USART1 (0 - off, 1 - master, 2 - slave)\n"

View File

@ -38,13 +38,9 @@ int main(void){
SysTick_Config((uint32_t)48000); // 1ms SysTick_Config((uint32_t)48000); // 1ms
} }
hw_setup(); hw_setup();
// here we should check the debug mode and turn off SWD if no USBPU_OFF(); // make a reconnection
if(BTN_state(0) && BTN_state(1)){ // NO debug - turn ON SWDIO (AF0) USB_setup();
GPIOA->MODER = (GPIOA->MODER & ~MODER_CLR(13)) | MODER_AF(13); USBPU_ON();
}else{
USB_setup();
USBPU_ON();
}
CAN_setup(100); CAN_setup(100);
uint32_t ctr = 0; uint32_t ctr = 0;
CAN_message *can_mesg; CAN_message *can_mesg;
@ -52,8 +48,9 @@ int main(void){
IWDG->KR = IWDG_REFRESH; IWDG->KR = IWDG_REFRESH;
if(Tms - ctr > 499){ if(Tms - ctr > 499){
ctr = Tms; ctr = Tms;
LED_blink();
} }
can_proc(); CAN_proc();
USB_proc(); USB_proc();
if(CAN_get_status() == CAN_FIFO_OVERRUN){ if(CAN_get_status() == CAN_FIFO_OVERRUN){
USB_sendstr("CAN bus fifo overrun occured!\n"); USB_sendstr("CAN bus fifo overrun occured!\n");

View File

@ -5,3 +5,4 @@
#define STM32F303xd #define STM32F303xd
#define __thumb2__ 1 #define __thumb2__ 1
#define __ARM_ARCH_7M__ #define __ARM_ARCH_7M__
#define USB2_16

View File

@ -1,11 +1,9 @@
# SPDX-License-Identifier: GPL-2.0-or-later
# script for stm32f3x family # script for stm32f3x family
# #
# stm32 devices support both JTAG and SWD transports. # stm32 devices support both JTAG and SWD transports.
# #
source [find interface/stlink-v2-1.cfg] source [find interface/stlink.cfg]
source [find target/swj-dp.tcl] source [find target/swj-dp.tcl]
source [find mem_helper.tcl] source [find mem_helper.tcl]
@ -104,16 +102,9 @@ $_TARGETNAME configure -event examine-end { stm32f3x_default_examine_end }
$_TARGETNAME configure -event reset-start { stm32f3x_default_reset_start } $_TARGETNAME configure -event reset-start { stm32f3x_default_reset_start }
$_TARGETNAME configure -event reset-init { stm32f3x_default_reset_init } $_TARGETNAME configure -event reset-init { stm32f3x_default_reset_init }
tpiu create $_CHIPNAME.tpiu -dap $_CHIPNAME.dap -ap-num 0 -baseaddr 0xE0040000 $_TARGETNAME configure -event trace-config {
lappend _telnet_autocomplete_skip _proc_pre_enable_$_CHIPNAME.tpiu
proc _proc_pre_enable_$_CHIPNAME.tpiu {_targetname} {
targets $_targetname
# Set TRACE_IOEN; TRACE_MODE is set to async; when using sync # Set TRACE_IOEN; TRACE_MODE is set to async; when using sync
# change this value accordingly to configure trace pins # change this value accordingly to configure trace pins
# assignment # assignment
mmw 0xe0042004 0x00000020 0 mmw 0xe0042004 0x00000020 0
} }
$_CHIPNAME.tpiu configure -event pre-enable "_proc_pre_enable_$_CHIPNAME.tpiu $_TARGETNAME"

View File

@ -282,7 +282,7 @@ int fn_canfilter(_U_ uint32_t hash, char *args){
} }
int fn_canflood(_U_ uint32_t hash, char *args){ int fn_canflood(_U_ uint32_t hash, char *args){
set_flood(parseCANmsg(args), 0); CAN_flood(parseCANmsg(args), 0);
return RET_GOOD; return RET_GOOD;
} }
@ -294,7 +294,7 @@ int fn_cansend(_U_ uint32_t hash, char *args){
CAN_message *msg = parseCANmsg(args); CAN_message *msg = parseCANmsg(args);
if(!msg) return RET_WRONGCMD; if(!msg) return RET_WRONGCMD;
uint32_t N = 5; uint32_t N = 5;
while(CAN_BUSY == can_send(msg->data, msg->length, msg->ID)){ while(CAN_BUSY == CAN_send(msg->data, msg->length, msg->ID)){
if(--N == 0) break; if(--N == 0) break;
} }
if(N == 0) return RET_BAD; if(N == 0) return RET_BAD;
@ -326,12 +326,12 @@ int fn_canstat(_U_ uint32_t hash, _U_ char *args){
} }
int fn_canerrcodes(_U_ uint32_t hash, _U_ char *args){ int fn_canerrcodes(_U_ uint32_t hash, _U_ char *args){
printCANerr(); CAN_printerr();
return RET_GOOD; return RET_GOOD;
} }
int fn_canincrflood(_U_ uint32_t hash, _U_ char *args){ int fn_canincrflood(_U_ uint32_t hash, _U_ char *args){
set_flood(NULL, 1); CAN_flood(NULL, 1);
USB_sendstr("Incremental flooding is ON ('F' to off)\n"); USB_sendstr("Incremental flooding is ON ('F' to off)\n");
return RET_GOOD; return RET_GOOD;
} }
@ -344,7 +344,9 @@ int fn_canspeed(_U_ uint32_t hash, _U_ char *args){
return RET_GOOD; return RET_GOOD;
} }
if(N < 50){ if(N < 50){
USB_sendstr("Lowest speed is 50kbps"); USB_sendstr("canspeed=");
USB_sendstr(u2str(CAN_speed()));
newline();
return RET_GOOD; return RET_GOOD;
}else if(N > 3000){ }else if(N > 3000){
USB_sendstr("Highest speed is 3000kbps"); USB_sendstr("Highest speed is 3000kbps");

View File

@ -146,7 +146,7 @@ static void transmit_Handler(){ // EP3IN
static void receive_Handler(){ // EP2OUT static void receive_Handler(){ // EP2OUT
uint8_t buf[USB_RXBUFSZ]; uint8_t buf[USB_RXBUFSZ];
uint16_t epstatus = KEEP_DTOG(USB->EPnR[2]); uint16_t epstatus = KEEP_DTOG(USB->EPnR[2]);
uint8_t sz = EP_Read(2, (uint16_t*)buf); uint8_t sz = EP_Read(2, (uint8_t*)buf);
if(sz){ if(sz){
if(RB_write((ringbuffer*)&in, buf, sz) != sz) bufovrfl = 1; if(RB_write((ringbuffer*)&in, buf, sz) != sz) bufovrfl = 1;
} }

View File

@ -27,6 +27,9 @@
#define newline() USB_putbyte('\n') #define newline() USB_putbyte('\n')
#define USND(s) do{USB_sendstr(s); USB_putbyte('\n');}while(0) #define USND(s) do{USB_sendstr(s); USB_putbyte('\n');}while(0)
#define STR_HELPER(s) #s
#define STR(s) STR_HELPER(s)
#ifdef EBUG #ifdef EBUG
#define DBG(str) do{USB_sendstr(__FILE__ " (L" STR(__LINE__) "): " str);}while(0) #define DBG(str) do{USB_sendstr(__FILE__ " (L" STR(__LINE__) "): " str);}while(0)
#else #else

View File

@ -25,7 +25,6 @@ usb_dev_t USB_Dev;
static usb_LineCoding lineCoding = {115200, 0, 0, 8}; static usb_LineCoding lineCoding = {115200, 0, 0, 8};
config_pack_t setup_packet; config_pack_t setup_packet;
uint8_t ep0databuf[EP0DATABUF_SIZE]; uint8_t ep0databuf[EP0DATABUF_SIZE];
uint8_t ep0dbuflen = 0;
usb_LineCoding getLineCoding(){return lineCoding;} usb_LineCoding getLineCoding(){return lineCoding;}
@ -344,15 +343,24 @@ void EP0_Handler(){
* @param size - its size * @param size - its size
*/ */
void EP_WriteIRQ(uint8_t number, const uint8_t *buf, uint16_t size){ void EP_WriteIRQ(uint8_t number, const uint8_t *buf, uint16_t size){
uint8_t i;
if(size > endpoints[number].txbufsz) size = endpoints[number].txbufsz; if(size > endpoints[number].txbufsz) size = endpoints[number].txbufsz;
uint16_t N2 = (size + 1) >> 1; uint16_t N2 = (size + 1) >> 1;
// the buffer is 16-bit, so we should copy data as it would be uint16_t // the buffer is 16-bit, so we should copy data as it would be uint16_t
uint16_t *buf16 = (uint16_t *)buf; uint16_t *buf16 = (uint16_t *)buf;
#if defined USB1_16
// very bad: what if `size` is odd?
uint32_t *out = (uint32_t *)endpoints[number].tx_buf; uint32_t *out = (uint32_t *)endpoints[number].tx_buf;
for(i = 0; i < N2; ++i, ++out){ for(int i = 0; i < N2; ++i, ++out){
*out = buf16[i]; *out = buf16[i];
} }
#elif defined USB2_16
// use memcpy instead?
for(int i = 0; i < N2; i++){
endpoints[number].tx_buf[i] = buf16[i];
}
#else
#error "Define USB1_16 or USB2_16"
#endif
USB_BTABLE->EP[number].USB_COUNT_TX = size; USB_BTABLE->EP[number].USB_COUNT_TX = size;
} }
@ -374,16 +382,23 @@ void EP_Write(uint8_t number, const uint8_t *buf, uint16_t size){
* @param *buf - user array for data * @param *buf - user array for data
* @return amount of data read * @return amount of data read
*/ */
int EP_Read(uint8_t number, uint16_t *buf){ int EP_Read(uint8_t number, uint8_t *buf){
int sz = endpoints[number].rx_cnt; int sz = endpoints[number].rx_cnt;
if(!sz) return 0; if(!sz) return 0;
endpoints[number].rx_cnt = 0; endpoints[number].rx_cnt = 0;
#if defined USB1_16
int n = (sz + 1) >> 1; int n = (sz + 1) >> 1;
uint32_t *in = (uint32_t *)endpoints[number].rx_buf; uint32_t *in = (uint32_t*)endpoints[number].rx_buf;
if(n){ uint16_t *out = (uint16_t*)buf;
for(int i = 0; i < n; ++i, ++in) for(int i = 0; i < n; ++i, ++in)
buf[i] = *(uint16_t*)in; out[i] = *(uint16_t*)in;
} #elif defined USB2_16
// use memcpy instead?
for(int i = 0; i < sz; ++i)
buf[i] = endpoints[number].rx_buf[i];
#else
#error "Define USB1_16 or USB2_16"
#endif
return sz; return sz;
} }

View File

@ -128,7 +128,7 @@ typedef struct {
typedef struct{ typedef struct{
uint16_t *tx_buf; // transmission buffer address uint16_t *tx_buf; // transmission buffer address
uint16_t txbufsz; // transmission buffer size uint16_t txbufsz; // transmission buffer size
uint16_t *rx_buf; // reception buffer address uint8_t *rx_buf; // reception buffer address
void (*func)(); // endpoint action function void (*func)(); // endpoint action function
unsigned rx_cnt : 10; // received data counter unsigned rx_cnt : 10; // received data counter
} ep_t; } ep_t;
@ -167,13 +167,12 @@ extern usb_dev_t USB_Dev;
extern volatile uint8_t usbON; extern volatile uint8_t usbON;
extern config_pack_t setup_packet; extern config_pack_t setup_packet;
extern uint8_t ep0databuf[]; extern uint8_t ep0databuf[];
extern uint8_t ep0dbuflen;
void EP0_Handler(); void EP0_Handler();
void EP_WriteIRQ(uint8_t number, const uint8_t *buf, uint16_t size); void EP_WriteIRQ(uint8_t number, const uint8_t *buf, uint16_t size);
void EP_Write(uint8_t number, const uint8_t *buf, uint16_t size); void EP_Write(uint8_t number, const uint8_t *buf, uint16_t size);
int EP_Read(uint8_t number, uint16_t *buf); int EP_Read(uint8_t number, uint8_t *buf);
usb_LineCoding getLineCoding(); usb_LineCoding getLineCoding();
void linecoding_handler(usb_LineCoding *lc); void linecoding_handler(usb_LineCoding *lc);

View File

@ -61,12 +61,12 @@ int EP_Init(uint8_t number, uint8_t type, uint16_t txsz, uint16_t rxsz, void (*f
countrx = 31 + rxsz / 32; countrx = 31 + rxsz / 32;
} }
USB_BTABLE->EP[number].USB_ADDR_TX = lastaddr; USB_BTABLE->EP[number].USB_ADDR_TX = lastaddr;
endpoints[number].tx_buf = (uint16_t *)(USB_BTABLE_BASE + lastaddr*2); endpoints[number].tx_buf = (uint16_t *)(USB_BTABLE_BASE + lastaddr * ACCESSZ);
endpoints[number].txbufsz = txsz; endpoints[number].txbufsz = txsz;
lastaddr += txsz; lastaddr += txsz;
USB_BTABLE->EP[number].USB_COUNT_TX = 0; USB_BTABLE->EP[number].USB_COUNT_TX = 0;
USB_BTABLE->EP[number].USB_ADDR_RX = lastaddr; USB_BTABLE->EP[number].USB_ADDR_RX = lastaddr;
endpoints[number].rx_buf = (uint16_t *)(USB_BTABLE_BASE + lastaddr*2); endpoints[number].rx_buf = (uint8_t *)(USB_BTABLE_BASE + lastaddr * ACCESSZ);
lastaddr += rxsz; lastaddr += rxsz;
USB_BTABLE->EP[number].USB_COUNT_RX = countrx << 10; USB_BTABLE->EP[number].USB_COUNT_RX = countrx << 10;
endpoints[number].func = func; endpoints[number].func = func;
@ -101,12 +101,10 @@ void usb_lp_isr(){
if(USB->ISTR & USB_ISTR_DIR){ // OUT interrupt - receive data, CTR_RX==1 (if CTR_TX == 1 - two pending transactions: receive following by transmit) if(USB->ISTR & USB_ISTR_DIR){ // OUT interrupt - receive data, CTR_RX==1 (if CTR_TX == 1 - two pending transactions: receive following by transmit)
if(n == 0){ // control endpoint if(n == 0){ // control endpoint
if(epstatus & USB_EPnR_SETUP){ // setup packet -> copy data to conf_pack if(epstatus & USB_EPnR_SETUP){ // setup packet -> copy data to conf_pack
EP_Read(0, (uint16_t*)&setup_packet); EP_Read(0, (uint8_t*)&setup_packet);
ep0dbuflen = 0;
// interrupt handler will be called later // interrupt handler will be called later
}else if(epstatus & USB_EPnR_CTR_RX){ // data packet -> push received data to ep0databuf }else if(epstatus & USB_EPnR_CTR_RX){ // data packet -> push received data to ep0databuf
ep0dbuflen = endpoints[0].rx_cnt; EP_Read(0, (uint8_t*)&ep0databuf);
EP_Read(0, (uint16_t*)&ep0databuf);
} }
} }
} }

View File

@ -83,13 +83,28 @@ typedef struct {
__IO uint32_t BTABLE; __IO uint32_t BTABLE;
} USB_TypeDef; } USB_TypeDef;
// F303 D/E have 2x16 access scheme
typedef struct{ typedef struct{
#if defined USB2_16
__IO uint16_t USB_ADDR_TX;
__IO uint16_t USB_COUNT_TX;
__IO uint16_t USB_ADDR_RX;
__IO uint16_t USB_COUNT_RX;
#define ACCESSZ (1)
#define BUFTYPE uint8_t
#elif defined USB1_16
__IO uint32_t USB_ADDR_TX; __IO uint32_t USB_ADDR_TX;
__IO uint32_t USB_COUNT_TX; __IO uint32_t USB_COUNT_TX;
__IO uint32_t USB_ADDR_RX; __IO uint32_t USB_ADDR_RX;
__IO uint32_t USB_COUNT_RX; __IO uint32_t USB_COUNT_RX;
#define ACCESSZ (2)
#define BUFTYPE uint16_t
#else
#error "Define USB1_16 or USB2_16"
#endif
} USB_EPDATA_TypeDef; } USB_EPDATA_TypeDef;
typedef struct{ typedef struct{
__IO USB_EPDATA_TypeDef EP[STM32ENDPOINTS]; __IO USB_EPDATA_TypeDef EP[STM32ENDPOINTS];
} USB_BtableDef; } USB_BtableDef;

View File

@ -1,2 +1,2 @@
#define BUILD_NUMBER "1" #define BUILD_NUMBER "11"
#define BUILD_DATE "2023-02-04" #define BUILD_DATE "2023-02-07"

View File

@ -2,6 +2,6 @@
# MCU FAMILY # MCU FAMILY
FAMILY ?= F3 FAMILY ?= F3
# or __ARM_ARCH_7EM__ # or __ARM_ARCH_7EM__
ARMARCH = -D__ARM_ARCH_7M__ DEFINES += -D__ARM_ARCH_7M__
FP_FLAGS ?= -mfpu=fpv4-sp-d16 -mfloat-abi=hard -fsingle-precision-constant -mlittle-endian -DARM_MATH_CM4 FP_FLAGS ?= -mfpu=fpv4-sp-d16 -mfloat-abi=hard -fsingle-precision-constant -mlittle-endian -DARM_MATH_CM4
ASM_FLAGS ?= -mthumb -mcpu=cortex-m4 -march=armv7e-m ASM_FLAGS ?= -mthumb -mcpu=cortex-m4 -march=armv7e-m