/** Local function to handle outgoing bulk data @param [in] bEP @param [in] bEPStatus */ static void BulkIn(U8 bEP, U8 bEPStatus) { int i, iLen; if (_fifo_avail(&txfifo) == 0) { // no more data, disable further NAK interrupts until next USB frame USBHwNakIntEnable(0); return; } // get bytes from transmit FIFO into intermediate buffer for (i = 0; i < MAX_PACKET_SIZE; i++) { if (!_fifo_get(&txfifo, &abBulkBuf[i])) { break; } } iLen = i; // send over USB if (iLen > 0) { USBHwEPWrite(bEP, abBulkBuf, iLen); } }
/** Local function to handle outgoing bulk data @param [in] bEP @param [in] bEPStatus */ static void BulkIn(U8 bEP, U8 bEPStatus) { int i, iLen; // Verifica se não há data para enviar ao PC if (_fifo_avail(&txfifo) == 0) { // no more data, disable further NAK interrupts until next USB frame USBHwNakIntEnable(0); // não é gerada nenhuma interrupção sempre que o host tenta ler/escrever nos EPs mas este estão cheios/vazios. return; } // get bytes from transmit FIFO into intermediate buffer for (i = 0; i < MAX_PACKET_SIZE; i++) { if (!_fifo_get(&txfifo, &abBulkBuf[i])) { break; // sai do ciclo quando o fifo fica vazio, terminando a transferência de informação do &txfifo para &abBulkBuf[]. } } iLen = i; // send over USB if (iLen > 0) { USBHwEPWrite(bEP, abBulkBuf, iLen); } }
static void USBFrameHandler(U16 wFrame) { if (_fifo_avail(&txfifo) > 0) { // data available, enable NAK interrupt on bulk in USBHwNakIntEnable(INACK_BI); } }
//Atomic version int fifo_avail(fifo_t *fifo) { int t; NVIC_DisableIRQ(USB_IRQn); t = _fifo_avail(fifo); NVIC_EnableIRQ(USB_IRQn); return t; }
static void USBFrameHandler(U16 wFrame) { if (_fifo_avail(&txfifo) > 0) // Se há data no fifo de tx... { // data available, enable NAK interrupt on bulk in // // Caso esta interrupção não seja ligada, não há transmissão de dados, uma vez que a interrupão sobre o EP IN só // acontece após transferência com sucesso. É necessário activar esta interrupção para que seja chamada a BulkIn() // e acontecer a transferência. // Caso haja um RTOS, uma task pode ver regularmente quando o EP IN está vazio e fazer a transferência, em vez de // este USBFrame Interrupt. USBHwNakIntEnable(INACK_BI); } }