error_t samv71EthSendPacket(NetInterface *interface, const NetBuffer *buffer, size_t offset) { size_t length; //Retrieve the length of the packet length = netBufferGetLength(buffer) - offset; //Check the frame length if(length > SAMV71_ETH_TX_BUFFER_SIZE) { //The transmitter can accept another packet osSetEvent(&interface->nicTxEvent); //Report an error return ERROR_INVALID_LENGTH; } //Make sure the current buffer is available for writing if(!(txBufferDesc[txBufferIndex].status & GMAC_TX_USED)) return ERROR_FAILURE; //Copy user data to the transmit buffer netBufferRead(txBuffer[txBufferIndex], buffer, offset, length); //Set the necessary flags in the descriptor entry if(txBufferIndex < (SAMV71_ETH_TX_BUFFER_COUNT - 1)) { //Write the status word txBufferDesc[txBufferIndex].status = GMAC_TX_LAST | (length & GMAC_TX_LENGTH); //Point to the next buffer txBufferIndex++; } else { //Write the status word txBufferDesc[txBufferIndex].status = GMAC_TX_WRAP | GMAC_TX_LAST | (length & GMAC_TX_LENGTH); //Wrap around txBufferIndex = 0; } //Data synchronization barrier __DSB(); //Set the TSTART bit to initiate transmission GMAC->GMAC_NCR |= GMAC_NCR_TSTART; //Check whether the next buffer is available for writing if(txBufferDesc[txBufferIndex].status & GMAC_TX_USED) { //The transmitter can accept another packet osSetEvent(&interface->nicTxEvent); } //Successful processing return NO_ERROR; }
error_t rx63nEthSendPacket(NetInterface *interface, const NetBuffer *buffer, size_t offset) { //Retrieve the length of the packet size_t length = netBufferGetLength(buffer) - offset; //Check the frame length if(length > RX63N_ETH_TX_BUFFER_SIZE) { //The transmitter can accept another packet osSetEvent(&interface->nicTxEvent); //Report an error return ERROR_INVALID_LENGTH; } //Make sure the current buffer is available for writing if(txDmaDesc[txIndex].td0 & EDMAC_TD0_TACT) return ERROR_FAILURE; //Copy user data to the transmit buffer netBufferRead(txBuffer[txIndex], buffer, offset, length); //Write the number of bytes to send txDmaDesc[txIndex].td1 = (length << 16) & EDMAC_TD1_TBL; //Check current index if(txIndex < (RX63N_ETH_TX_BUFFER_COUNT - 1)) { //Give the ownership of the descriptor to the DMA engine txDmaDesc[txIndex].td0 = EDMAC_TD0_TACT | EDMAC_TD0_TFP_SOF | EDMAC_TD0_TFP_EOF | EDMAC_TD0_TWBI; //Point to the next descriptor txIndex++; } else { //Give the ownership of the descriptor to the DMA engine txDmaDesc[txIndex].td0 = EDMAC_TD0_TACT | EDMAC_TD0_TDLE | EDMAC_TD0_TFP_SOF | EDMAC_TD0_TFP_EOF | EDMAC_TD0_TWBI; //Wrap around txIndex = 0; } //Instruct the DMA to poll the transmit descriptor list EDMAC.EDTRR.BIT.TR = 1; //Check whether the next buffer is available for writing if(!(txDmaDesc[txIndex].td0 & EDMAC_TD0_TACT)) { //The transmitter can accept another packet osSetEvent(&interface->nicTxEvent); } //Successful write operation return NO_ERROR; }
error_t dm9000SendPacket(NetInterface *interface, const NetBuffer *buffer, size_t offset) { size_t i; uint16_t *p; //Point to the driver context Dm9000Context *context = (Dm9000Context *) interface->nicContext; //Retrieve the length of the packet size_t length = netBufferGetLength(buffer) - offset; //Check the frame length if(length > 1536) { //The transmitter can accept another packet osSetEvent(&interface->nicTxEvent); //Report an error return ERROR_INVALID_LENGTH; } //Copy user data netBufferRead(txBuffer, buffer, offset, length); //A dummy write is required before accessing FIFO dm9000WriteReg(DM9000_REG_MWCMDX, 0); //Select MWCMD register DM9000_INDEX_REG = DM9000_REG_MWCMD; //Point to the beginning of the buffer p = (uint16_t *) txBuffer; //Write data to the FIFO using 16-bit mode for(i = length; i > 1; i -= 2) DM9000_DATA_REG = *(p++); //Odd number of bytes? if(i > 0) DM9000_DATA_REG = *((uint8_t *) p); //Write the number of bytes to send dm9000WriteReg(DM9000_REG_TXPLL, LSB(length)); dm9000WriteReg(DM9000_REG_TXPLH, MSB(length)); //Clear interrupt flag dm9000WriteReg(DM9000_REG_ISR, ISR_PT); //Start data transfer dm9000WriteReg(DM9000_REG_TCR, TCR_TXREQ); //The packet was successfully written to FIFO context->queuedPackets++; //Successful processing return NO_ERROR; }
error_t rawSocketReceiveEthPacket(Socket *socket, void *data, size_t size, size_t *received, uint_t flags) { SocketQueueItem *queueItem; //The SOCKET_FLAG_DONT_WAIT enables non-blocking operation if(!(flags & SOCKET_FLAG_DONT_WAIT)) { //The receive queue is empty? if(!socket->receiveQueue) { //Set the events the application is interested in socket->eventMask = SOCKET_EVENT_RX_READY; //Reset the event object osResetEvent(&socket->event); //Leave critical section osReleaseMutex(&socketMutex); //Wait until an event is triggered osWaitForEvent(&socket->event, socket->timeout); //Enter critical section osAcquireMutex(&socketMutex); } } //Check whether the read operation timed out if(!socket->receiveQueue) { //No data can be read *received = 0; //Report a timeout error return ERROR_TIMEOUT; } //Point to the first item in the receive queue queueItem = socket->receiveQueue; //Copy data to user buffer *received = netBufferRead(data, queueItem->buffer, queueItem->offset, size); //If the SOCKET_FLAG_PEEK flag is set, the data is copied //into the buffer but is not removed from the input queue if(!(flags & SOCKET_FLAG_PEEK)) { //Remove the item from the receive queue socket->receiveQueue = queueItem->next; //Deallocate memory buffer netBufferFree(queueItem->buffer); } //Update the state of events rawSocketUpdateEvents(socket); //Successful read operation return NO_ERROR; }
error_t m2sxxxEthSendPacket(NetInterface *interface, const NetBuffer *buffer, size_t offset) { //Retrieve the length of the packet size_t length = netBufferGetLength(buffer) - offset; //Check the frame length if(length > M2SXXX_ETH_TX_BUFFER_SIZE) { //The transmitter can accept another packet osSetEvent(&interface->nicTxEvent); //Report an error return ERROR_INVALID_LENGTH; } //Make sure the current buffer is available for writing if(!(txCurDmaDesc->size & DMA_DESC_EMPTY_FLAG)) return ERROR_FAILURE; //Copy user data to the transmit buffer netBufferRead((uint8_t *) txCurDmaDesc->addr, buffer, offset, length); //Set the packet length and give the ownership of the descriptor to the DMA txCurDmaDesc->size = length & DMA_DESC_SIZE_MASK; //Check whether DMA transfers are suspended if(!(MAC->DMA_TX_CTRL & DMA_TX_CTRL_TX_EN)) { //Set the start position in the ring buffer MAC->DMA_TX_DESC = (uint32_t) txCurDmaDesc; } //Instruct the DMA controller to transfer the packet MAC->DMA_TX_CTRL = DMA_TX_CTRL_TX_EN; //Point to the next descriptor in the list txCurDmaDesc = (M2sxxxTxDmaDesc *) txCurDmaDesc->next; //Check whether the next buffer is available for writing if(txCurDmaDesc->size & DMA_DESC_EMPTY_FLAG) { //The transmitter can accept another packet osSetEvent(&interface->nicTxEvent); } //Data successfully written return NO_ERROR; }
error_t stm32f4x7EthSendPacket(NetInterface *interface, const NetBuffer *buffer, size_t offset) { //Retrieve the length of the packet size_t length = netBufferGetLength(buffer) - offset; //Check the frame length if(length > STM32F4X7_ETH_TX_BUFFER_SIZE) { //The transmitter can accept another packet osSetEvent(&interface->nicTxEvent); //Report an error return ERROR_INVALID_LENGTH; } //Make sure the current buffer is available for writing if(txCurDmaDesc->tdes0 & ETH_TDES0_OWN) return ERROR_FAILURE; //Copy user data to the transmit buffer netBufferRead((uint8_t *) txCurDmaDesc->tdes2, buffer, offset, length); //Write the number of bytes to send txCurDmaDesc->tdes1 = length & ETH_TDES1_TBS1; //Set LS and FS flags as the data fits in a single buffer txCurDmaDesc->tdes0 |= ETH_TDES0_LS | ETH_TDES0_FS; //Give the ownership of the descriptor to the DMA txCurDmaDesc->tdes0 |= ETH_TDES0_OWN; //Clear TBUS flag to resume processing ETH->DMASR = ETH_DMASR_TBUS; //Instruct the DMA to poll the transmit descriptor list ETH->DMATPDR = 0; //Point to the next descriptor in the list txCurDmaDesc = (Stm32f4x7TxDmaDesc *) txCurDmaDesc->tdes3; //Check whether the next buffer is available for writing if(!(txCurDmaDesc->tdes0 & ETH_TDES0_OWN)) { //The transmitter can accept another packet osSetEvent(&interface->nicTxEvent); } //Data successfully written return NO_ERROR; }
error_t a2fxxxm3EthSendPacket(NetInterface *interface, const NetBuffer *buffer, size_t offset) { //Retrieve the length of the packet size_t length = netBufferGetLength(buffer) - offset; //Check the frame length if(length > A2FXXXM3_ETH_TX_BUFFER_SIZE) { //The transmitter can accept another packet osSetEvent(&interface->nicTxEvent); //Report an error return ERROR_INVALID_LENGTH; } //Make sure the current buffer is available for writing if(txCurDmaDesc->tdes0 & TDES0_OWN) return ERROR_FAILURE; //Copy user data to the transmit buffer netBufferRead((uint8_t *) txCurDmaDesc->tdes2, buffer, offset, length); //Write the number of bytes to send txCurDmaDesc->tdes1 = length & TDES1_TBS1_MASK; //Set LS and FS flags as the data fits in a single buffer txCurDmaDesc->tdes1 |= TDES1_IC | TDES1_LS | TDES1_FS | TDES1_TCH; //Give the ownership of the descriptor to the DMA txCurDmaDesc->tdes0 |= TDES0_OWN; //Instruct the DMA to poll the transmit descriptor list MAC->CSR1 = 1; //Point to the next descriptor in the list txCurDmaDesc = (A2fxxxm3TxDmaDesc *) txCurDmaDesc->tdes3; //Check whether the next buffer is available for writing if(!(txCurDmaDesc->tdes0 & TDES0_OWN)) { //The transmitter can accept another packet osSetEvent(&interface->nicTxEvent); } //Data successfully written return NO_ERROR; }
error_t wilc1000SendPacket(NetInterface *interface, const NetBuffer *buffer, size_t offset) { int8_t status; size_t length; //Retrieve the length of the packet length = netBufferGetLength(buffer) - offset; //Check the frame length if(length > WILC1000_TX_BUFFER_SIZE) { //The transmitter can accept another packet osSetEvent(&interface->nicTxEvent); //Report an error return ERROR_INVALID_LENGTH; } //Copy user data to the transmit buffer netBufferRead(txBuffer, buffer, offset, length); //STA or AP mode? if(interface == wilc1000StaInterface) { //Send packet status = m2m_wifi_send_ethernet_pkt(txBuffer, length); } else { status = m2m_wifi_send_ethernet_pkt_ifc1(txBuffer, length); } //The transmitter can accept another packet osSetEvent(&interface->nicTxEvent); //Return status code if(status == M2M_SUCCESS) return NO_ERROR; else return ERROR_FAILURE; }