- the way TxFIFO empty interrupts are handled has been redesigned, and the ability to "wake up" the endpoint added
This commit is contained in:
		
							parent
							
								
									25dc4a9aa8
								
							
						
					
					
						commit
						9a34b5e286
					
				@ -125,6 +125,7 @@ int usb_cdc_process_and_return(USB_CallbackEvent *cbevt) {
 | 
				
			|||||||
void usb_cdc_write(const uint8_t * data, uint32_t size) {
 | 
					void usb_cdc_write(const uint8_t * data, uint32_t size) {
 | 
				
			||||||
    if (cdcs.initialized) {
 | 
					    if (cdcs.initialized) {
 | 
				
			||||||
        bfifo_push_all(&fifo, data, size);
 | 
					        bfifo_push_all(&fifo, data, size);
 | 
				
			||||||
 | 
					        usbcore_wake_up_endpoint(cdcs.ep_assignments.data_ep, USB_IN);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										14
									
								
								usb.c
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								usb.c
									
									
									
									
									
								
							@ -25,7 +25,14 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// ---------------
 | 
					// ---------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static uint8_t tx_assembly_buf[USB_MAX_FS_PCKT_SIZE_NON_ISOCHRONOUS] DWORD_ALIGN; // buffer for assembling packets
 | 
					#ifndef USB_HIGH_SPEED
 | 
				
			||||||
 | 
					#define USB_RX_BUF_SIZE (USB_MAX_FS_PCKT_SIZE_NON_ISOCHRONOUS)
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#define USB_RX_BUF_SIZE (USB_MAX_HS_PCKT_SIZE_NON_ISOCHRONOUS)
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static uint8_t tx_assembly_buf[USB_RX_BUF_SIZE] DWORD_ALIGN; // buffer for assembling packets
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// ---------------
 | 
					// ---------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -241,7 +248,12 @@ void usbcore_process_nonsetup_event(USBDRV_CallbackCompound *cbcpd) {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void usbcore_wake_up_endpoint(uint8_t ep, uint8_t dir) {
 | 
				
			||||||
 | 
					    usbdrv_enable_endpoint_interrupt(ep, dir, true);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
uint32_t usbcore_schedule_transmission(uint8_t ep, const uint8_t *data, uint16_t size) {
 | 
					uint32_t usbcore_schedule_transmission(uint8_t ep, const uint8_t *data, uint16_t size) {
 | 
				
			||||||
 | 
					    usbdrv_enable_endpoint_interrupt(ep, USB_IN, true);
 | 
				
			||||||
    return usbdrv_arm_IN_endpoint(ep, data, size);
 | 
					    return usbdrv_arm_IN_endpoint(ep, data, size);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										5
									
								
								usb.h
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								usb.h
									
									
									
									
									
								
							@ -3,8 +3,9 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "usb_callback_event.h"
 | 
					#include "usb_callback_event.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void usbcore_init();                                                // initialize USB core
 | 
					void usbcore_init();                                                                    // initialize USB core
 | 
				
			||||||
uint32_t usbcore_schedule_transmission(uint8_t ep, const uint8_t *data, uint16_t size); // write data to endpoint, return with number of bytes actually written
 | 
					uint32_t usbcore_schedule_transmission(uint8_t ep, const uint8_t *data, uint16_t size); // write data to endpoint, return with number of bytes actually written
 | 
				
			||||||
uint32_t usbcore_schedule_reception(uint8_t ep, uint16_t size); // expect data coming from the endpoint
 | 
					uint32_t usbcore_schedule_reception(uint8_t ep, uint16_t size);                         // expect data coming from the endpoint
 | 
				
			||||||
 | 
					void usbcore_wake_up_endpoint(uint8_t ep, uint8_t dir);                                 // wake up endpoint
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* CORE_USB_USB */
 | 
					#endif /* CORE_USB_USB */
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										83
									
								
								usb_driver.c
									
									
									
									
									
								
							
							
						
						
									
										83
									
								
								usb_driver.c
									
									
									
									
									
								
							@ -8,6 +8,9 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "desc/usb_desc.h"
 | 
					#include "desc/usb_desc.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "embfmt/embformat.h"
 | 
				
			||||||
 | 
					#define SNPRINTF(str, n, fmt, ...) embfmt(str, n, fmt, __VA_ARGS__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// ---------------
 | 
					// ---------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
 | 
					#define MAX(a, b) (((a) > (b)) ? (a) : (b))
 | 
				
			||||||
@ -24,7 +27,13 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
static USBDRV_GlobalState gs; // global USB state
 | 
					static USBDRV_GlobalState gs; // global USB state
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static uint8_t rx_buf[USB_MAX_FS_PCKT_SIZE_NON_ISOCHRONOUS] DWORD_ALIGN; // receive buffer
 | 
					#ifndef USB_HIGH_SPEED
 | 
				
			||||||
 | 
					#define USB_RX_BUF_SIZE (USB_MAX_FS_PCKT_SIZE_NON_ISOCHRONOUS)
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#define USB_RX_BUF_SIZE (USB_MAX_HS_PCKT_SIZE_NON_ISOCHRONOUS)
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static uint8_t rx_buf[USB_RX_BUF_SIZE] DWORD_ALIGN; // receive buffer
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define USB_EVENT_QUEUE_LENGTH (16)
 | 
					#define USB_EVENT_QUEUE_LENGTH (16)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -115,7 +124,7 @@ void usbdrv_gpio_init() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// initialize USB subsystem
 | 
					// initialize USB subsystem
 | 
				
			||||||
void usbdrv_init() {
 | 
					void usbdrv_init() {
 | 
				
			||||||
    NVIC_DisableIRQ(USB_IRQn);
 | 
					    HAL_NVIC_DisableIRQ(USB_IRQn);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    usbdrv_init_global_state();
 | 
					    usbdrv_init_global_state();
 | 
				
			||||||
    usbdrv_gpio_init();
 | 
					    usbdrv_gpio_init();
 | 
				
			||||||
@ -123,8 +132,8 @@ void usbdrv_init() {
 | 
				
			|||||||
    usbdrv_initial_ep0_setup();
 | 
					    usbdrv_initial_ep0_setup();
 | 
				
			||||||
    usbdrv_power_and_connect(true);
 | 
					    usbdrv_power_and_connect(true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    NVIC_SetPriority(USB_IRQn, 7);
 | 
					    HAL_NVIC_SetPriority(USB_IRQn, 8, 0);
 | 
				
			||||||
    NVIC_EnableIRQ(USB_IRQn);
 | 
					    HAL_NVIC_EnableIRQ(USB_IRQn);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void usbdrv_reset() {
 | 
					void usbdrv_reset() {
 | 
				
			||||||
@ -237,7 +246,7 @@ void usbdrv_periph_init() {
 | 
				
			|||||||
    CLEAR_BIT(USBG->GAHBCFG, USB_OTG_GAHBCFG_GINT);                            // mask all interrupts for now
 | 
					    CLEAR_BIT(USBG->GAHBCFG, USB_OTG_GAHBCFG_GINT);                            // mask all interrupts for now
 | 
				
			||||||
    CLEAR_BIT(USBG->GUSBCFG, USB_OTG_GUSBCFG_HNPCAP | USB_OTG_GUSBCFG_SRPCAP); // disable HNP and SRP
 | 
					    CLEAR_BIT(USBG->GUSBCFG, USB_OTG_GUSBCFG_HNPCAP | USB_OTG_GUSBCFG_SRPCAP); // disable HNP and SRP
 | 
				
			||||||
    WRITE_FIELD(USBG->GUSBCFG, USB_OTG_GUSBCFG_TRDT, TRDT_VALUE);              // set TRDT according to the RM
 | 
					    WRITE_FIELD(USBG->GUSBCFG, USB_OTG_GUSBCFG_TRDT, TRDT_VALUE);              // set TRDT according to the RM
 | 
				
			||||||
    //WRITE_FIELD(USBG->GUSBCFG, USB_OTG_GUSBCFG_TOCAL, TOCAL_VALUE);            // set TOCAL
 | 
					    // WRITE_FIELD(USBG->GUSBCFG, USB_OTG_GUSBCFG_TOCAL, TOCAL_VALUE);            // set TOCAL
 | 
				
			||||||
    CLEAR_BIT(USBG->GUSBCFG, USB_OTG_GUSBCFG_FHMOD); // clear Host mode forcing
 | 
					    CLEAR_BIT(USBG->GUSBCFG, USB_OTG_GUSBCFG_FHMOD); // clear Host mode forcing
 | 
				
			||||||
    SET_BIT(USBG->GUSBCFG, USB_OTG_GUSBCFG_FDMOD);   // force Device mode
 | 
					    SET_BIT(USBG->GUSBCFG, USB_OTG_GUSBCFG_FDMOD);   // force Device mode
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -258,8 +267,8 @@ void usbdrv_periph_init() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#ifdef USB_HIGH_SPEED
 | 
					#ifdef USB_HIGH_SPEED
 | 
				
			||||||
    // WRITE_FIELD(USBD->DCFG, USB_OTG_DCFG_DSPD, USB_LINESPEED_FULL_SPEED);
 | 
					    // WRITE_FIELD(USBD->DCFG, USB_OTG_DCFG_DSPD, USB_LINESPEED_FULL_SPEED);
 | 
				
			||||||
    WRITE_FIELD(USBD->DCFG, USB_OTG_DCFG_DSPD, USB_LINESPEED_HIGH_SPEED_ULPI);
 | 
					    // WRITE_FIELD(USBD->DCFG, USB_OTG_DCFG_DSPD, USB_LINESPEED_HIGH_SPEED_ULPI);
 | 
				
			||||||
    //WRITE_FIELD(USBD->DCFG, USB_OTG_DCFG_DSPD, USB_LINESPEED_FULL_SPEED_ULPI);
 | 
					    WRITE_FIELD(USBD->DCFG, USB_OTG_DCFG_DSPD, USB_LINESPEED_FULL_SPEED_ULPI);
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
    WRITE_FIELD(USBD->DCFG, USB_OTG_DCFG_DSPD, USB_LINESPEED_FULL_SPEED); // there's no other possible option
 | 
					    WRITE_FIELD(USBD->DCFG, USB_OTG_DCFG_DSPD, USB_LINESPEED_FULL_SPEED); // there's no other possible option
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
@ -301,14 +310,14 @@ void usbdrv_periph_init() {
 | 
				
			|||||||
void usbdrv_power_and_connect(bool en) {
 | 
					void usbdrv_power_and_connect(bool en) {
 | 
				
			||||||
    if (en) { // ON
 | 
					    if (en) { // ON
 | 
				
			||||||
        CLEAR_BIT(USBD->DCTL, USB_OTG_DCTL_SDIS);
 | 
					        CLEAR_BIT(USBD->DCTL, USB_OTG_DCTL_SDIS);
 | 
				
			||||||
    #ifndef USB_HIGH_SPEED
 | 
					#ifndef USB_HIGH_SPEED
 | 
				
			||||||
        SET_BIT(USBG->GCCFG, USB_OTG_GCCFG_PWRDWN); // actually, this is power UP
 | 
					        SET_BIT(USBG->GCCFG, USB_OTG_GCCFG_PWRDWN); // actually, this is power UP
 | 
				
			||||||
    #endif
 | 
					#endif
 | 
				
			||||||
    } else {                                        // OFF
 | 
					    } else { // OFF
 | 
				
			||||||
        SET_BIT(USBD->DCTL, USB_OTG_DCTL_SDIS);
 | 
					        SET_BIT(USBD->DCTL, USB_OTG_DCTL_SDIS);
 | 
				
			||||||
    #ifndef USB_HIGH_SPEED
 | 
					#ifndef USB_HIGH_SPEED
 | 
				
			||||||
        CLEAR_BIT(USBG->GCCFG, USB_OTG_GCCFG_PWRDWN);
 | 
					        CLEAR_BIT(USBG->GCCFG, USB_OTG_GCCFG_PWRDWN);
 | 
				
			||||||
    #endif
 | 
					#endif
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -386,7 +395,7 @@ void usbdrv_fetch_endpoint_configuration(uint8_t config_index) {
 | 
				
			|||||||
#define USB_RX_FIFO_SETUP_RESERVATION_DWORDS (10)
 | 
					#define USB_RX_FIFO_SETUP_RESERVATION_DWORDS (10)
 | 
				
			||||||
#define USB_MIN_GROSS_TX_FIFO_SIZE (2 * USB_MIN_EP_FIFO_SIZE)
 | 
					#define USB_MIN_GROSS_TX_FIFO_SIZE (2 * USB_MIN_EP_FIFO_SIZE)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if defined(USB_STM32F4) 
 | 
					#if defined(USB_STM32F4)
 | 
				
			||||||
#ifndef USB_HIGH_SPEED
 | 
					#ifndef USB_HIGH_SPEED
 | 
				
			||||||
#define USB_MIN_GROSS_RX_FIFO_SIZE (2 * USB_MIN_EP_FIFO_SIZE + USB_RX_FIFO_SETUP_RESERVATION_DWORDS * 4)
 | 
					#define USB_MIN_GROSS_RX_FIFO_SIZE (2 * USB_MIN_EP_FIFO_SIZE + USB_RX_FIFO_SETUP_RESERVATION_DWORDS * 4)
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
@ -396,6 +405,9 @@ void usbdrv_fetch_endpoint_configuration(uint8_t config_index) {
 | 
				
			|||||||
#define USB_MIN_GROSS_RX_FIFO_SIZE (256)
 | 
					#define USB_MIN_GROSS_RX_FIFO_SIZE (256)
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define USBDRV_ADDR_TABLE_STR_LEN (255)
 | 
				
			||||||
 | 
					static char usbdrv_addr_table[USBDRV_ADDR_TABLE_STR_LEN + 1];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// build FIFO (compute addresses)
 | 
					// build FIFO (compute addresses)
 | 
				
			||||||
void usbdrv_build_fifo() {
 | 
					void usbdrv_build_fifo() {
 | 
				
			||||||
    // ---- OUT ----
 | 
					    // ---- OUT ----
 | 
				
			||||||
@ -430,19 +442,28 @@ void usbdrv_build_fifo() {
 | 
				
			|||||||
    next_fifo_addr += fifo_size;        // advance next FIFO address
 | 
					    next_fifo_addr += fifo_size;        // advance next FIFO address
 | 
				
			||||||
    usbdrv_set_rx_fifo_size(fifo_size); // set Rx FIFO size in hardware
 | 
					    usbdrv_set_rx_fifo_size(fifo_size); // set Rx FIFO size in hardware
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    uint32_t str_offset = SNPRINTF(usbdrv_addr_table, USBDRV_ADDR_TABLE_STR_LEN, "RX:  000-%03x (%u)\r\n", fifo_size - 1, fifo_size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // ---- IN ----
 | 
					    // ---- IN ----
 | 
				
			||||||
    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, 2 * cfg->max_packet_size)); // correct FIFO size if necessary
 | 
					            cfg->fifo_size = CEIL4(MAX(USB_MIN_GROSS_TX_FIFO_SIZE, cfg->max_packet_size + 64)); // 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;
 | 
					            cfg->zlp_next = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            str_offset += SNPRINTF(usbdrv_addr_table + str_offset, USBDRV_ADDR_TABLE_STR_LEN - str_offset, "TX%u: %03x-%03x (%u)\r\n", i, next_fifo_addr, next_fifo_addr + cfg->fifo_size - 1, cfg->fifo_size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // cfg->txp = false;                                                                                    // no transfer is in progress
 | 
					            // cfg->txp = false;                                                                                    // no transfer is in progress
 | 
				
			||||||
            next_fifo_addr += cfg->fifo_size; // advance next address
 | 
					            next_fifo_addr += cfg->fifo_size; // advance next address
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const char * usbdrv_get_fifo_addr_table() {
 | 
				
			||||||
 | 
					    return usbdrv_addr_table;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// create an initial setup for EP0 in both directions
 | 
					// create an initial setup for EP0 in both directions
 | 
				
			||||||
void usbdrv_initial_ep0_setup() {
 | 
					void usbdrv_initial_ep0_setup() {
 | 
				
			||||||
    // setup EP0 OUT and IN
 | 
					    // setup EP0 OUT and IN
 | 
				
			||||||
@ -508,10 +529,9 @@ void usbdrv_configure_endpoint(uint8_t ep, uint8_t dir, const USBDRV_EpConfig *c
 | 
				
			|||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            WRITE_FIELD(USBINEP[ep].DIEPCTL, USB_OTG_DIEPCTL_EPTYP, cfg->type);            // program endpoint type
 | 
					            WRITE_FIELD(USBINEP[ep].DIEPCTL, USB_OTG_DIEPCTL_EPTYP, cfg->type);            // program endpoint type
 | 
				
			||||||
            WRITE_FIELD(USBINEP[ep].DIEPCTL, USB_OTG_DIEPCTL_MPSIZ, cfg->max_packet_size); // program maximum packet size
 | 
					            WRITE_FIELD(USBINEP[ep].DIEPCTL, USB_OTG_DIEPCTL_MPSIZ, cfg->max_packet_size); // program maximum packet size
 | 
				
			||||||
	    SET_BIT(USBINEP[ep].DIEPCTL, USB_OTG_DIEPCTL_USBAEP);                          // the endpoint is active in the current configuration
 | 
					            SET_BIT(USBINEP[ep].DIEPCTL, USB_OTG_DIEPCTL_USBAEP);                          // the endpoint is active in the current configuration
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
        // ---- common for all endpoints ----
 | 
					        // ---- common for all endpoints ----
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // program FIFO corresponding FIFO number
 | 
					        // program FIFO corresponding FIFO number
 | 
				
			||||||
@ -522,7 +542,7 @@ void usbdrv_configure_endpoint(uint8_t ep, uint8_t dir, const USBDRV_EpConfig *c
 | 
				
			|||||||
        *(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);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // NAK processing
 | 
					        // NAK processing
 | 
				
			||||||
        if (cfg->responding_NAK) {
 | 
					        if (cfg->responding_NAK) {
 | 
				
			||||||
@ -685,6 +705,9 @@ uint32_t usbdrv_arm_IN_endpoint(uint8_t ep, const uint8_t *data, uint16_t len) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        // 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);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // enable endpoint interrupts
 | 
				
			||||||
 | 
					        SET_BIT(USBD->DAINTMSK, 1 << ep);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // turn on interrupt generation only, if this is NOT the last FIFO write considering the current transfer
 | 
					    // turn on interrupt generation only, if this is NOT the last FIFO write considering the current transfer
 | 
				
			||||||
@ -753,6 +776,15 @@ void usbdrv_autoarm_OUT_endpoint(uint8_t ep) {
 | 
				
			|||||||
    gs.ep_OUT[ep].autoarm = true;
 | 
					    gs.ep_OUT[ep].autoarm = true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void usbdrv_enable_endpoint_interrupt(uint8_t ep, uint8_t dir, bool en) {
 | 
				
			||||||
 | 
					    uint32_t mask = 1 << (ep + ((dir == USB_OUT) ? USB_OTG_DAINTMSK_OEPM_Pos : 0));
 | 
				
			||||||
 | 
					    if (en) {
 | 
				
			||||||
 | 
					        SET_BIT(USBD->DAINTMSK, mask);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        CLEAR_BIT(USBD->DAINTMSK, mask);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// ----------------
 | 
					// ----------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void usbdrv_set_address(uint8_t addr) {
 | 
					void usbdrv_set_address(uint8_t addr) {
 | 
				
			||||||
@ -858,7 +890,7 @@ void usbdrv_process_event(uint8_t evt_code, USBDRV_EventData *evt_data) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                // SET_BIT(USBG->GINTMSK, USB_OTG_GINTMSK_RXFLVLM); // unmask interrupt
 | 
					                // SET_BIT(USBG->GINTMSK, USB_OTG_GINTMSK_RXFLVLM); // unmask interrupt
 | 
				
			||||||
            } else {                                                            // not EP0
 | 
					            } else {                                                            // not EP0
 | 
				
			||||||
                if (evt_data.rx.pckt_status == USB_PCKT_STATUS_OUT_DATA_RECV) { // TODO maybe the
 | 
					                if (evt_data.rx.pckt_status == USB_PCKT_STATUS_OUT_DATA_RECV) { // TODO: "maybe the"????
 | 
				
			||||||
                    USBDRV_CallbackCompound cbcpd;
 | 
					                    USBDRV_CallbackCompound cbcpd;
 | 
				
			||||||
                    cbcpd.ep = evt_data.rx.ep_num;
 | 
					                    cbcpd.ep = evt_data.rx.ep_num;
 | 
				
			||||||
                    cbcpd.dir = USB_OUT;
 | 
					                    cbcpd.dir = USB_OUT;
 | 
				
			||||||
@ -903,7 +935,8 @@ void usbdrv_process_event(uint8_t evt_code, USBDRV_EventData *evt_data) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            for (uint8_t ep = 0; ep < USB_NUM_OF_ENDPOINTS; ep++) {
 | 
					            for (uint8_t ep = 0; ep < USB_NUM_OF_ENDPOINTS; ep++) {
 | 
				
			||||||
                cbcpd.ep = ep;
 | 
					                cbcpd.ep = ep;
 | 
				
			||||||
                if (gs.ep_IN[ep].is_configured) {                             // if the endpoint is running
 | 
					                bool ep_on = USBD->DAINTMSK & (1 << ep);                      // decide if this endpoint is currently enable for transmission based on its endpoint mask
 | 
				
			||||||
 | 
					                if (gs.ep_IN[ep].is_configured && ep_on) {                    // if the endpoint is running
 | 
				
			||||||
                    if (READ_BIT(USBINEP[ep].DIEPINT, USB_OTG_DIEPINT_TOC)) { // timeout done
 | 
					                    if (READ_BIT(USBINEP[ep].DIEPINT, USB_OTG_DIEPINT_TOC)) { // timeout done
 | 
				
			||||||
                        SET_BIT(USBINEP[ep].DIEPINT, USB_OTG_DIEPINT_TOC);
 | 
					                        SET_BIT(USBINEP[ep].DIEPINT, USB_OTG_DIEPINT_TOC);
 | 
				
			||||||
                        USBMSG("TO\n");
 | 
					                        USBMSG("TO\n");
 | 
				
			||||||
@ -931,14 +964,24 @@ void usbdrv_process_event(uint8_t evt_code, USBDRV_EventData *evt_data) {
 | 
				
			|||||||
                            cbcpd.code = USB_CBC_IN_DONE;
 | 
					                            cbcpd.code = USB_CBC_IN_DONE;
 | 
				
			||||||
                            usbcore_process_nonsetup_event(&cbcpd);
 | 
					                            usbcore_process_nonsetup_event(&cbcpd);
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    } else if (READ_BIT(USBINEP[ep].DIEPINT, USB_OTG_DIEPINT_ITTXFE)) { // IN endpoint IN token received with Tx FIFO empty interrupt
 | 
					                    } else if (READ_BIT(USBINEP[ep].DIEPINT, USB_OTG_DIEPINT_ITTXFE)) { // IN endpoint IN token received with Tx FIFO empty interrupt
 | 
				
			||||||
                        SET_BIT(USBINEP[ep].DIEPINT, USB_OTG_DIEPINT_ITTXFE);
 | 
					                        SET_BIT(USBINEP[ep].DIEPINT, USB_OTG_DIEPINT_ITTXFE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        // MSG("E %u\n", ep);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        // USBMSG("IN FIFOEMPTY [%d]\n", ep);
 | 
					                        // USBMSG("IN FIFOEMPTY [%d]\n", ep);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        // transfer finished
 | 
					                        // transfer finished
 | 
				
			||||||
                        // gs.ep_IN[ep].txp = false;
 | 
					                        // gs.ep_IN[ep].txp = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        // if (!gs.ep_IN[ep].) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        //}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        // disable endpoint interrupt
 | 
				
			||||||
 | 
					                        usbdrv_enable_endpoint_interrupt(ep, USB_IN, false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        cbcpd.code = USB_CBC_IN_FIFOEMPTY;
 | 
					                        cbcpd.code = USB_CBC_IN_FIFOEMPTY;
 | 
				
			||||||
                        usbcore_process_nonsetup_event(&cbcpd);
 | 
					                        usbcore_process_nonsetup_event(&cbcpd);
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										15
									
								
								usb_driver.h
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								usb_driver.h
									
									
									
									
									
								
							@ -7,9 +7,13 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// #define USBDBGMSG
 | 
					// #define USBDBGMSG
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define USB_NUM_OF_ENDPOINTS (4)
 | 
					#define USB_NUM_OF_ENDPOINTS (4) // FIXME: this is module-dependend
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// non isochronous transfers
 | 
				
			||||||
#define USB_MAX_FS_PCKT_SIZE_NON_ISOCHRONOUS (64)
 | 
					#define USB_MAX_FS_PCKT_SIZE_NON_ISOCHRONOUS (64)
 | 
				
			||||||
 | 
					#define USB_MAX_HS_PCKT_SIZE_NON_ISOCHRONOUS (512)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// isochronous transfers
 | 
				
			||||||
#define USB_MAX_FS_PCKT_SIZE_ISOCHRONOUS (1023)
 | 
					#define USB_MAX_FS_PCKT_SIZE_ISOCHRONOUS (1023)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define USB_MIN_EP_FIFO_SIZE (64)
 | 
					#define USB_MIN_EP_FIFO_SIZE (64)
 | 
				
			||||||
@ -135,6 +139,7 @@ void usbdrv_preload_endpoint_config(uint8_t ep, uint8_t dir, const USBDRV_EpConf
 | 
				
			|||||||
void usbdrv_clear_endpoint_config();                                                      // clear endpoint config
 | 
					void usbdrv_clear_endpoint_config();                                                      // clear endpoint config
 | 
				
			||||||
void usbdrv_apply_endpoint_config();                                                      // apply preloaded endpoint configuration
 | 
					void usbdrv_apply_endpoint_config();                                                      // apply preloaded endpoint configuration
 | 
				
			||||||
void usbdrv_build_fifo();                                                                 // build FIFO (compute addresses)
 | 
					void usbdrv_build_fifo();                                                                 // build FIFO (compute addresses)
 | 
				
			||||||
 | 
					const char *usbdrv_get_fifo_addr_table();                                                 // get FIFO address table
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void usbdrv_fetch_endpoint_configuration(uint8_t config_index);                      // fetch endpoint configuration from descriptor dump
 | 
					void usbdrv_fetch_endpoint_configuration(uint8_t config_index);                      // fetch endpoint configuration from descriptor dump
 | 
				
			||||||
void usbdrv_configure_endpoint(uint8_t ep, uint8_t dir, const USBDRV_EpConfig *cfg); // configure USB endpoint
 | 
					void usbdrv_configure_endpoint(uint8_t ep, uint8_t dir, const USBDRV_EpConfig *cfg); // configure USB endpoint
 | 
				
			||||||
@ -151,10 +156,10 @@ void usbdrv_process_rx_fifo_top(USBDRV_EventData *evt_data); // see what's on to
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
uint32_t usbdrv_arm_IN_endpoint(uint8_t ep, const uint8_t *data, uint16_t len); // write data to specific endpoint FIFO
 | 
					uint32_t usbdrv_arm_IN_endpoint(uint8_t ep, const uint8_t *data, uint16_t len); // write data to specific endpoint FIFO
 | 
				
			||||||
#define USBDRV_ARM_IN_ZLP(ep) usbdrv_arm_IN_endpoint((ep), NULL, 0)
 | 
					#define USBDRV_ARM_IN_ZLP(ep) usbdrv_arm_IN_endpoint((ep), NULL, 0)
 | 
				
			||||||
uint32_t usbdrv_arm_OUT_endpoint(uint8_t ep, uint8_t size); // arm OUT endpoint, returned with the actual armed size (capped by the max packet size on that endpoint)
 | 
					uint32_t usbdrv_arm_OUT_endpoint(uint8_t ep, uint8_t size);              // arm OUT endpoint, returned with the actual armed size (capped by the max packet size on that endpoint)
 | 
				
			||||||
void usbdrv_autoarm_OUT_endpoint(uint8_t ep);               // automatically re-arm OUT endpoint at the and of the current OUT transfer
 | 
					void usbdrv_autoarm_OUT_endpoint(uint8_t ep);                            // automatically re-arm OUT endpoint at the and of the current OUT transfer
 | 
				
			||||||
 | 
					void usbdrv_enable_endpoint_interrupt(uint8_t ep, uint8_t dir, bool en); // enable/disable endpoint interrupt signaling
 | 
				
			||||||
bool usbdrv_get_endpoint_interrupt_flag(uint8_t ep, uint8_t dir); // get endpoint interrupt flag
 | 
					bool usbdrv_get_endpoint_interrupt_flag(uint8_t ep, uint8_t dir);        // get endpoint interrupt flag
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void usbdrv_set_address(uint8_t addr); // set device address
 | 
					void usbdrv_set_address(uint8_t addr); // set device address
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user