/** ISR to handle the reloading of the data endpoint with the next sample. */ ISR(TIMER0_COMPA_vect, ISR_BLOCK) { uint8_t PrevEndpoint = Endpoint_GetCurrentEndpoint(); /* Check if the sample reload timer period has elapsed, and that the USB bus is ready for a new sample */ if (Audio_Device_IsReadyForNextSample(&Microphone_Audio_Interface)) { int16_t AudioSample; #if defined(USE_TEST_TONE) static uint8_t SquareWaveSampleCount; static int16_t CurrentWaveValue; /* In test tone mode, generate a square wave at 1/256 of the sample rate */ if (SquareWaveSampleCount++ == 0xFF) CurrentWaveValue ^= 0x8000; /* Only generate audio if the board button is being pressed */ AudioSample = (Buttons_GetStatus() & BUTTONS_BUTTON1) ? CurrentWaveValue : 0; #else /* Audio sample is ADC value scaled to fit the entire range */ AudioSample = ((SAMPLE_MAX_RANGE / ADC_MAX_RANGE) * ADC_GetResult()); #if defined(MICROPHONE_BIASED_TO_HALF_RAIL) /* Microphone is biased to half rail voltage, subtract the bias from the sample value */ AudioSample -= (SAMPLE_MAX_RANGE / 2); #endif #endif Audio_Device_WriteSample16(&Microphone_Audio_Interface, AudioSample); } Endpoint_SelectEndpoint(PrevEndpoint); }
void sendControlMessage(uint8_t* data, uint8_t length) { uint8_t previousEndpoint = Endpoint_GetCurrentEndpoint(); Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP); Endpoint_ClearSETUP(); Endpoint_Write_Control_Stream_LE(data, length); Endpoint_ClearOUT(); Endpoint_SelectEndpoint(previousEndpoint); }
ISR(USB_COM_vect, ISR_BLOCK) { uint8_t PrevSelectedEndpoint = Endpoint_GetCurrentEndpoint(); USB_USBTask(); USB_INT_Clear(USB_INT_ENDPOINT_SETUP); Endpoint_SelectEndpoint(PrevSelectedEndpoint); }
/* * Stall all endpoints and set a flag indicating any current transfers * should be aborted. IO loops will see this flag in TimerWorker(). */ void SetAbortState() { uint8_t origEndpoint = Endpoint_GetCurrentEndpoint(); doDeviceReset = true; Endpoint_SelectEndpoint(XUM_BULK_OUT_ENDPOINT); Endpoint_StallTransaction(); Endpoint_SelectEndpoint(XUM_BULK_IN_ENDPOINT); Endpoint_StallTransaction(); Endpoint_SelectEndpoint(origEndpoint); }
ISR(USB_COM_vect, ISR_BLOCK) { uint8_t PrevSelectedEndpoint = Endpoint_GetCurrentEndpoint(); USB_INT_Disable(USB_INT_RXSTPI); sei(); USB_USBTask(); USB_INT_Enable(USB_INT_RXSTPI); USB_INT_Clear(USB_INT_RXSTPI); Endpoint_SelectEndpoint(PrevSelectedEndpoint); }
static void USB_DeviceTask(void) { if (USB_DeviceState != DEVICE_STATE_Unattached) { uint8_t PrevEndpoint = Endpoint_GetCurrentEndpoint(); Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP); if (Endpoint_IsSETUPReceived()) USB_Device_ProcessControlRequest(); Endpoint_SelectEndpoint(PrevEndpoint); } }
ISR(USB_COM_vect, ISR_BLOCK) { uint8_t PrevSelectedEndpoint = Endpoint_GetCurrentEndpoint(); Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP); USB_INT_Disable(USB_INT_RXSTPI); GlobalInterruptEnable(); USB_Device_ProcessControlRequest(); Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP); USB_INT_Enable(USB_INT_RXSTPI); Endpoint_SelectEndpoint(PrevSelectedEndpoint); }
ISR(USB_COM_vect, ISR_BLOCK) { uint8_t PrevSelectedEndpoint = Endpoint_GetCurrentEndpoint(); Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP); USB_INT_Disable(USB_INT_RXSTPI); NONATOMIC_BLOCK(NONATOMIC_FORCEOFF) { USB_Device_ProcessControlRequest(); } Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP); USB_INT_Enable(USB_INT_RXSTPI); Endpoint_SelectEndpoint(PrevSelectedEndpoint); }
void readFromHost(UsbDevice* usbDevice, bool (*callback)(uint8_t*)) { uint8_t previousEndpoint = Endpoint_GetCurrentEndpoint(); Endpoint_SelectEndpoint(OUT_ENDPOINT_NUMBER); while(Endpoint_IsOUTReceived()) { for(int i = 0; i < usbDevice->outEndpointSize; i++) { if(!QUEUE_PUSH(uint8_t, &usbDevice->receiveQueue, Endpoint_Read_8())) { debug("Dropped write from host -- queue is full"); } } processQueue(&usbDevice->receiveQueue, callback); Endpoint_ClearOUT(); } Endpoint_SelectEndpoint(previousEndpoint); }
/* * The Linux and OSX call the configuration changed entry each time * a transaction is started (e.g., multiple runs of cbmctrl status). * We need to reset the endpoints before reconfiguring them, otherwise * we get a hang the second time through. * * We keep the original endpoint selected after returning. */ void USB_ResetConfig() { static uint8_t endpoints[] = { XUM_BULK_IN_ENDPOINT, XUM_BULK_OUT_ENDPOINT, 0, }; uint8_t lastEndpoint, *endp; lastEndpoint = Endpoint_GetCurrentEndpoint(); for (endp = endpoints; *endp != 0; endp++) { Endpoint_SelectEndpoint(*endp); Endpoint_ResetFIFO(*endp); Endpoint_ResetDataToggle(); if (Endpoint_IsStalled()) Endpoint_ClearStall(); } Endpoint_SelectEndpoint(lastEndpoint); }
void USBSerial::flush() { uint8_t prevEndpoint = Endpoint_GetCurrentEndpoint(); Endpoint_SelectEndpoint(CDC_TX_EPADDR); bool IsFull = !Endpoint_IsReadWriteAllowed(); Endpoint_ClearIN(); /* Send an empty packet to ensure that the host does not buffer data sent to it */ if (IsFull) { while (!Endpoint_IsINReady() && USB_DeviceState == DEVICE_STATE_Configured) { USB_USBTask(); } Endpoint_ClearIN(); } //Endpoint_WaitUntilReady(); while (!Endpoint_IsINReady() && USB_DeviceState == DEVICE_STATE_Configured) { USB_USBTask(); } Endpoint_SelectEndpoint(prevEndpoint); }
/* Private: Flush any queued data out to the USB host. */ static void sendToHost(UsbDevice* usbDevice) { if(!usbDevice->configured) { return; } uint8_t previousEndpoint = Endpoint_GetCurrentEndpoint(); Endpoint_SelectEndpoint(IN_ENDPOINT_NUMBER); if(!Endpoint_IsINReady() || QUEUE_EMPTY(uint8_t, &usbDevice->sendQueue)) { return; } // get bytes from transmit FIFO into intermediate buffer int byteCount = 0; while(!QUEUE_EMPTY(uint8_t, &usbDevice->sendQueue) && byteCount < USB_SEND_BUFFER_SIZE) { usbDevice->sendBuffer[byteCount++] = QUEUE_POP(uint8_t, &usbDevice->sendQueue); } if(byteCount > 0) { Endpoint_Write_Stream_LE(usbDevice->sendBuffer, byteCount, NULL); } Endpoint_ClearIN(); Endpoint_SelectEndpoint(previousEndpoint); }
static bool USB_BulkWorker() { uint8_t cmdBuf[XUM_CMDBUF_SIZE], statusBuf[XUM_STATUSBUF_SIZE]; int8_t status; /* * If we are not connected to the host or a command has not yet * been sent, no more processing is required. */ if (USB_DeviceState != DEVICE_STATE_Configured) return false; Endpoint_SelectEndpoint(XUM_BULK_OUT_ENDPOINT); if (!Endpoint_IsReadWriteAllowed()) return false; #ifdef DEBUG // Dump the status of both endpoints before getting the command Endpoint_SelectEndpoint(XUM_BULK_IN_ENDPOINT); DEBUGF(DBG_INFO, "bsti %x %x %x %x %x %x %x %x\n", Endpoint_GetCurrentEndpoint(), Endpoint_BytesInEndpoint(), Endpoint_IsEnabled(), Endpoint_IsReadWriteAllowed(), Endpoint_IsConfigured(), Endpoint_IsINReady(), Endpoint_IsOUTReceived(), Endpoint_IsStalled()); Endpoint_SelectEndpoint(XUM_BULK_OUT_ENDPOINT); DEBUGF(DBG_INFO, "bsto %x %x %x %x %x %x %x %x\n", Endpoint_GetCurrentEndpoint(), Endpoint_BytesInEndpoint(), Endpoint_IsEnabled(), Endpoint_IsReadWriteAllowed(), Endpoint_IsConfigured(), Endpoint_IsINReady(), Endpoint_IsOUTReceived(), Endpoint_IsStalled()); #endif // Read in the command from the host now that one is ready. if (!USB_ReadBlock(cmdBuf, sizeof(cmdBuf))) { board_set_status(STATUS_ERROR); return false; } // Allow commands to leave the extended status untouched memset(statusBuf, 0, sizeof(statusBuf)); /* * Decode and process the command. * usbHandleBulk() stores its extended result in the output buffer, * up to XUM_STATUSBUF_SIZE. * * Return values: * >0: completed ok, send the return value and extended status * 0: completed ok, don't send any status * -1: error, no status */ status = usbHandleBulk(cmdBuf, statusBuf); if (status > 0) { statusBuf[0] = status; USB_WriteBlock(statusBuf, sizeof(statusBuf)); } else if (status < 0) { DEBUGF(DBG_ERROR, "usbblk err\n"); board_set_status(STATUS_ERROR); Endpoint_StallTransaction(); return false; } return true; }
/** ISR for the general Pipe/Endpoint interrupt vector. This ISR fires when an endpoint's status changes (such as * a packet has been received) on an endpoint with its corresponding ISR enabling bits set. This is used to send * HID packets to the host each time the HID interrupt endpoints polling period elapses, as managed by the USB * controller. */ ISR(ENDPOINT_PIPE_vect, ISR_BLOCK) { /* Save previously selected endpoint before selecting a new endpoint */ uint8_t PrevSelectedEndpoint = Endpoint_GetCurrentEndpoint(); #if defined(INTERRUPT_CONTROL_ENDPOINT) /* Check if the control endpoint has received a request */ if (Endpoint_HasEndpointInterrupted(ENDPOINT_CONTROLEP)) { /* Clear the endpoint interrupt */ Endpoint_ClearEndpointInterrupt(ENDPOINT_CONTROLEP); /* Process the control request */ USB_USBTask(); /* Handshake the endpoint setup interrupt - must be after the call to USB_USBTask() */ USB_INT_Clear(ENDPOINT_INT_SETUP); } #endif #if defined(INTERRUPT_DATA_ENDPOINT) /* Check if Generic IN endpoint has interrupted */ if (Endpoint_HasEndpointInterrupted(GENERIC_IN_EPNUM)) { /* Select the Generic IN Report Endpoint */ Endpoint_SelectEndpoint(GENERIC_IN_EPNUM); /* Clear the endpoint IN interrupt flag */ USB_INT_Clear(ENDPOINT_INT_IN); /* Clear the Generic IN Report endpoint interrupt and select the endpoint */ Endpoint_ClearEndpointInterrupt(GENERIC_IN_EPNUM); /* Create a temporary buffer to hold the report to send to the host */ uint8_t GenericData[GENERIC_REPORT_SIZE]; /* Create Generic Report Data */ CreateGenericHIDReport(GenericData); /* Write Generic Report Data */ Endpoint_Write_Stream_LE(&GenericData, sizeof(GenericData)); /* Finalize the stream transfer to send the last packet */ Endpoint_ClearIN(); } /* Check if Generic OUT endpoint has interrupted */ if (Endpoint_HasEndpointInterrupted(GENERIC_OUT_EPNUM)) { /* Select the Generic OUT Report Endpoint */ Endpoint_SelectEndpoint(GENERIC_OUT_EPNUM); /* Clear the endpoint OUT Interrupt flag */ USB_INT_Clear(ENDPOINT_INT_OUT); /* Clear the Generic OUT Report endpoint interrupt and select the endpoint */ Endpoint_ClearEndpointInterrupt(GENERIC_OUT_EPNUM); /* Create a temporary buffer to hold the read in report from the host */ uint8_t GenericData[GENERIC_REPORT_SIZE]; /* Read Generic Report Data */ Endpoint_Read_Stream_LE(&GenericData, sizeof(GenericData)); /* Process Generic Report Data */ ProcessGenericHIDReport(GenericData); /* Finalize the stream transfer to send the last packet */ Endpoint_ClearOUT(); } #endif /* Restore previously selected endpoint */ Endpoint_SelectEndpoint(PrevSelectedEndpoint); }