Add SPI DMA Tx example

This commit is contained in:
eddyem
2019-12-03 20:15:05 +03:00
parent 864f8c58df
commit a1f0824cef
24 changed files with 3157 additions and 1613 deletions

Binary file not shown.

View File

@@ -55,6 +55,7 @@ void iwdg_setup(){
}
char *parse_cmd(char *buf){
IWDG->KR = IWDG_REFRESH;
if(buf[1] != '\n') return buf;
switch(*buf){
case 'p':

View File

@@ -53,7 +53,10 @@ int usart_getline(char **line){
// transmit current tbuf and swap buffers
void transmit_tbuf(){
uint32_t tmout = 16000000;
while(!txrdy){if(--tmout == 0) return;}; // wait for previos buffer transmission
while(!txrdy){ // wait for previos buffer transmission
IWDG->KR = IWDG_REFRESH;
if(--tmout == 0) return;
}
register int l = odatalen[tbufno];
if(!l) return;
txrdy = 0;
@@ -109,7 +112,10 @@ void usart_setup(){
// setup usart1
USART1->BRR = 72000000 / 115200;
USART1->CR1 = USART_CR1_TE | USART_CR1_RE | USART_CR1_UE; // 1start,8data,nstop; enable Rx,Tx,USART
while(!(USART1->SR & USART_SR_TC)){if(--tmout == 0) break;} // polling idle frame Transmission
while(!(USART1->SR & USART_SR_TC)){ // polling idle frame Transmission
IWDG->KR = IWDG_REFRESH;
if(--tmout == 0) break;
}
USART1->SR = 0; // clear flags
USART1->CR1 |= USART_CR1_RXNEIE; // allow Rx IRQ
USART1->CR3 = USART_CR3_DMAT; // enable DMA Tx

View File

@@ -58,11 +58,11 @@ static uint16_t EP23_Handler(ep_t ep){
}
}
// end of transaction: clear DTOGs
ep.status = CLEAR_DTOG_RX(ep.status);
ep.status = CLEAR_DTOG_TX(ep.status);
ep.status = SET_STALL_TX(ep.status);
//ep.status = CLEAR_DTOG_RX(ep.status);
//ep.status = CLEAR_DTOG_TX(ep.status);
//ep.status = SET_STALL_TX(ep.status);
}else if (ep.tx_flag){
ep.status = KEEP_STAT_TX(ep.status);
//ep.status = KEEP_STAT_TX(ep.status);
tx_succesfull = 1;
}
ep.status = SET_VALID_RX(ep.status);
@@ -81,21 +81,21 @@ void USB_setup(){
USB->ISTR = 0;
USB->CNTR = USB_CNTR_RESETM | USB_CNTR_WKUPM; // allow only wakeup & reset interrupts
NVIC_EnableIRQ(USB_LP_CAN1_RX0_IRQn);
NVIC_EnableIRQ(USB_HP_CAN1_TX_IRQn );
//NVIC_EnableIRQ(USB_HP_CAN1_TX_IRQn );
}
void usb_proc(){
switch(USB_Dev.USB_Status){
case USB_CONFIGURE_STATE:
case USB_STATE_CONFIGURED:
// make new BULK endpoint
// Buffer have 1024 bytes, but last 256 we use for CAN bus (30.2 of RM: USB main features)
EP_Init(1, EP_TYPE_INTERRUPT, USB_EP1BUFSZ, 0, EP1_Handler); // IN1 - transmit
EP_Init(2, EP_TYPE_BULK, 0, USB_RXBUFSZ, EP23_Handler); // OUT2 - receive data
EP_Init(3, EP_TYPE_BULK, USB_TXBUFSZ, 0, EP23_Handler); // IN3 - transmit data
USB_Dev.USB_Status = USB_CONNECTED_STATE;
USB_Dev.USB_Status = USB_STATE_CONNECTED;
break;
case USB_DEFAULT_STATE:
case USB_ADRESSED_STATE:
case USB_STATE_DEFAULT:
case USB_STATE_ADDRESSED:
usbON = 0;
default:
return;
@@ -112,8 +112,10 @@ void USB_send(const char *buf){
tx_succesfull = 0;
EP_Write(3, (uint8_t*)&buf[ctr], s);
uint32_t ctra = 1000000;
while(--ctra && tx_succesfull == 0);
if(tx_succesfull == 0){usbON = 0; DBG("USB disconnected"); return;} // usb is OFF?
while(--ctra && tx_succesfull == 0){
IWDG->KR = IWDG_REFRESH;
}
if(tx_succesfull == 0){usbON = 0; DBG("USB transfer error"); return;} // usb is OFF?
l -= s;
ctr += s;
}

View File

@@ -54,13 +54,14 @@ static const uint8_t USB_DeviceDescriptor[] = {
bDeviceSubClass, // bDeviceSubClass
bDeviceProtocol, // bDeviceProtocol
USB_EP0_BUFSZ, // bMaxPacketSize
/* 0x1915, 0x520f
0x15, 0x19, 0x0f, 0x52,*/
// 0483:5740
0x83, 0x04, 0x40, 0x57,
/*
0xae, // idVendor_L VID=0x25AE, PID=0x24AB
0x25, // idVendor_H
0xab, // idProduct_L
0x24, // idProduct_H
*/
0x00, // bcdDevice_Ver_L
0x01, // bcdDevice_Ver_H
0x01, // iManufacturer
@@ -175,10 +176,10 @@ static const uint8_t USB_ConfigDescriptor[] = {
};
_USB_LANG_ID_(USB_StringLangDescriptor, LANG_US);
_USB_STRING_(USB_StringSerialDescriptor, u"000001");
_USB_STRING_(USB_StringManufacturingDescriptor, u"Eddy @ SAO RAS");
_USB_STRING_(USB_StringProdDescriptor, u"USB-Serial Controller");
USB_LANG_ID(USB_StringLangDescriptor, LANG_US);
USB_STRING(USB_StringSerialDescriptor, u"000001");
USB_STRING(USB_StringManufacturingDescriptor, u"Eddy @ SAO RAS");
USB_STRING(USB_StringProdDescriptor, u"USB-Serial Controller");
/*
@@ -210,16 +211,16 @@ static uint16_t wr0(const uint8_t *buf, uint16_t size, uint16_t status){
size -= l;
uint8_t needzlp = (l == endpoints[0].txbufsz) ? 1 : 0;
if(size || needzlp){ // send last data buffer
status = SET_NAK_RX(status);
USB->ISTR = 0;
//status = SET_NAK_RX(status);
status = SET_VALID_TX(status);
status = KEEP_DTOG_TX(status);
status = KEEP_DTOG_RX(status);
status = CLEAR_CTR_RX(status);
status = CLEAR_CTR_TX(status);
USB->ISTR = 0;
USB->EPnR[0] = status;
uint32_t ctr = 1000000;
while(--ctr && (USB->ISTR & USB_ISTR_CTR) == 0);
while(--ctr && (USB->ISTR & USB_ISTR_CTR) == 0){IWDG->KR = IWDG_REFRESH;};
if((USB->ISTR & USB_ISTR_CTR) == 0){
return USB->EPnR[0];
}
@@ -255,6 +256,7 @@ static inline uint16_t get_descriptor(uint16_t status){
status = wr0(USB_DeviceQualifierDescriptor, USB_DeviceQualifierDescriptor[0], status);
break;
default:
DBG("WTF?");
break;
}
return status;
@@ -274,6 +276,7 @@ static inline uint16_t std_d2h_req(uint16_t status){
EP_WriteIRQ(0, &configuration, 1);
break;
default:
DBG("WTF?");
break;
}
return status;
@@ -287,10 +290,11 @@ static inline void std_h2d_req(){
break;
case SET_CONFIGURATION:
// Now device configured
USB_Dev.USB_Status = USB_CONFIGURE_STATE;
USB_Dev.USB_Status = USB_STATE_CONFIGURED;
configuration = setup_packet.wValue;
break;
default:
DBG("WTF?");
break;
}
}
@@ -319,13 +323,13 @@ static uint16_t EP0_Handler(ep_t ep){
std_h2d_req();
EP_WriteIRQ(0, (uint8_t *)0, 0);
}
epstatus = SET_NAK_RX(epstatus);
//epstatus = SET_NAK_RX(epstatus);
epstatus = SET_VALID_TX(epstatus);
break;
case STANDARD_ENDPOINT_REQUEST_TYPE: // standard endpoint request
if(setup_packet.bRequest == CLEAR_FEATURE){
EP_WriteIRQ(0, (uint8_t *)0, 0);
epstatus = SET_NAK_RX(epstatus);
//epstatus = SET_NAK_RX(epstatus);
epstatus = SET_VALID_TX(epstatus);
}
break;
@@ -344,6 +348,7 @@ static uint16_t EP0_Handler(ep_t ep){
break_handler();
break;
default:
DBG("WTF?");
break;
}
//if(!dev2host) EP_WriteIRQ(0, (uint8_t *)0, 0); // write acknowledgement
@@ -353,6 +358,7 @@ static uint16_t EP0_Handler(ep_t ep){
break;
default:
EP_WriteIRQ(0, (uint8_t *)0, 0);
DBG("WTF?");
epstatus = SET_NAK_RX(epstatus);
epstatus = SET_VALID_TX(epstatus);
}
@@ -363,8 +369,8 @@ static uint16_t EP0_Handler(ep_t ep){
}
}
// Close transaction
epstatus = CLEAR_DTOG_RX(epstatus);
epstatus = CLEAR_DTOG_TX(epstatus);
//epstatus = CLEAR_DTOG_RX(epstatus);
//epstatus = CLEAR_DTOG_TX(epstatus);
// wait for new data from host
epstatus = SET_VALID_RX(epstatus);
epstatus = SET_STALL_TX(epstatus);
@@ -373,11 +379,11 @@ static uint16_t EP0_Handler(ep_t ep){
if ((USB->DADDR & USB_DADDR_ADD) != USB_Dev.USB_Addr){
USB->DADDR = USB_DADDR_EF | USB_Dev.USB_Addr;
// change state to ADRESSED
USB_Dev.USB_Status = USB_ADRESSED_STATE;
USB_Dev.USB_Status = USB_STATE_ADDRESSED;
}
// end of transaction
epstatus = CLEAR_DTOG_RX(epstatus);
epstatus = CLEAR_DTOG_TX(epstatus);
//epstatus = CLEAR_DTOG_RX(epstatus);
//epstatus = CLEAR_DTOG_TX(epstatus);
epstatus = SET_VALID_RX(epstatus);
epstatus = SET_VALID_TX(epstatus);
}
@@ -422,23 +428,23 @@ int EP_Init(uint8_t number, uint8_t type, uint16_t txsz, uint16_t rxsz, uint16_t
//extern int8_t dump;
// standard IRQ handler
void usb_isr(){
void usb_lp_can_rx0_isr(){
if (USB->ISTR & USB_ISTR_RESET){
usbON = 0;
// Reinit registers
USB->CNTR = USB_CNTR_RESETM | USB_CNTR_CTRM;// | USB_CNTR_SUSPM;
USB->ISTR = 0;
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;
// clear address, leave only enable bit
USB->DADDR = USB_DADDR_EF;
// state is default - wait for enumeration
USB_Dev.USB_Status = USB_DEFAULT_STATE;
USB_Dev.USB_Status = USB_STATE_DEFAULT;
if(EP_Init(0, EP_TYPE_CONTROL, USB_EP0_BUFSZ, USB_EP0_BUFSZ, EP0_Handler)){
return;
}
}else if(USB->ISTR & USB_ISTR_CTR){
}
if(USB->ISTR & USB_ISTR_CTR){
// EP number
uint8_t n = USB->ISTR & USB_ISTR_EPID;
// copy status register
@@ -477,20 +483,13 @@ void usb_isr(){
epstatus = CLEAR_CTR_TX(epstatus);
// refresh EPnR
USB->EPnR[n] = epstatus;
}else if(USB->ISTR & USB_ISTR_SUSP){ // suspend -> usb disconnected
// usbON = 0;
}
if(USB->ISTR & USB_ISTR_SUSP){ // suspend -> still no connection, may sleep
usbON = 0;
}
USB->ISTR = 0;
}
void usb_lp_can_rx0_isr(){
usb_isr();
}
void usb_hp_can_tx_isr(){
usb_isr();
}
/**
* Write data to EP buffer (called from IRQ handler)
* @param number - EP number
@@ -519,7 +518,7 @@ 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){
uint16_t status = USB->EPnR[number];
EP_WriteIRQ(number, buf, size);
status = SET_NAK_RX(status);
//status = SET_NAK_RX(status);
status = SET_VALID_TX(status);
status = KEEP_DTOG_TX(status);
status = KEEP_DTOG_RX(status);

View File

@@ -100,10 +100,12 @@
#define CLEAR_CTR_RX_TX(R) (R & (~(USB_EPnR_CTR_TX | USB_EPnR_CTR_RX)))
// USB state: uninitialized, addressed, ready for use
#define USB_DEFAULT_STATE 0
#define USB_ADRESSED_STATE 1
#define USB_CONFIGURE_STATE 2
#define USB_CONNECTED_STATE 3
typedef enum{
USB_STATE_DEFAULT,
USB_STATE_ADDRESSED,
USB_STATE_CONFIGURED,
USB_STATE_CONNECTED
} USB_state;
// EP types
#define EP_TYPE_BULK 0x00
@@ -113,7 +115,7 @@
#define LANG_US (uint16_t)0x0409
#define _USB_STRING_(name, str) \
#define USB_STRING(name, str) \
static const struct name \
{ \
uint8_t bLength; \
@@ -123,7 +125,7 @@ static const struct name \
} \
name = {sizeof(name), 0x03, str}
#define _USB_LANG_ID_(name, lng_id) \
#define USB_LANG_ID(name, lng_id) \
\
static const struct name \
{ \