- CDC class OS-managed blocking buffer added; - some low-level USB function signatures have been changed
This commit is contained in:
		
							parent
							
								
									93a0ff53e6
								
							
						
					
					
						commit
						627e038dbb
					
				
							
								
								
									
										41
									
								
								class/cdc.c
									
									
									
									
									
								
							
							
						
						
									
										41
									
								
								class/cdc.c
									
									
									
									
									
								
							@ -6,9 +6,16 @@
 | 
			
		||||
 | 
			
		||||
#include "../usb.h"
 | 
			
		||||
 | 
			
		||||
#include <blocking_io/blocking_fifo.h>
 | 
			
		||||
 | 
			
		||||
// state
 | 
			
		||||
static USB_CdcState cdcs;
 | 
			
		||||
static uint8_t cdc_buffer[USB_CDC_BUFSIZE];
 | 
			
		||||
static USB_CdcState cdcs = { 0 };
 | 
			
		||||
static uint8_t tx_buffer[USB_CDC_PCKT_BUFSIZE];
 | 
			
		||||
 | 
			
		||||
#define USB_CDC_FIFO_MEM_SIZE (2048)
 | 
			
		||||
 | 
			
		||||
static uint8_t fifo_mem[USB_CDC_FIFO_MEM_SIZE];
 | 
			
		||||
static BFifo fifo;
 | 
			
		||||
 | 
			
		||||
void usb_cdc_init(const USB_CdcAssignments *as) {
 | 
			
		||||
    // clear the structure
 | 
			
		||||
@ -24,10 +31,11 @@ void usb_cdc_init(const USB_CdcAssignments *as) {
 | 
			
		||||
    // fill-in assigments
 | 
			
		||||
    cdcs.ep_assignments = *as;
 | 
			
		||||
 | 
			
		||||
    // assign buffer pointer
 | 
			
		||||
    USB_CdcBuffer * buf = &cdcs.buffer;
 | 
			
		||||
    buf->p = cdc_buffer;
 | 
			
		||||
    buf->size = USB_CDC_BUFSIZE;    
 | 
			
		||||
    // initialize buffer
 | 
			
		||||
    bfifo_create(&fifo, fifo_mem, USB_CDC_FIFO_MEM_SIZE);
 | 
			
		||||
 | 
			
		||||
    // from now on CDC is considered initialized
 | 
			
		||||
    cdcs.initialized = true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int usb_cdc_process_and_return(USB_CallbackEvent *cbevt) {
 | 
			
		||||
@ -37,12 +45,12 @@ int usb_cdc_process_and_return(USB_CallbackEvent *cbevt) {
 | 
			
		||||
            switch (cbevt->setup_request->bRequest) {
 | 
			
		||||
                case USB_CDC_SET_LINE_CODING: // set line coding
 | 
			
		||||
                    memcpy(&cdcs.line_coding, cbevt->data, sizeof(USB_Cdc_LineCodingStruct));
 | 
			
		||||
                    MSG("%u\n", cdcs.line_coding.dwDTERate);
 | 
			
		||||
                    //MSG("%u\n", cdcs.line_coding.dwDTERate);
 | 
			
		||||
                    ret = 0;
 | 
			
		||||
                    break;
 | 
			
		||||
                case USB_CDC_SET_CONTROL_LINE_STATE: // set control line state
 | 
			
		||||
                    memcpy(&cdcs.control_line_state, cbevt->data, sizeof(USB_Cdc_ControlLineStateStruct));
 | 
			
		||||
                    MSG("%u\n", cdcs.control_line_state.D);
 | 
			
		||||
                    //MSG("%u\n", cdcs.control_line_state.D);
 | 
			
		||||
                    ret = 0;
 | 
			
		||||
                    break;
 | 
			
		||||
                default:
 | 
			
		||||
@ -63,6 +71,7 @@ int usb_cdc_process_and_return(USB_CallbackEvent *cbevt) {
 | 
			
		||||
            if (cbevt->ep == cdcs.ep_assignments.data_ep) {
 | 
			
		||||
                //MSG("%c\n", cbevt->data[0]);
 | 
			
		||||
                ret = 0;
 | 
			
		||||
 | 
			
		||||
                usbcore_write(cdcs.ep_assignments.data_ep, cbevt->data, cbevt->size); // echo
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
@ -75,7 +84,13 @@ int usb_cdc_process_and_return(USB_CallbackEvent *cbevt) {
 | 
			
		||||
            } else if (cbevt->ep == cdcs.ep_assignments.data_ep) { // if data are requested
 | 
			
		||||
                //usbcore_write(cdcs.ep_assignments.data_ep, NULL, 0); // send ZLP
 | 
			
		||||
                ret = 0;
 | 
			
		||||
                // TODO!!
 | 
			
		||||
                
 | 
			
		||||
                // read from the fifo
 | 
			
		||||
                uint32_t readSize = bfifo_read(&fifo, tx_buffer, USB_CDC_PCKT_BUFSIZE);
 | 
			
		||||
                if (readSize > 0) {
 | 
			
		||||
                    uint32_t writeSize = usbcore_write(cdcs.ep_assignments.data_ep, tx_buffer, readSize); // write data acquired from the buffer
 | 
			
		||||
                    bfifo_pop(&fifo, writeSize, 0); // pop with no blocking
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -86,6 +101,12 @@ int usb_cdc_process_and_return(USB_CallbackEvent *cbevt) {
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void usb_event_callback(USB_CallbackEvent *cbevt) {
 | 
			
		||||
    usb_cdc_process_and_return(cbevt);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void usb_cdc_write(const uint8_t * data, uint32_t size) {
 | 
			
		||||
    
 | 
			
		||||
    if (cdcs.initialized) {
 | 
			
		||||
        bfifo_push_all(&fifo, data, size);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										11
									
								
								class/cdc.h
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								class/cdc.h
									
									
									
									
									
								
							@ -46,17 +46,11 @@ typedef struct {
 | 
			
		||||
    uint8_t data_ep : 4; // data endpoint
 | 
			
		||||
} USB_CdcAssignments;
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
    uint32_t size;
 | 
			
		||||
    uint8_t * p;
 | 
			
		||||
    uint8_t read_idx, write_idx;
 | 
			
		||||
} USB_CdcBuffer;
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
    USB_CdcAssignments ep_assignments; // endpoint assignments
 | 
			
		||||
    USB_CdcBuffer buffer; // buffer
 | 
			
		||||
    USB_Cdc_LineCodingStruct line_coding; // line coding
 | 
			
		||||
    USB_Cdc_ControlLineStateStruct control_line_state; // control line state
 | 
			
		||||
    bool initialized; // CDC is initialized
 | 
			
		||||
} USB_CdcState;
 | 
			
		||||
 | 
			
		||||
// ----------------
 | 
			
		||||
@ -68,11 +62,12 @@ typedef struct {
 | 
			
		||||
 | 
			
		||||
// ----------------
 | 
			
		||||
 | 
			
		||||
#define USB_CDC_BUFSIZE (256)
 | 
			
		||||
#define USB_CDC_PCKT_BUFSIZE (120)
 | 
			
		||||
 | 
			
		||||
// ----------------
 | 
			
		||||
 | 
			
		||||
void usb_cdc_init(const USB_CdcAssignments * as);
 | 
			
		||||
int usb_cdc_process_and_return(USB_CallbackEvent * cbevt);
 | 
			
		||||
void usb_cdc_write(const uint8_t * data, uint32_t size);
 | 
			
		||||
 | 
			
		||||
#endif /* CORE_USB_CLASS_CDC */
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										4
									
								
								usb.c
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								usb.c
									
									
									
									
									
								
							@ -222,6 +222,6 @@ void usbcore_process_nonsetup_event(USBDRV_CallbackCompound *cbcpd) {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void usbcore_write(uint8_t ep, const uint8_t *data, uint16_t size) {
 | 
			
		||||
    usbdrv_arm_IN_endpoint(ep, data, size);
 | 
			
		||||
uint32_t usbcore_write(uint8_t ep, const uint8_t *data, uint16_t size) {
 | 
			
		||||
    return usbdrv_arm_IN_endpoint(ep, data, size);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										2
									
								
								usb.h
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								usb.h
									
									
									
									
									
								
							@ -4,6 +4,6 @@
 | 
			
		||||
#include "usb_callback_event.h"
 | 
			
		||||
 | 
			
		||||
void usbcore_init();                                                // initialize USB core
 | 
			
		||||
void usbcore_write(uint8_t ep, const uint8_t *data, uint16_t size); // write data to endpoint
 | 
			
		||||
uint32_t usbcore_write(uint8_t ep, const uint8_t *data, uint16_t size); // write data to endpoint, return with number of bytes actually written
 | 
			
		||||
 | 
			
		||||
#endif /* CORE_USB_USB */
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										289
									
								
								usb_driver.c
									
									
									
									
									
								
							
							
						
						
									
										289
									
								
								usb_driver.c
									
									
									
									
									
								
							@ -82,6 +82,7 @@ void usbdrv_init() {
 | 
			
		||||
    usbdrv_initial_ep0_setup();
 | 
			
		||||
    usbdrv_power_and_connect(true);
 | 
			
		||||
 | 
			
		||||
    NVIC_SetPriority(OTG_FS_IRQn, 6);
 | 
			
		||||
    NVIC_EnableIRQ(OTG_FS_IRQn);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -471,27 +472,31 @@ void usbdrv_fetch_received_data(uint8_t ep, uint16_t len) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// write data to specific endpoint FIFO
 | 
			
		||||
void usbdrv_arm_IN_endpoint(uint8_t ep, const uint8_t *data, uint16_t len) {
 | 
			
		||||
uint32_t usbdrv_arm_IN_endpoint(uint8_t ep, const uint8_t *data, uint16_t len) {
 | 
			
		||||
    /*WRITE_FIELD(USBINEP[ep].DIEPTSIZ, USB_OTG_DIEPTSIZ_XFRSIZ, len);
 | 
			
		||||
    WRITE_FIELD(USBINEP[ep].DIEPTSIZ, USB_OTG_DIEPTSIZ_PKTCNT, 1);*/
 | 
			
		||||
 | 
			
		||||
    // endpoint is already armed
 | 
			
		||||
    if (gs.ep_IN[ep].task_commenced == USB_EPEVT_ARMED) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    // if (gs.ep_IN[ep].task_commenced == USB_EPEVT_ARMED) {
 | 
			
		||||
    //     return;
 | 
			
		||||
    // }
 | 
			
		||||
 | 
			
		||||
    gs.ep_IN[ep].task_commenced = USB_EPEVT_ARMED;
 | 
			
		||||
    // gs.ep_IN[ep].task_commenced = USB_EPEVT_ARMED;
 | 
			
		||||
 | 
			
		||||
    // determine final write size
 | 
			
		||||
    uint32_t freeSize = USBINEP[ep].DTXFSTS * sizeof(uint32_t); // get free transmit buffer size
 | 
			
		||||
    uint16_t writeSize = MIN(freeSize, len); // limit transmit size to free size
 | 
			
		||||
 | 
			
		||||
    // calculate packet count based on max packet size
 | 
			
		||||
    uint16_t mps = gs.ep_IN[ep].max_packet_size;
 | 
			
		||||
    uint16_t packet_count = 1; // for ZLPs
 | 
			
		||||
    if (len > 0) {             // if length is nonzero
 | 
			
		||||
        packet_count = len / mps + (((len % mps) > 0) ? 1 : 0);
 | 
			
		||||
    if (writeSize > 0) {             // if length is nonzero
 | 
			
		||||
        packet_count = writeSize / mps + (((writeSize % mps) > 0) ? 1 : 0);
 | 
			
		||||
    }
 | 
			
		||||
    // TODO: ZLP ending
 | 
			
		||||
 | 
			
		||||
    // program DIEPTSIZ with transfer length (TODO: currently only a single transfer!)
 | 
			
		||||
    USBINEP[ep].DIEPTSIZ = (packet_count << USB_OTG_DIEPTSIZ_PKTCNT_Pos) | len;
 | 
			
		||||
    USBINEP[ep].DIEPTSIZ = (packet_count << USB_OTG_DIEPTSIZ_PKTCNT_Pos) | writeSize;
 | 
			
		||||
 | 
			
		||||
    // enable endpoint and cancel responding NAK
 | 
			
		||||
    SET_BIT(USBINEP[ep].DIEPCTL, USB_OTG_DIEPCTL_EPENA | USB_OTG_DIEPCTL_CNAK);
 | 
			
		||||
@ -501,7 +506,7 @@ void usbdrv_arm_IN_endpoint(uint8_t ep, const uint8_t *data, uint16_t len) {
 | 
			
		||||
 | 
			
		||||
    // push full dwords
 | 
			
		||||
    volatile uint32_t *p = (uint32_t *)USBFIFO(ep);
 | 
			
		||||
    uint32_t floorlen_dwords = len >> 2;
 | 
			
		||||
    uint32_t floorlen_dwords = writeSize >> 2;
 | 
			
		||||
    for (uint16_t i = 0; i < floorlen_dwords; i++) {
 | 
			
		||||
        uint16_t i0 = 4 * i;
 | 
			
		||||
        uint32_t dword = data[i0] | (data[i0 + 1] << 8) | (data[i0 + 2] << 16) | (data[i0 + 3] << 24);
 | 
			
		||||
@ -521,6 +526,9 @@ void usbdrv_arm_IN_endpoint(uint8_t ep, const uint8_t *data, uint16_t len) {
 | 
			
		||||
 | 
			
		||||
    // unmask USB interrupts
 | 
			
		||||
    SET_BIT(USBG->GAHBCFG, USB_OTG_GAHBCFG_GINT);
 | 
			
		||||
 | 
			
		||||
    // return with written size
 | 
			
		||||
    return writeSize;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// arm OUT endpoint
 | 
			
		||||
@ -602,151 +610,152 @@ void usbdrv_process_event(uint8_t evt_code, USBDRV_EventData *evt_data) {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    switch (gs.state) {
 | 
			
		||||
        case USB_FSM_INITIAL_WAIT_SPEEDNEG: // wait for speed negotitation to conclude
 | 
			
		||||
            if (evt_code == USB_EVT_SPEEDNEG_DONE) {
 | 
			
		||||
                gs.state = USB_FSM_SETUP_OPERATE; // wait for speed negotiation
 | 
			
		||||
    case USB_FSM_INITIAL_WAIT_SPEEDNEG: // wait for speed negotitation to conclude
 | 
			
		||||
        if (evt_code == USB_EVT_SPEEDNEG_DONE) {
 | 
			
		||||
            gs.state = USB_FSM_SETUP_OPERATE; // wait for speed negotiation
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
    case USB_FSM_SETUP_OPERATE: { // expect SETUP transactions first, then everything else as well
 | 
			
		||||
        switch (evt_code) {
 | 
			
		||||
        case USB_EVT_RECEPTION_DONE: { // reception done
 | 
			
		||||
 | 
			
		||||
            // for (uint32_t i = 0; i < 100000; i++) {
 | 
			
		||||
            //     __NOP();
 | 
			
		||||
            // }
 | 
			
		||||
 | 
			
		||||
            USBDRV_EventData evt_data = {0};
 | 
			
		||||
            usbdrv_process_rx_fifo_top(&evt_data); // process rx fifo top
 | 
			
		||||
 | 
			
		||||
            // fetch data if data are available
 | 
			
		||||
            if ((evt_data.rx.pckt_status == USB_PCKT_STATUS_SETUP_DATA_RECV) ||
 | 
			
		||||
                (evt_data.rx.pckt_status == USB_PCKT_STATUS_OUT_DATA_RECV)) {
 | 
			
		||||
                usbdrv_fetch_received_data(evt_data.rx.ep_num, evt_data.rx.byte_count); // fetch the data
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // act according to what we have received
 | 
			
		||||
            if (evt_data.rx.ep_num == 0) { // EP0 special treatment
 | 
			
		||||
                int stage = -1;
 | 
			
		||||
                if (evt_data.rx.pckt_status == USB_PCKT_STATUS_SETUP_CPLT) {
 | 
			
		||||
                    stage = UST_SETUP;
 | 
			
		||||
                    USBMSG("--SETUP\n");
 | 
			
		||||
                } else if (evt_data.rx.pckt_status == USB_PCKT_STATUS_OUT_TRANSFER_CPLT) {
 | 
			
		||||
                    stage = UST_DATA;
 | 
			
		||||
 | 
			
		||||
                    // OUT transaction has fired
 | 
			
		||||
                    if (gs.ep_OUT[0].task_commenced == USB_EPEVT_ARMED) {
 | 
			
		||||
                        gs.ep_OUT[0].task_commenced = USB_EPEVT_IDLE;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    USBMSG("--DATA\n");
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // process setup packet
 | 
			
		||||
                if (stage != -1) {
 | 
			
		||||
                    usbcore_process_setup_pckt(gs.rx_buf, gs.rx_buf_level, stage);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // SET_BIT(USBG->GINTMSK, USB_OTG_GINTMSK_RXFLVLM); // unmask interrupt
 | 
			
		||||
            } else {                                                            // not EP0
 | 
			
		||||
                if (evt_data.rx.pckt_status == USB_PCKT_STATUS_OUT_DATA_RECV) { // TODO maybe the
 | 
			
		||||
                    USBDRV_CallbackCompound cbcpd;
 | 
			
		||||
                    cbcpd.ep = evt_data.rx.ep_num;
 | 
			
		||||
                    cbcpd.dir = USB_OUT;
 | 
			
		||||
                    cbcpd.code = USB_CBC_OUT;
 | 
			
		||||
                    cbcpd.data = gs.rx_buf;
 | 
			
		||||
                    cbcpd.size = gs.rx_buf_level;
 | 
			
		||||
                    usbcore_process_nonsetup_event(&cbcpd);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
        case USB_FSM_SETUP_OPERATE: { // expect SETUP transactions
 | 
			
		||||
            switch (evt_code) {
 | 
			
		||||
                case USB_EVT_RECEPTION_DONE: { // reception done
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
                    for (uint32_t i = 0; i < 100000; i++) {
 | 
			
		||||
                        __NOP();
 | 
			
		||||
        case USB_EVT_OUT_DONE: { // some OUT operations have finished
 | 
			
		||||
            for (uint8_t ep = 0; ep < USB_NUM_OF_ENDPOINTS; ep++) {
 | 
			
		||||
                if (gs.ep_OUT[ep].is_configured) {                              // if the endpoint is running
 | 
			
		||||
                    if (READ_BIT(USBOUTEP[ep].DOEPINT, USB_OTG_DOEPINT_STUP)) { // setup done
 | 
			
		||||
                        SET_BIT(USBOUTEP[ep].DOEPINT, USB_OTG_DOEPINT_STUP);
 | 
			
		||||
                        USBMSG("SETUP\n");
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    USBDRV_EventData evt_data = {0};
 | 
			
		||||
                    usbdrv_process_rx_fifo_top(&evt_data); // process rx fifo top
 | 
			
		||||
                    if (READ_BIT(USBOUTEP[ep].DOEPINT, USB_OTG_DOEPINT_XFRC)) { // OUT transaction done
 | 
			
		||||
                        SET_BIT(USBOUTEP[ep].DOEPINT, USB_OTG_DOEPINT_XFRC);
 | 
			
		||||
                        USBMSG("OUT\n");
 | 
			
		||||
 | 
			
		||||
                    // fetch data if data are available
 | 
			
		||||
                    if ((evt_data.rx.pckt_status == USB_PCKT_STATUS_SETUP_DATA_RECV) ||
 | 
			
		||||
                        (evt_data.rx.pckt_status == USB_PCKT_STATUS_OUT_DATA_RECV)) {
 | 
			
		||||
                        usbdrv_fetch_received_data(evt_data.rx.ep_num, evt_data.rx.byte_count); // fetch the data
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    // act according to what we have received
 | 
			
		||||
                    if (evt_data.rx.ep_num == 0) { // EP0 special treatment
 | 
			
		||||
                        int stage = -1;
 | 
			
		||||
                        if (evt_data.rx.pckt_status == USB_PCKT_STATUS_SETUP_CPLT) {
 | 
			
		||||
                            stage = UST_SETUP;
 | 
			
		||||
                            USBMSG("--SETUP\n");
 | 
			
		||||
                        } else if (evt_data.rx.pckt_status == USB_PCKT_STATUS_OUT_TRANSFER_CPLT) {
 | 
			
		||||
                            stage = UST_DATA;
 | 
			
		||||
 | 
			
		||||
                            // OUT transaction has fired
 | 
			
		||||
                            if (gs.ep_OUT[0].task_commenced == USB_EPEVT_ARMED) {
 | 
			
		||||
                                gs.ep_OUT[0].task_commenced = USB_EPEVT_IDLE;
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                            USBMSG("--DATA\n");
 | 
			
		||||
                        // reset commenced task state
 | 
			
		||||
                        if (gs.ep_OUT[ep].task_commenced == USB_EPEVT_ARMED) {
 | 
			
		||||
                            gs.ep_OUT[ep].task_commenced = USB_EPEVT_IDLE;
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        // process setup packet
 | 
			
		||||
                        if (stage != -1) {
 | 
			
		||||
                            usbcore_process_setup_pckt(gs.rx_buf, gs.rx_buf_level, stage);
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        //SET_BIT(USBG->GINTMSK, USB_OTG_GINTMSK_RXFLVLM); // unmask interrupt
 | 
			
		||||
                    } else {                                             // not EP0
 | 
			
		||||
                        if (evt_data.rx.pckt_status == USB_PCKT_STATUS_OUT_DATA_RECV) { // TODO maybe the 
 | 
			
		||||
                            USBDRV_CallbackCompound cbcpd;
 | 
			
		||||
                            cbcpd.ep = evt_data.rx.ep_num;
 | 
			
		||||
                            cbcpd.dir = USB_OUT;
 | 
			
		||||
                            cbcpd.code = USB_CBC_OUT;
 | 
			
		||||
                            cbcpd.data = gs.rx_buf;
 | 
			
		||||
                            cbcpd.size = gs.rx_buf_level;
 | 
			
		||||
                            usbcore_process_nonsetup_event(&cbcpd);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                case USB_EVT_OUT_DONE: { // some OUT operations have finished
 | 
			
		||||
                    for (uint8_t ep = 0; ep < USB_NUM_OF_ENDPOINTS; ep++) {
 | 
			
		||||
                        if (gs.ep_OUT[ep].is_configured) {                              // if the endpoint is running
 | 
			
		||||
                            if (READ_BIT(USBOUTEP[ep].DOEPINT, USB_OTG_DOEPINT_STUP)) { // setup done
 | 
			
		||||
                                SET_BIT(USBOUTEP[ep].DOEPINT, USB_OTG_DOEPINT_STUP);
 | 
			
		||||
                                USBMSG("SETUP\n");
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                            if (READ_BIT(USBOUTEP[ep].DOEPINT, USB_OTG_DOEPINT_XFRC)) { // OUT transaction done
 | 
			
		||||
                                SET_BIT(USBOUTEP[ep].DOEPINT, USB_OTG_DOEPINT_XFRC);
 | 
			
		||||
                                USBMSG("OUT\n");
 | 
			
		||||
 | 
			
		||||
                                // reset commenced task state
 | 
			
		||||
                                if (gs.ep_OUT[ep].task_commenced == USB_EPEVT_ARMED) {
 | 
			
		||||
                                    gs.ep_OUT[ep].task_commenced = USB_EPEVT_IDLE;
 | 
			
		||||
                                }
 | 
			
		||||
 | 
			
		||||
                                usbdrv_arm_OUT_endpoint(ep, gs.ep_OUT[ep].max_packet_size);
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                        usbdrv_arm_OUT_endpoint(ep, gs.ep_OUT[ep].max_packet_size);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                case USB_EVT_IN_DONE: { // some IN operations have finished
 | 
			
		||||
 | 
			
		||||
                    // callback compound
 | 
			
		||||
                    USBDRV_CallbackCompound cbcpd;
 | 
			
		||||
                    cbcpd.dir = USB_IN;
 | 
			
		||||
                    cbcpd.data = NULL;
 | 
			
		||||
                    cbcpd.size = 0;
 | 
			
		||||
 | 
			
		||||
                    for (uint8_t ep = 0; ep < USB_NUM_OF_ENDPOINTS; ep++) {
 | 
			
		||||
                        cbcpd.ep = ep;
 | 
			
		||||
                        if (gs.ep_IN[ep].is_configured) {                             // if the endpoint is running
 | 
			
		||||
                            if (READ_BIT(USBINEP[ep].DIEPINT, USB_OTG_DIEPINT_TOC)) { // timeout done
 | 
			
		||||
                                SET_BIT(USBINEP[ep].DIEPINT, USB_OTG_DIEPINT_TOC);
 | 
			
		||||
                                USBMSG("TO\n");
 | 
			
		||||
 | 
			
		||||
                                gs.ep_IN[ep].task_commenced = USB_EPEVT_IDLE;
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                            if (READ_BIT(USBINEP[ep].DIEPINT, USB_OTG_DIEPINT_XFRC)) { // IN transaction done
 | 
			
		||||
                                SET_BIT(USBINEP[ep].DIEPINT, USB_OTG_DIEPINT_XFRC);
 | 
			
		||||
 | 
			
		||||
                                // reset commenced task state
 | 
			
		||||
                                if (gs.ep_IN[ep].task_commenced == USB_EPEVT_ARMED) {
 | 
			
		||||
                                    gs.ep_IN[ep].task_commenced = USB_EPEVT_IDLE;
 | 
			
		||||
                                }
 | 
			
		||||
 | 
			
		||||
                                USBMSG("IN [%d]\n", ep);
 | 
			
		||||
 | 
			
		||||
                                cbcpd.code = USB_CBC_IN_DONE;
 | 
			
		||||
                                usbcore_process_nonsetup_event(&cbcpd);
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                            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);
 | 
			
		||||
 | 
			
		||||
                                // reset stalled state
 | 
			
		||||
                                if (gs.ep_IN[ep].task_commenced == USB_EPEVT_STALLED) {
 | 
			
		||||
                                    usbdrv_stall_endpoint(ep, USB_IN, false);
 | 
			
		||||
                                }
 | 
			
		||||
 | 
			
		||||
                                // USBMSG("IN FIFOEMPTY [%d]\n", ep);
 | 
			
		||||
 | 
			
		||||
                                cbcpd.code = USB_CBC_IN_FIFOEMPTY;
 | 
			
		||||
                                usbcore_process_nonsetup_event(&cbcpd);
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    // // set new address if it's already waiting
 | 
			
		||||
                    // if (gs.new_address != 0) {
 | 
			
		||||
                    //     WRITE_FIELD(USBD->DCFG, USB_OTG_DCFG_DAD, gs.new_address);
 | 
			
		||||
                    //     gs.new_address = 0;
 | 
			
		||||
                    //     USBMSG("ADDR SET\n");
 | 
			
		||||
                    // }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                default:
 | 
			
		||||
                    break;
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        case USB_EVT_IN_DONE: { // some IN operations have finished
 | 
			
		||||
 | 
			
		||||
            // callback compound
 | 
			
		||||
            USBDRV_CallbackCompound cbcpd;
 | 
			
		||||
            cbcpd.dir = USB_IN;
 | 
			
		||||
            cbcpd.data = NULL;
 | 
			
		||||
            cbcpd.size = 0;
 | 
			
		||||
 | 
			
		||||
            for (uint8_t ep = 0; ep < USB_NUM_OF_ENDPOINTS; ep++) {
 | 
			
		||||
                cbcpd.ep = ep;
 | 
			
		||||
                if (gs.ep_IN[ep].is_configured) {                             // if the endpoint is running
 | 
			
		||||
                    if (READ_BIT(USBINEP[ep].DIEPINT, USB_OTG_DIEPINT_TOC)) { // timeout done
 | 
			
		||||
                        SET_BIT(USBINEP[ep].DIEPINT, USB_OTG_DIEPINT_TOC);
 | 
			
		||||
                        USBMSG("TO\n");
 | 
			
		||||
 | 
			
		||||
                        gs.ep_IN[ep].task_commenced = USB_EPEVT_IDLE;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    if (READ_BIT(USBINEP[ep].DIEPINT, USB_OTG_DIEPINT_XFRC)) { // IN transaction done
 | 
			
		||||
                        SET_BIT(USBINEP[ep].DIEPINT, USB_OTG_DIEPINT_XFRC);
 | 
			
		||||
 | 
			
		||||
                        // reset commenced task state
 | 
			
		||||
                        if (gs.ep_IN[ep].task_commenced == USB_EPEVT_ARMED) {
 | 
			
		||||
                            gs.ep_IN[ep].task_commenced = USB_EPEVT_IDLE;
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        USBMSG("IN [%d]\n", ep);
 | 
			
		||||
 | 
			
		||||
                        cbcpd.code = USB_CBC_IN_DONE;
 | 
			
		||||
                        usbcore_process_nonsetup_event(&cbcpd);
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    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);
 | 
			
		||||
 | 
			
		||||
                        // reset stalled state
 | 
			
		||||
                        if (gs.ep_IN[ep].task_commenced == USB_EPEVT_STALLED) {
 | 
			
		||||
                            usbdrv_stall_endpoint(ep, USB_IN, false);
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        // USBMSG("IN FIFOEMPTY [%d]\n", ep);
 | 
			
		||||
 | 
			
		||||
                        cbcpd.code = USB_CBC_IN_FIFOEMPTY;
 | 
			
		||||
                        usbcore_process_nonsetup_event(&cbcpd);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // // set new address if it's already waiting
 | 
			
		||||
            // if (gs.new_address != 0) {
 | 
			
		||||
            //     WRITE_FIELD(USBD->DCFG, USB_OTG_DCFG_DAD, gs.new_address);
 | 
			
		||||
            //     gs.new_address = 0;
 | 
			
		||||
            //     USBMSG("ADDR SET\n");
 | 
			
		||||
            // }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        default:
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    default:
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -804,7 +813,7 @@ void OTG_FS_IRQHandler() {
 | 
			
		||||
    if (ints & USB_OTG_GINTSTS_RXFLVL) {
 | 
			
		||||
        // SET_BIT(USBG->GINTSTS, USB_OTG_GINTSTS_RXFLVL); // clear interrupt
 | 
			
		||||
        USBMSG("RX DONE\n");
 | 
			
		||||
        //CLEAR_BIT(USBG->GINTMSK, USB_OTG_GINTMSK_RXFLVLM);  // mask interrupt until processing is done
 | 
			
		||||
        // CLEAR_BIT(USBG->GINTMSK, USB_OTG_GINTMSK_RXFLVLM);  // mask interrupt until processing is done
 | 
			
		||||
        usbdrv_process_event(USB_EVT_RECEPTION_DONE, NULL); // process event
 | 
			
		||||
        // usbdrv_push_event(USB_EVT_RECEPTION_DONE, NULL); // push event
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -138,7 +138,7 @@ void usbdrv_set_rx_fifo_size(uint16_t size); // set Rx FIFO size
 | 
			
		||||
void usbdrv_fetch_received_data(uint8_t ep, uint16_t len);   // fetch received data from RX FIFO to receive buffer
 | 
			
		||||
void usbdrv_process_rx_fifo_top(USBDRV_EventData *evt_data); // see what's on top of Rx FIFO
 | 
			
		||||
 | 
			
		||||
void 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)
 | 
			
		||||
void usbdrv_arm_OUT_endpoint(uint8_t ep, uint8_t size);           // arm OUT endpoint
 | 
			
		||||
bool usbdrv_get_endpoint_interrupt_flag(uint8_t ep, uint8_t dir); // get endpoint interrupt flag
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user