mirror of
https://github.com/eddyem/stm32samples.git
synced 2025-12-06 18:55:13 +03:00
works, but still have a lot of bugzzz
This commit is contained in:
parent
3c7687bb0e
commit
7fa84cb0ef
Binary file not shown.
@ -69,7 +69,7 @@ void parse_cmd(const char *buf){
|
||||
uint32_t Num = 0;
|
||||
const char *nxt;
|
||||
char cmd = *buf++;
|
||||
if(cmd > '0'+CMD_EPNO && cmd <= '0'+DBG_EPNO){ // send data to iface
|
||||
if(cmd > '0'+CMD_EPNO && cmd <= '0'+MAX_EPNO){ // send data to iface
|
||||
cmd -= '1';
|
||||
if(USBON(cmd)){
|
||||
SENDN("OK");
|
||||
|
||||
@ -23,10 +23,12 @@
|
||||
#ifdef EBUG
|
||||
#define DBG(str) do{USB_sendstr(DBG_IDX, __FILE__ " (L" STR(__LINE__) "): " str); newline(DBG_IDX);}while(0)
|
||||
#define DBGmesg(str) do{USB_sendstr(DBG_IDX, str);}while(0)
|
||||
#define DBGmesgn(str,n) do{USB_send(DBG_IDX, str, n);}while(0)
|
||||
#define DBGnl() newline(DBG_IDX)
|
||||
#else
|
||||
#define DBG(str)
|
||||
#define DBGmesg(str)
|
||||
#define DBGmesgn(str,n)
|
||||
#define DBGnl()
|
||||
#endif
|
||||
|
||||
|
||||
@ -32,7 +32,7 @@ void sys_tick_handler(void){
|
||||
}
|
||||
|
||||
static const char *ebufovr = "ERROR: USB buffer overflow or string was too long\n";
|
||||
static const char *idxnames[MAX_IDX] = {"CMD", "USART1", "USART2", "USART3", "NOFUNCT", "CAN", "DBG"};
|
||||
static const char *idxnames[MAX_IDX] = {"CMD", "DBG", "USART1", "USART2", "USART3", "NOFUNCT", "CAN"};
|
||||
|
||||
int main(void){
|
||||
char inbuff[MAXSTRLEN+1];
|
||||
@ -68,10 +68,6 @@ int main(void){
|
||||
USB_sendstr(DBG_IDX, "> ");
|
||||
USB_sendstr(DBG_IDX, inbuff);
|
||||
USB_putbyte(DBG_IDX, '\n');
|
||||
USB_sendstr(CMD_IDX, idxnames[i]);
|
||||
USB_sendstr(CMD_IDX, "> ");
|
||||
USB_sendstr(CMD_IDX, inbuff);
|
||||
USB_putbyte(CMD_IDX, '\n');
|
||||
switch(i){
|
||||
case CMD_IDX:
|
||||
parse_cmd(inbuff);
|
||||
|
||||
Binary file not shown.
@ -17,7 +17,9 @@
|
||||
*/
|
||||
|
||||
#include "stm32f3.h"
|
||||
#include "debug.h"
|
||||
#include "hardware.h"
|
||||
#include "strfunc.h"
|
||||
#include "usart.h"
|
||||
#include "usb.h"
|
||||
#include <string.h>
|
||||
@ -31,12 +33,12 @@ volatile int linerdy = 0, // received data ready
|
||||
bufovr = 0; // input buffer overfull
|
||||
// USARTs speeds
|
||||
static usb_LineCoding lineCodings[USARTSNO+1] = {
|
||||
{115200, USB_CDC_1_STOP_BITS, USB_CDC_NO_PARITY, 8}, {0}};
|
||||
{9600, USB_CDC_1_STOP_BITS, USB_CDC_NO_PARITY, 8}, {0}};
|
||||
|
||||
usb_LineCoding *getLineCoding(int ifNo){
|
||||
int usartNo = ifNo - USART1_EPNO + 1;
|
||||
if(usartNo < 1 || usartNo > USARTSNO) return lineCodings;
|
||||
return & lineCodings[usartNo];
|
||||
return &lineCodings[usartNo];
|
||||
// TODO: fixme for different settings
|
||||
//lineCoding.dwDTERate = speeds[usartNo];
|
||||
//lineCoding.bCharFormat = USB_CDC_1_STOP_BITS;
|
||||
@ -44,14 +46,14 @@ usb_LineCoding *getLineCoding(int ifNo){
|
||||
//lineCoding.bDataBits = 8;
|
||||
}
|
||||
|
||||
void usart_putchar(uint8_t ch){
|
||||
while(!(USART1->ISR & USART_ISR_TXE));
|
||||
USART1->TDR = ch;
|
||||
static void usart_putchar(int no, uint8_t ch){
|
||||
while(!(USARTx[no]->ISR & USART_ISR_TXE));
|
||||
USARTx[no]->TDR = ch;
|
||||
}
|
||||
void usart_sendn(const uint8_t *str, int L){
|
||||
if(!str || L < 0) return;
|
||||
void usart_sendn(int no, const uint8_t *str, int L){
|
||||
if(!str || L < 0 || no < 1 || no > USARTSNO) return;
|
||||
for(int i = 0; i < L; ++i){
|
||||
usart_putchar(str[i]);
|
||||
usart_putchar(no, str[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -60,17 +62,21 @@ void usarts_setup(){
|
||||
// clock
|
||||
RCC->APB1ENR |= RCC_APB1ENR_USART2EN | RCC_APB1ENR_USART3EN;
|
||||
RCC->APB2ENR |= RCC_APB2ENR_USART1EN;
|
||||
for(int i = USART1_IDX; i <= USART3_IDX; ++i)
|
||||
usart_config(i, lineCodings);
|
||||
NVIC_EnableIRQ(USART1_IRQn);
|
||||
NVIC_EnableIRQ(USART2_IRQn);
|
||||
NVIC_EnableIRQ(USART3_IRQn);
|
||||
}
|
||||
|
||||
void usart_config(uint8_t ifNo, usb_LineCoding *lc){
|
||||
int usartNo = ifNo - USART1_EPNO + 1;
|
||||
int usartNo = ifNo - USART1_IDX + 1;
|
||||
if(usartNo < 1 || usartNo > USARTSNO) return;
|
||||
DBGmesg("setup USART"); DBGmesg(u2str(usartNo)); DBGnl();
|
||||
lineCodings[usartNo] = *lc;
|
||||
// FIXME: change also parity and so on
|
||||
volatile USART_TypeDef *U = USARTx[usartNo];
|
||||
U->CR1 = 0; // disable for reconfigure
|
||||
U->ICR = 0xffffffff; // clear all flags
|
||||
U->BRR = SysFreq / lc->dwDTERate;
|
||||
U->CR1 = USART_CR1_TE | USART_CR1_RE | USART_CR1_UE | USART_CR1_RXNEIE; // 1start,8data,nstop; enable Rx,Tx,USART
|
||||
@ -81,8 +87,25 @@ void usart_config(uint8_t ifNo, usb_LineCoding *lc){
|
||||
|
||||
void usart1_exti25_isr(){
|
||||
if(USART1->ISR & USART_ISR_RXNE){ // RX not emty - receive next char
|
||||
DBG("got\n");
|
||||
// read RDR clears flag
|
||||
uint8_t rb = USART1->RDR;
|
||||
USB_putbyte(1, rb);
|
||||
USB_putbyte(USART1_IDX, rb);
|
||||
}
|
||||
}
|
||||
|
||||
void usart2_exti26_isr(){
|
||||
if(USART2->ISR & USART_ISR_RXNE){
|
||||
DBG("got\n");
|
||||
uint8_t rb = USART2->RDR;
|
||||
USB_putbyte(USART2_IDX, rb);
|
||||
}
|
||||
}
|
||||
|
||||
void usart3_exti28_isr(){
|
||||
if(USART3->ISR & USART_ISR_RXNE){
|
||||
DBG("got\n");
|
||||
uint8_t rb = USART3->RDR;
|
||||
USB_putbyte(USART3_IDX, rb);
|
||||
}
|
||||
}
|
||||
|
||||
@ -30,7 +30,7 @@ extern volatile int linerdy, bufovr;
|
||||
|
||||
void usarts_setup();
|
||||
void usart_config(uint8_t ifNo, usb_LineCoding *lc);
|
||||
void usart_sendn(const uint8_t *str, int L);
|
||||
void usart_sendn(int no, const uint8_t *str, int L);
|
||||
usb_LineCoding *getLineCoding(int ifNo);
|
||||
|
||||
#endif // __USART_H__
|
||||
|
||||
@ -27,7 +27,7 @@ static volatile uint8_t usbbuff[USB_TRBUFSZ]; // temporary buffer for sending da
|
||||
static uint8_t obuf[WORK_EPs][RBOUTSZ], ibuf[WORK_EPs][RBINSZ];
|
||||
#define OBUF(N) {.data = obuf[N], .length = RBOUTSZ, .head = 0, .tail = 0}
|
||||
volatile ringbuffer rbout[WORK_EPs] = {OBUF(0), OBUF(1), OBUF(2), OBUF(3), OBUF(4), OBUF(5), OBUF(6)};
|
||||
#define IBUF(N) {.data = ibuf[N], .length = RBOUTSZ, .head = 0, .tail = 0}
|
||||
#define IBUF(N) {.data = ibuf[N], .length = RBINSZ, .head = 0, .tail = 0}
|
||||
volatile ringbuffer rbin[WORK_EPs] = {IBUF(0), IBUF(1), IBUF(2), IBUF(3), IBUF(4), IBUF(5), IBUF(6)};
|
||||
// transmission is succesfull
|
||||
volatile uint8_t bufisempty[WORK_EPs] = {1,1,1,1,1,1,1};
|
||||
@ -39,7 +39,7 @@ void send_next(int ifNo){
|
||||
static uint8_t lastdsz[WORK_EPs] = {0};
|
||||
int buflen = RB_read((ringbuffer*)&rbout[ifNo], (uint8_t*)usbbuff, USB_TRBUFSZ);
|
||||
if(!buflen){
|
||||
if(lastdsz[ifNo] == 64) EP_Write(ifNo+1, NULL, 0); // send ZLP after 64 bits packet when nothing more to send
|
||||
if(lastdsz[ifNo] == USB_TRBUFSZ) EP_Write(ifNo+1, NULL, 0); // send ZLP after 64 bits packet when nothing more to send
|
||||
lastdsz[ifNo] = 0;
|
||||
bufisempty[ifNo] = 1;
|
||||
return;
|
||||
@ -62,7 +62,7 @@ int USB_send(int ifNo, const uint8_t *buf, int len){
|
||||
uint32_t T = Tms;
|
||||
while(len){
|
||||
int a = RB_write((ringbuffer*)&rbout[ifNo], buf, len);
|
||||
if(a == 0 && Tms - T > 5){
|
||||
if(a == 0 && Tms - T > 5){ // buffer overflow && timeout -> interface disconnected
|
||||
usbON &= ~(1<<ifNo);
|
||||
bufisempty[ifNo] = 0;
|
||||
RB_clearbuf((ringbuffer*)&rbout[ifNo]);
|
||||
@ -80,11 +80,10 @@ int USB_send(int ifNo, const uint8_t *buf, int len){
|
||||
|
||||
int USB_putbyte(int ifNo, uint8_t byte){
|
||||
if(!USBON(ifNo)) return 0;
|
||||
while(0 == RB_write((ringbuffer*)&rbout[ifNo], &byte, 1)){
|
||||
if(bufisempty[ifNo]){
|
||||
bufisempty[ifNo] = 0;
|
||||
send_next(ifNo);
|
||||
}
|
||||
while(0 == RB_write((ringbuffer*)&rbout[ifNo], &byte, 1)) send_next(ifNo);
|
||||
if(bufisempty[ifNo]){
|
||||
bufisempty[ifNo] = 0;
|
||||
send_next(ifNo);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -35,16 +35,23 @@
|
||||
#define WORK_EPs 7
|
||||
// functional EPs
|
||||
#define CMD_EPNO 1
|
||||
#define USART1_EPNO 2
|
||||
#define USART2_EPNO 3
|
||||
#define USART3_EPNO 4
|
||||
#define CAN_EPNO 6
|
||||
#define DBG_EPNO 2
|
||||
#define USART1_EPNO 3
|
||||
#define USART2_EPNO 4
|
||||
#define USART3_EPNO 5
|
||||
#define USART4_EPNO 6
|
||||
#define CAN_EPNO 7
|
||||
#define MAX_EPNO 7
|
||||
|
||||
#define USARTMAX_EPNO USART3_EPNO
|
||||
// functional indexes
|
||||
#define CMD_IDX (CMD_EPNO-1)
|
||||
#define CAN_IDX (CAN_EPNO-1)
|
||||
#define DBG_IDX (DBG_EPNO-1)
|
||||
#define USART1_IDX (USART1_EPNO-1)
|
||||
#define USART2_IDX (USART2_EPNO-1)
|
||||
#define USART3_IDX (USART3_EPNO-1)
|
||||
#define USART4_IDX (USART4_EPNO-1)
|
||||
#define MAX_IDX 7
|
||||
|
||||
extern volatile ringbuffer rbout[], rbin[];
|
||||
|
||||
@ -18,9 +18,7 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include "debug.h"
|
||||
#ifdef EBUG
|
||||
#include "strfunc.h"
|
||||
#endif
|
||||
#include "usart.h"
|
||||
#include "usb.h"
|
||||
#include "usb_lib.h"
|
||||
@ -188,7 +186,7 @@ static const uint8_t USB_ConfigDescriptor[] = {
|
||||
0x02, /* bInterfaceClass: Communication Interface Class */
|
||||
0x02, /* bInterfaceSubClass: Abstract Control Model */
|
||||
0x00, /* bInterfaceProtocol */
|
||||
iINTERFACE_DESCR_USART1, /* iInterface: */
|
||||
iINTERFACE_DESCR_DBG, /* iInterface: */
|
||||
/*Header Functional Descriptor*/
|
||||
0x05, /* bLength: Endpoint Descriptor size */
|
||||
0x24, /* bDescriptorType: CS_INTERFACE */
|
||||
@ -269,7 +267,7 @@ static const uint8_t USB_ConfigDescriptor[] = {
|
||||
0x02, /* bInterfaceClass: Communication Interface Class */
|
||||
0x02, /* bInterfaceSubClass: Abstract Control Model */
|
||||
0x00, /* bInterfaceProtocol */
|
||||
iINTERFACE_DESCR_USART2, /* iInterface: */
|
||||
iINTERFACE_DESCR_USART1, /* iInterface: */
|
||||
/*Header Functional Descriptor*/
|
||||
0x05, /* bLength: Endpoint Descriptor size */
|
||||
0x24, /* bDescriptorType: CS_INTERFACE */
|
||||
@ -350,7 +348,7 @@ static const uint8_t USB_ConfigDescriptor[] = {
|
||||
0x02, /* bInterfaceClass: Communication Interface Class */
|
||||
0x02, /* bInterfaceSubClass: Abstract Control Model */
|
||||
0x00, /* bInterfaceProtocol */
|
||||
iINTERFACE_DESCR_USART3, /* iInterface: */
|
||||
iINTERFACE_DESCR_USART2, /* iInterface: */
|
||||
/*Header Functional Descriptor*/
|
||||
0x05, /* bLength: Endpoint Descriptor size */
|
||||
0x24, /* bDescriptorType: CS_INTERFACE */
|
||||
@ -430,8 +428,8 @@ static const uint8_t USB_ConfigDescriptor[] = {
|
||||
0x01, /* bNumEndpoints: One endpoints used */
|
||||
0x02, /* bInterfaceClass: Communication Interface Class */
|
||||
0x02, /* bInterfaceSubClass: Abstract Control Model */
|
||||
iINTERFACE_DESCR_USART4, /* bInterfaceProtocol */
|
||||
0x00, /* iInterface: */
|
||||
0x00, /* bInterfaceProtocol */
|
||||
iINTERFACE_DESCR_USART3, /* iInterface: */
|
||||
/*Header Functional Descriptor*/
|
||||
0x05, /* bLength: Endpoint Descriptor size */
|
||||
0x24, /* bDescriptorType: CS_INTERFACE */
|
||||
@ -512,7 +510,7 @@ static const uint8_t USB_ConfigDescriptor[] = {
|
||||
0x02, /* bInterfaceClass: Communication Interface Class */
|
||||
0x02, /* bInterfaceSubClass: Abstract Control Model */
|
||||
0x00, /* bInterfaceProtocol */
|
||||
iINTERFACE_DESCR_CAN, /* iInterface: */
|
||||
iINTERFACE_DESCR_USART4, /* iInterface: */
|
||||
/*Header Functional Descriptor*/
|
||||
0x05, /* bLength: Endpoint Descriptor size */
|
||||
0x24, /* bDescriptorType: CS_INTERFACE */
|
||||
@ -593,7 +591,7 @@ static const uint8_t USB_ConfigDescriptor[] = {
|
||||
0x02, /* bInterfaceClass: Communication Interface Class */
|
||||
0x02, /* bInterfaceSubClass: Abstract Control Model */
|
||||
0x00, /* bInterfaceProtocol */
|
||||
iINTERFACE_DESCR_DBG, /* iInterface: */
|
||||
iINTERFACE_DESCR_CAN, /* iInterface: */
|
||||
/*Header Functional Descriptor*/
|
||||
0x05, /* bLength: Endpoint Descriptor size */
|
||||
0x24, /* bDescriptorType: CS_INTERFACE */
|
||||
@ -673,12 +671,12 @@ static void const *StringDescriptor[iDESCR_AMOUNT] = {
|
||||
[iPRODUCT_DESCR] = &PD,
|
||||
[iSERIAL_DESCR] = &SD,
|
||||
[iINTERFACE_DESCR_CMD] = &ID0,
|
||||
[iINTERFACE_DESCR_DBG] = &ID6,
|
||||
[iINTERFACE_DESCR_USART1] = &ID1,
|
||||
[iINTERFACE_DESCR_USART2] = &ID2,
|
||||
[iINTERFACE_DESCR_USART3] = &ID3,
|
||||
[iINTERFACE_DESCR_USART4] = &ID4,
|
||||
[iINTERFACE_DESCR_CAN] = &ID5,
|
||||
[iINTERFACE_DESCR_DBG] = &ID6
|
||||
[iINTERFACE_DESCR_CAN] = &ID5
|
||||
};
|
||||
|
||||
static void wr0(const uint8_t *buf, uint16_t size){
|
||||
@ -760,9 +758,30 @@ static void rxtx_Handler(uint8_t epno){
|
||||
USB->EPnR[epno] = epstatus;
|
||||
//USB->EPnR[epno] = (KEEP_DTOG(epstatus) & ~USB_EPnR_CTR_RX) ^ USB_EPnR_STAT_RX;
|
||||
uint8_t sz = EP_Read(epno, (uint8_t*)buf);
|
||||
DBG("epno");
|
||||
DBGmesg(u2str(epno)); DBGmesg(" ("); DBGmesg(u2str(sz));
|
||||
DBGmesg(") > "); hexdump(DBG_IDX, buf, sz); DBGnl();
|
||||
if(sz){
|
||||
if(RB_write((ringbuffer*)&rbin[idx], buf, sz) != sz) bufovrfl[idx] = 1;
|
||||
switch(epno){
|
||||
case USART1_EPNO:
|
||||
usart_sendn(1, buf, sz);
|
||||
break;
|
||||
case USART2_EPNO:
|
||||
usart_sendn(2, buf, sz);
|
||||
break;
|
||||
case USART3_EPNO:
|
||||
usart_sendn(3, buf, sz);
|
||||
break;
|
||||
case USART4_EPNO:
|
||||
; // we have no USART4 in STM32F303CBT6
|
||||
break;
|
||||
default:
|
||||
if(RB_write((ringbuffer*)&rbin[idx], buf, sz) != sz) bufovrfl[idx] = 1;
|
||||
}
|
||||
}
|
||||
/*if(epno != DBG_EPNO){
|
||||
MSG();
|
||||
}*/
|
||||
// set ACK Rx
|
||||
USB->EPnR[epno] = (KEEP_DTOG(USB->EPnR[epno]) & ~(USB_EPnR_STAT_TX)) ^ USB_EPnR_STAT_RX;
|
||||
}else{
|
||||
@ -807,9 +826,13 @@ void EP0_Handler(uint8_t __attribute__((unused)) epno){
|
||||
usb_LineCoding *lc;
|
||||
// calculate iFno (EP number minus 1) by setup_packet->wIndex (bInterfaceNumber): iFno = wIndex >> 1
|
||||
int iFno = setup_packet->wIndex >> 1;
|
||||
DBGmesg(uhex2str(epstatus));
|
||||
DBGmesg(" - "); hexdump(DBG_IDX, (uint8_t*)setup_packet, sizeof(config_pack_t));
|
||||
if(iFno != DBG_IDX){
|
||||
DBGmesg(uhex2str(epstatus));
|
||||
DBGmesg(" ("); DBGmesg(u2str(iFno));
|
||||
DBGmesg(") - "); hexdump(DBG_IDX, (uint8_t*)setup_packet, sizeof(config_pack_t));
|
||||
}
|
||||
if(rxflag && SETUP_FLAG(epstatus)){
|
||||
if(iFno != DBG_IDX){DBGmesg("setup\n");}
|
||||
switch(reqtype){
|
||||
case STANDARD_DEVICE_REQUEST_TYPE: // standard device request
|
||||
if(dev2host){
|
||||
@ -827,24 +850,24 @@ void EP0_Handler(uint8_t __attribute__((unused)) epno){
|
||||
case CONTROL_REQUEST_TYPE:
|
||||
switch(setup_packet->bRequest){
|
||||
case GET_LINE_CODING:
|
||||
DBG("GLC");
|
||||
if(iFno != DBG_IDX){ DBG("GLC");}
|
||||
lc = getLineCoding(iFno);
|
||||
if(!lc) EP_WriteIRQ(0, (uint8_t *)0, 0);
|
||||
else EP_WriteIRQ(0, (uint8_t*)&lc, sizeof(usb_LineCoding));
|
||||
break;
|
||||
case SET_LINE_CODING: // omit this for next stage, when data will come
|
||||
DBG("SLC");
|
||||
if(iFno != DBG_IDX){ DBG("SLC");}
|
||||
break;
|
||||
case SET_CONTROL_LINE_STATE:
|
||||
DBG("SCLS");
|
||||
if(iFno != DBG_IDX){ DBG("SCLS");}
|
||||
usbON |= 1 << iFno; // now this interface is connected
|
||||
break;
|
||||
case SEND_BREAK:
|
||||
DBG("B");
|
||||
if(iFno != DBG_IDX){ DBG("B");}
|
||||
usbON &= ~(1<<iFno); // interface is disconnected
|
||||
break;
|
||||
default:
|
||||
DBG("U");
|
||||
if(iFno != DBG_IDX){ DBG("U");}
|
||||
break;
|
||||
}
|
||||
if(setup_packet->bRequest != GET_LINE_CODING) EP_WriteIRQ(0, (uint8_t *)0, 0); // write acknowledgement
|
||||
@ -853,11 +876,16 @@ void EP0_Handler(uint8_t __attribute__((unused)) epno){
|
||||
EP_WriteIRQ(0, (uint8_t *)0, 0);
|
||||
}
|
||||
}else if(rxflag){ // got data over EP0 or host acknowlegement
|
||||
if(endpoints[0].rx_cnt){
|
||||
if(setup_packet->bRequest == SET_LINE_CODING){
|
||||
usart_config(iFno + 1 - USART1_EPNO, (usb_LineCoding*)ep0databuf);
|
||||
}
|
||||
}
|
||||
if(iFno != DBG_IDX){ DBGmesg("rxflag\n");}
|
||||
//if(endpoints[0].rx_cnt){
|
||||
// if(setup_packet->bRequest == SET_LINE_CODING){
|
||||
if(iFno != DBG_IDX){
|
||||
DBGmesg("USART"); DBGmesg(u2str(iFno + 2 - USART1_EPNO));
|
||||
DBGmesg(" speed = "); DBGmesg(u2str(((usb_LineCoding*)ep0databuf)->dwDTERate)); DBGnl();
|
||||
}
|
||||
usart_config(iFno, (usb_LineCoding*)ep0databuf);
|
||||
// }
|
||||
//}
|
||||
} else if(TX_FLAG(epstatus)){ // package transmitted
|
||||
// now we can change address after enumeration
|
||||
if ((USB->DADDR & USB_DADDR_ADD) != USB_Addr){
|
||||
|
||||
@ -67,12 +67,12 @@ enum{
|
||||
iPRODUCT_DESCR,
|
||||
iSERIAL_DESCR,
|
||||
iINTERFACE_DESCR_CMD,
|
||||
iINTERFACE_DESCR_DBG,
|
||||
iINTERFACE_DESCR_USART1,
|
||||
iINTERFACE_DESCR_USART2,
|
||||
iINTERFACE_DESCR_USART3,
|
||||
iINTERFACE_DESCR_USART4,
|
||||
iINTERFACE_DESCR_CAN,
|
||||
iINTERFACE_DESCR_DBG,
|
||||
iDESCR_AMOUNT
|
||||
};
|
||||
|
||||
|
||||
@ -16,6 +16,7 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "debug.h"
|
||||
#include "usb.h"
|
||||
#include "usb_lib.h"
|
||||
|
||||
@ -33,7 +34,7 @@ void USB_setup(){
|
||||
USB->BTABLE = 0;
|
||||
USB->DADDR = 0;
|
||||
USB->ISTR = 0;
|
||||
USB->CNTR = USB_CNTR_RESETM | USB_CNTR_WKUPM; // allow only wakeup & reset interrupts
|
||||
USB->CNTR = USB_CNTR_RESETM;// | USB_CNTR_WKUPM; // allow only wakeup & reset interrupts
|
||||
NVIC_EnableIRQ(USB_LP_IRQn);
|
||||
}
|
||||
|
||||
@ -50,11 +51,11 @@ static uint16_t lastaddr = LASTADDR_DEFAULT;
|
||||
int EP_Init(uint8_t number, uint8_t type, uint16_t txsz, uint16_t rxsz, void (*func)(uint8_t epno)){
|
||||
if(number >= STM32ENDPOINTS) return 4; // out of configured amount
|
||||
if(txsz > USB_BTABLE_SIZE || rxsz > USB_BTABLE_SIZE) return 1; // buffer too large
|
||||
if(lastaddr + txsz + rxsz >= USB_BTABLE_SIZE) return 2; // out of btable
|
||||
if(lastaddr + txsz + rxsz >= USB_BTABLE_SIZE/ACCESSZ) return 2; // out of btable
|
||||
USB->EPnR[number] = (type << 9) | (number & USB_EPnR_EA);
|
||||
USB->EPnR[number] ^= USB_EPnR_STAT_RX | USB_EPnR_STAT_TX_1;
|
||||
if(rxsz & 1 || rxsz > 512) return 3; // wrong rx buffer size
|
||||
uint16_t countrx = 0;
|
||||
if(rxsz & 1 || rxsz > USB_BTABLE_SIZE) return 3; // wrong rx buffer size
|
||||
uint16_t countrx = 0; // BLSIZE:NUM_BLOCKS[4:0]
|
||||
if(rxsz < 64) countrx = rxsz / 2;
|
||||
else{
|
||||
if(rxsz & 0x1f) return 3; // should be multiple of 32
|
||||
@ -73,13 +74,17 @@ int EP_Init(uint8_t number, uint8_t type, uint16_t txsz, uint16_t rxsz, void (*f
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint8_t oldusbon = 0; // to store flags while suspended
|
||||
|
||||
// standard IRQ handler
|
||||
void usb_lp_isr(){
|
||||
static uint8_t oldusbon = 0; // to store flags while suspended
|
||||
// EP number
|
||||
uint8_t n = USB->ISTR & USB_ISTR_EPID;
|
||||
//if(n && n != DBG_EPNO) DBG("ISR\n");
|
||||
if(USB->ISTR & USB_ISTR_RESET){
|
||||
usbON = 0;
|
||||
// Reinit registers
|
||||
USB->CNTR = USB_CNTR_RESETM | USB_CNTR_CTRM | USB_CNTR_SUSPM | USB_CNTR_WKUPM;
|
||||
USB->CNTR = USB_CNTR_RESETM | USB_CNTR_CTRM | USB_CNTR_SUSPM;
|
||||
// Endpoint 0 - CONTROL
|
||||
// ON USB LS size of EP0 may be 8 bytes, but on FS it should be 64 bytes!
|
||||
lastaddr = LASTADDR_DEFAULT;
|
||||
@ -91,8 +96,6 @@ void usb_lp_isr(){
|
||||
USB->ISTR = ~USB_ISTR_RESET;
|
||||
}
|
||||
if(USB->ISTR & USB_ISTR_CTR){
|
||||
// EP number
|
||||
uint8_t n = USB->ISTR & USB_ISTR_EPID;
|
||||
// copy status register
|
||||
uint16_t epstatus = USB->EPnR[n];
|
||||
// copy received bytes amount
|
||||
@ -101,9 +104,11 @@ 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(n == 0){ // control endpoint
|
||||
if(epstatus & USB_EPnR_SETUP){ // setup packet -> copy data to conf_pack
|
||||
DBG("setup\n");
|
||||
EP_Read(0, setupdatabuf);
|
||||
// interrupt handler will be called later
|
||||
}else if(epstatus & USB_EPnR_CTR_RX){ // data packet -> push received data to ep0databuf
|
||||
DBG("data\n");
|
||||
EP_Read(0, ep0databuf);
|
||||
}
|
||||
}
|
||||
@ -112,15 +117,25 @@ void usb_lp_isr(){
|
||||
if(endpoints[n].func) endpoints[n].func(n);
|
||||
}
|
||||
if(USB->ISTR & USB_ISTR_SUSP){ // suspend -> still no connection, may sleep
|
||||
DBG("susp");
|
||||
oldusbon = usbON;
|
||||
usbON = 0;
|
||||
USB->CNTR |= USB_CNTR_FSUSP | USB_CNTR_LP_MODE;
|
||||
USB->ISTR = ~USB_ISTR_SUSP;
|
||||
}
|
||||
if(USB->ISTR & USB_ISTR_WKUP){ // wakeup
|
||||
DBG("wkup");
|
||||
USB->CNTR &= ~(USB_CNTR_FSUSP | USB_CNTR_LP_MODE); // clear suspend flags
|
||||
USB->ISTR = ~USB_ISTR_WKUP;
|
||||
usbON = oldusbon;
|
||||
}
|
||||
}
|
||||
|
||||
void usb_wkup_isr(){
|
||||
DBG("wkup");
|
||||
if(USB->ISTR & USB_ISTR_WKUP){ // wakeup
|
||||
USB->CNTR &= ~(USB_CNTR_FSUSP | USB_CNTR_LP_MODE); // clear suspend flags
|
||||
USB->ISTR = ~USB_ISTR_WKUP;
|
||||
usbON = oldusbon;
|
||||
}
|
||||
}
|
||||
|
||||
@ -25,13 +25,14 @@
|
||||
/**
|
||||
* Buffers size definition
|
||||
**/
|
||||
#define USB_BTABLE_SIZE 768
|
||||
// first 64 bytes of USB_BTABLE are registers!
|
||||
#define USB_BTABLE_SIZE 512
|
||||
// first 64*ACCESSZ bytes of USB_BTABLE are registers!
|
||||
//#define USB_EP0_BASEADDR 64
|
||||
// for USB FS EP0 buffers are from 8 to 64 bytes long
|
||||
// For STM32F303CBT6 ACCESSZ=2, so real available buffers size for all EPs = only 192 bytes (128 - EP0)
|
||||
#define USB_EP0_BUFSZ 64
|
||||
// USB transmit/receive buffer size
|
||||
#define USB_TRBUFSZ 64
|
||||
#define USB_TRBUFSZ 4
|
||||
// EP1 - interrupt - buffer size
|
||||
#define USB_EP1BUFSZ 8
|
||||
|
||||
|
||||
@ -1,2 +1,2 @@
|
||||
#define BUILD_NUMBER "77"
|
||||
#define BUILD_DATE "2023-04-26"
|
||||
#define BUILD_NUMBER "102"
|
||||
#define BUILD_DATE "2023-04-29"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user