- USB driver: TX FIFO overpushing fixed
- USB driver: TX FIFO allocated address must be in WORDs (fixed)
This commit is contained in:
		
							parent
							
								
									8ef6249e01
								
							
						
					
					
						commit
						db4e59cfd9
					
				@ -8,6 +8,8 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include <blocking_io/blocking_fifo.h>
 | 
					#include <blocking_io/blocking_fifo.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <cmsis_gcc.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// state
 | 
					// state
 | 
				
			||||||
static USB_CdcState cdcs = { 0 };
 | 
					static USB_CdcState cdcs = { 0 };
 | 
				
			||||||
static uint8_t tx_buffer[USB_CDC_PCKT_BUFSIZE];
 | 
					static uint8_t tx_buffer[USB_CDC_PCKT_BUFSIZE];
 | 
				
			||||||
 | 
				
			|||||||
@ -62,7 +62,7 @@ typedef struct {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// ----------------
 | 
					// ----------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define USB_CDC_PCKT_BUFSIZE (64)
 | 
					#define USB_CDC_PCKT_BUFSIZE (72)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// ----------------
 | 
					// ----------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										26
									
								
								usb_driver.c
									
									
									
									
									
								
							
							
						
						
									
										26
									
								
								usb_driver.c
									
									
									
									
									
								
							@ -265,10 +265,10 @@ void usbdrv_build_fifo() {
 | 
				
			|||||||
    for (uint8_t i = 0; i < USB_NUM_OF_ENDPOINTS; i++) {
 | 
					    for (uint8_t i = 0; i < USB_NUM_OF_ENDPOINTS; i++) {
 | 
				
			||||||
        USBDRV_EpConfig *cfg = &gs.ep_IN[i];
 | 
					        USBDRV_EpConfig *cfg = &gs.ep_IN[i];
 | 
				
			||||||
        if (cfg->is_configured) {
 | 
					        if (cfg->is_configured) {
 | 
				
			||||||
            cfg->fifo_size = CEIL4(MAX(USB_MIN_GROSS_TX_FIFO_SIZE, cfg->max_packet_size)); // correct FIFO size if necessary
 | 
					            cfg->fifo_size = CEIL4(MAX(USB_MIN_GROSS_TX_FIFO_SIZE, 2 * cfg->max_packet_size + USB_FIFO_MARGIN)); // correct FIFO size if necessary
 | 
				
			||||||
            cfg->fifo_address = next_fifo_addr;                                            // store FIFO address
 | 
					            cfg->fifo_address = next_fifo_addr;                                                                  // store FIFO address
 | 
				
			||||||
            cfg->zlp_next = false;                                                         // clear ZLP next
 | 
					            cfg->zlp_next = false;                                                                               // clear ZLP next
 | 
				
			||||||
            next_fifo_addr += cfg->fifo_size;                                              // advance next address
 | 
					            next_fifo_addr += cfg->fifo_size;                                                                    // advance next address
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -346,8 +346,8 @@ void usbdrv_configure_endpoint(uint8_t ep, uint8_t dir, const USBDRV_EpConfig *c
 | 
				
			|||||||
        WRITE_FIELD(USBINEP[ep].DIEPCTL, USB_OTG_DIEPCTL_TXFNUM, ep);
 | 
					        WRITE_FIELD(USBINEP[ep].DIEPCTL, USB_OTG_DIEPCTL_TXFNUM, ep);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // store Tx FIFO size
 | 
					        // store Tx FIFO size
 | 
				
			||||||
        uint32_t tx_fifo_config = ((cfg->fifo_size >> 2) << USB_OTG_DIEPTXF_INEPTXFD_Pos) | cfg->fifo_address; // combine size in DWORDs and address
 | 
					        uint32_t tx_fifo_config = ((cfg->fifo_size >> 2) << USB_OTG_DIEPTXF_INEPTXFD_Pos) | (cfg->fifo_address >> 2); // combine size in DWORDs and address
 | 
				
			||||||
        *(USB_pDIEPTXF[ep]) = tx_fifo_config;                                                                  // save
 | 
					        *(USB_pDIEPTXF[ep]) = tx_fifo_config;                                                                         // save
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // enable interrupt
 | 
					        // enable interrupt
 | 
				
			||||||
        SET_BIT(USBD->DAINTMSK, 1 << ep);
 | 
					        SET_BIT(USBD->DAINTMSK, 1 << ep);
 | 
				
			||||||
@ -477,9 +477,9 @@ uint32_t usbdrv_arm_IN_endpoint(uint8_t ep, const uint8_t *data, uint16_t len) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    // determine final write size
 | 
					    // determine final write size
 | 
				
			||||||
    uint32_t freeSize = 0;
 | 
					    uint32_t freeSize = 0;
 | 
				
			||||||
    if (len > 0) { // only poll DTXFSTS if (len > 0) (see datasheet)
 | 
					    // if (len > 0) { // only poll DTXFSTS if (len > 0) (see datasheet)
 | 
				
			||||||
        freeSize = USBINEP[ep].DTXFSTS * sizeof(uint32_t); // get free transmit buffer size
 | 
					    freeSize = USBINEP[ep].DTXFSTS * sizeof(uint32_t); // get free transmit buffer size
 | 
				
			||||||
    }
 | 
					    //}
 | 
				
			||||||
    uint16_t writeSize = MIN(freeSize, len); // limit transmit size to free size
 | 
					    uint16_t writeSize = MIN(freeSize, len); // limit transmit size to free size
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // calculate packet count based on max packet size
 | 
					    // calculate packet count based on max packet size
 | 
				
			||||||
@ -493,7 +493,7 @@ uint32_t usbdrv_arm_IN_endpoint(uint8_t ep, const uint8_t *data, uint16_t len) {
 | 
				
			|||||||
    gs.ep_IN[ep].zlp_next = (writeSize > 0) && ((writeSize % mps) == 0);
 | 
					    gs.ep_IN[ep].zlp_next = (writeSize > 0) && ((writeSize % mps) == 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // program DIEPTSIZ with transfer length
 | 
					    // program DIEPTSIZ with transfer length
 | 
				
			||||||
    USBINEP[ep].DIEPTSIZ = (packet_count << USB_OTG_DIEPTSIZ_PKTCNT_Pos) | writeSize;
 | 
					    USBINEP[ep].DIEPTSIZ = (packet_count << USB_OTG_DIEPTSIZ_MULCNT_Pos) | (packet_count << USB_OTG_DIEPTSIZ_PKTCNT_Pos) | writeSize;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // enable endpoint and cancel responding NAK
 | 
					    // enable endpoint and cancel responding NAK
 | 
				
			||||||
    SET_BIT(USBINEP[ep].DIEPCTL, USB_OTG_DIEPCTL_EPENA | USB_OTG_DIEPCTL_CNAK);
 | 
					    SET_BIT(USBINEP[ep].DIEPCTL, USB_OTG_DIEPCTL_EPENA | USB_OTG_DIEPCTL_CNAK);
 | 
				
			||||||
@ -511,11 +511,11 @@ uint32_t usbdrv_arm_IN_endpoint(uint8_t ep, const uint8_t *data, uint16_t len) {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // push the remaining partial dword
 | 
					    // push the remaining partial dword
 | 
				
			||||||
    uint8_t rem_bytes = len & 0b11;
 | 
					    uint8_t rem_bytes = writeSize & 0b11;
 | 
				
			||||||
    if (rem_bytes > 0) {
 | 
					    if (rem_bytes > 0) {
 | 
				
			||||||
        uint32_t rem_dword = 0;
 | 
					        uint32_t rem_dword = 0;
 | 
				
			||||||
        uint16_t rem_start = len - rem_bytes;
 | 
					        uint16_t rem_start = writeSize - rem_bytes;
 | 
				
			||||||
        for (int16_t i = len - 1; i >= rem_start; i--) {
 | 
					        for (int16_t i = writeSize - 1; i >= rem_start; i--) {
 | 
				
			||||||
            rem_dword = (rem_dword << 8) | data[i];
 | 
					            rem_dword = (rem_dword << 8) | data[i];
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        *p = rem_dword;
 | 
					        *p = rem_dword;
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user