- ACM fixed, thread added, wakeup() removed
This commit is contained in:
		
							parent
							
								
									a977b32471
								
							
						
					
					
						commit
						983c8a8840
					
				
							
								
								
									
										75
									
								
								class/acm.c
									
									
									
									
									
								
							
							
						
						
									
										75
									
								
								class/acm.c
									
									
									
									
									
								
							@ -9,12 +9,15 @@
 | 
				
			|||||||
#include "acm.h"
 | 
					#include "acm.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <memory.h>
 | 
					#include <memory.h>
 | 
				
			||||||
 | 
					#include <stdint.h>
 | 
				
			||||||
#include <string.h>
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "../usb.h"
 | 
					#include "../usb.h"
 | 
				
			||||||
#include "../usb_device_types.h"
 | 
					#include "../usb_device_types.h"
 | 
				
			||||||
 | 
					#include "cmsis_os2.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <blocking_io/blocking_fifo.h>
 | 
					#include <blocking_io/blocking_fifo.h>
 | 
				
			||||||
 | 
					#include <strings.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// -------------------------
 | 
					// -------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -22,6 +25,42 @@ static Usb_AcmState acms = {0};                 ///< ACM module state
 | 
				
			|||||||
static uint8_t tx_buffer[USB_ACM_PCKT_BUFSIZE]; ///< Transmit buffer
 | 
					static uint8_t tx_buffer[USB_ACM_PCKT_BUFSIZE]; ///< Transmit buffer
 | 
				
			||||||
static uint8_t fifo_mem[USB_ACM_FIFO_MEM_SIZE]; ///< Memory assigned to the TX BFifo
 | 
					static uint8_t fifo_mem[USB_ACM_FIFO_MEM_SIZE]; ///< Memory assigned to the TX BFifo
 | 
				
			||||||
static BFifo fifo;                              ///< TX Blocking FIFO
 | 
					static BFifo fifo;                              ///< TX Blocking FIFO
 | 
				
			||||||
 | 
					static osThreadId_t th;                         ///< ACM thread
 | 
				
			||||||
 | 
					static osEventFlagsId_t flags;                  ///< Event flags
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define USB_ACM_DATA_IN_DONE (0x01)         ///< IN transfer done flag
 | 
				
			||||||
 | 
					#define USB_ACM_COMM_INIT (0x02)            ///< Communication has been initialized
 | 
				
			||||||
 | 
					#define USB_ACM_HOSTBOUND_DATA_AVAIL (0x04) ///< Hostbound data is available
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define USB_ACM_LOOP_TIMEOUT_TICKS (100) ///< Main loop timeout for interrupt status transmission
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// -------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void thread_usb_acm(void *arg) {
 | 
				
			||||||
 | 
					    osEventFlagsWait(flags, USB_ACM_COMM_INIT, 0, osWaitForever); // wait for communication to become initialized
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    osEventFlagsSet(flags, USB_ACM_DATA_IN_DONE); // assume we can write to the data endpoint
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    while (true) {
 | 
				
			||||||
 | 
					        uint32_t signals = osEventFlagsWait(flags, USB_ACM_HOSTBOUND_DATA_AVAIL, osFlagsWaitAny, USB_ACM_LOOP_TIMEOUT_TICKS);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (signals != osErrorTimeout) {                  // check timeout
 | 
				
			||||||
 | 
					            if (signals & USB_ACM_HOSTBOUND_DATA_AVAIL) { // data hostbound available
 | 
				
			||||||
 | 
					                do {
 | 
				
			||||||
 | 
					                    osEventFlagsWait(flags, USB_ACM_DATA_IN_DONE, osFlagsWaitAny, 1000);       // wait for the IN DONE flag
 | 
				
			||||||
 | 
					                    uint32_t readSize = bfifo_read(&fifo, tx_buffer, USB_ACM_PCKT_BUFSIZE); // read from the fifo
 | 
				
			||||||
 | 
					                    if (readSize > 0) {
 | 
				
			||||||
 | 
					                        uint32_t writeSize = usbcore_schedule_transmission(acms.ep_assignments.data_ep, tx_buffer, readSize); // write data acquired from the buffer
 | 
				
			||||||
 | 
					                        bfifo_pop(&fifo, writeSize, 0);                                                                       // pop with no blocking
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                } while (bfifo_get_used(&fifo) > 0);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        } else { // timeout
 | 
				
			||||||
 | 
					            // send an all-zero interrupt
 | 
				
			||||||
 | 
					            usbcore_schedule_transmission(acms.ep_assignments.control_ep, (const uint8_t *)&(acms.interrupt_data), sizeof(uint16_t));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// -------------------------
 | 
					// -------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -42,11 +81,20 @@ void usb_acm_init(const Usb_Acm_EpAssignments *as) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    // initialize an all-0 interrupt
 | 
					    // initialize an all-0 interrupt
 | 
				
			||||||
    acms.interrupt_data = 0;
 | 
					    acms.interrupt_data = 0;
 | 
				
			||||||
    acms.interrupt_pending = true;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // communication parameters have not been set
 | 
					    // communication parameters have not been set
 | 
				
			||||||
    acms.commInit = false;
 | 
					    acms.commInit = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // create flags
 | 
				
			||||||
 | 
					    flags = osEventFlagsNew(NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // create thread
 | 
				
			||||||
 | 
					    osThreadAttr_t attr;
 | 
				
			||||||
 | 
					    memset(&attr, 0, sizeof(osThreadAttr_t));
 | 
				
			||||||
 | 
					    attr.stack_size = 1024;
 | 
				
			||||||
 | 
					    attr.name = "acm";
 | 
				
			||||||
 | 
					    th = osThreadNew(thread_usb_acm, NULL, &attr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // from now on CDC module is considered initialized
 | 
					    // from now on CDC module is considered initialized
 | 
				
			||||||
    acms.moduleInit = true;
 | 
					    acms.moduleInit = true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -61,6 +109,9 @@ static void usb_cdc_review_comm_init() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    // combine the above criteria
 | 
					    // combine the above criteria
 | 
				
			||||||
    acms.commInit = lcOk && clsOk;
 | 
					    acms.commInit = lcOk && clsOk;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // signal the processing thread
 | 
				
			||||||
 | 
					    osEventFlagsSet(flags, USB_ACM_COMM_INIT);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int usb_acm_process_and_return(Usb_CallbackEvent *cbevt) {
 | 
					int usb_acm_process_and_return(Usb_CallbackEvent *cbevt) {
 | 
				
			||||||
@ -108,24 +159,11 @@ int usb_acm_process_and_return(Usb_CallbackEvent *cbevt) {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    case USB_CBEVT_IN: {
 | 
					    case USB_CBEVT_IN: {
 | 
				
			||||||
        if (cbevt->ep == acms.ep_assignments.control_ep) { // if notification feeding is requested
 | 
					        if (cbevt->ep == acms.ep_assignments.data_ep) {
 | 
				
			||||||
            if (acms.interrupt_pending) {
 | 
					            osEventFlagsSet(flags, USB_ACM_DATA_IN_DONE);
 | 
				
			||||||
                usbcore_schedule_transmission(acms.ep_assignments.control_ep, (const uint8_t *)&(acms.interrupt_data), sizeof(uint16_t)); // send ZLP
 | 
					 | 
				
			||||||
                acms.interrupt_pending = false;
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        ret = 0;
 | 
					        ret = 0;
 | 
				
			||||||
        } else if (cbevt->ep == acms.ep_assignments.data_ep) { // if data are requested
 | 
					        break;
 | 
				
			||||||
            ret = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // read from the fifo
 | 
					 | 
				
			||||||
            if (acms.commInit) {
 | 
					 | 
				
			||||||
                uint32_t readSize = bfifo_read(&fifo, tx_buffer, USB_ACM_PCKT_BUFSIZE);
 | 
					 | 
				
			||||||
                if (readSize > 0) {
 | 
					 | 
				
			||||||
                    uint32_t writeSize = usbcore_schedule_transmission(acms.ep_assignments.data_ep, tx_buffer, readSize); // write data acquired from the buffer
 | 
					 | 
				
			||||||
                    bfifo_pop(&fifo, writeSize, 0);                                                                       // pop with no blocking
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    default:
 | 
					    default:
 | 
				
			||||||
@ -138,11 +176,10 @@ int usb_acm_process_and_return(Usb_CallbackEvent *cbevt) {
 | 
				
			|||||||
void usb_acm_write(const uint8_t *data, uint32_t size) {
 | 
					void usb_acm_write(const uint8_t *data, uint32_t size) {
 | 
				
			||||||
    if (acms.moduleInit) {
 | 
					    if (acms.moduleInit) {
 | 
				
			||||||
        bfifo_push_all(&fifo, data, size);
 | 
					        bfifo_push_all(&fifo, data, size);
 | 
				
			||||||
        usbcore_wake_up_endpoint(acms.ep_assignments.data_ep, USB_IN);
 | 
					        osEventFlagsSet(flags, USB_ACM_HOSTBOUND_DATA_AVAIL);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * @fn void usb_acm_read_callback(const uint8_t *data, uint32_t size)
 | 
					 * @fn void usb_acm_read_callback(const uint8_t *data, uint32_t size)
 | 
				
			||||||
 * Callback function prototype for data reception. This function is
 | 
					 * Callback function prototype for data reception. This function is
 | 
				
			||||||
 | 
				
			|||||||
@ -82,7 +82,6 @@ typedef struct {
 | 
				
			|||||||
    Usb_Acm_LineCodingStruct line_coding;              ///< Line Coding
 | 
					    Usb_Acm_LineCodingStruct line_coding;              ///< Line Coding
 | 
				
			||||||
    Usb_Acm_ControlLineStateStruct control_line_state; ///< Control Line State
 | 
					    Usb_Acm_ControlLineStateStruct control_line_state; ///< Control Line State
 | 
				
			||||||
    uint16_t interrupt_data;                           ///< Data sent though the next transfer on the notification element
 | 
					    uint16_t interrupt_data;                           ///< Data sent though the next transfer on the notification element
 | 
				
			||||||
    bool interrupt_pending;                            ///< Interrupt data is valid and should be send in the next cycle
 | 
					 | 
				
			||||||
    bool moduleInit;                                   ///< CDC module is initialized
 | 
					    bool moduleInit;                                   ///< CDC module is initialized
 | 
				
			||||||
    bool commInit;                                     ///< Communication protocol is initialized
 | 
					    bool commInit;                                     ///< Communication protocol is initialized
 | 
				
			||||||
} Usb_AcmState;
 | 
					} Usb_AcmState;
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user