//**************************************************************************** // // This function will print out to the console UART and not the echo UART. // //**************************************************************************** void CommandPrint(const char *pcStr) { int iIdx; const char cCR = 0xd; iIdx = 0; while(pcStr[iIdx] != 0) { // // Wait for space for two bytes in case there is a need to send out // the line feed plus the carriage return. // while(USBBufferSpaceAvailable(&g_sTxBuffer) < 2) { } // // Print the next character. // USBBufferWrite(&g_sTxBuffer, (const unsigned char *)&pcStr[iIdx], 1); // // If this is a line feed then send a carriage return as well. // if(pcStr[iIdx] == 0xa) { USBBufferWrite(&g_sTxBuffer, (const unsigned char *)&cCR, 1); } iIdx++; } }
/* * ======== txData ======== */ static uint32_t txData(const uint8_t *pStr, uint32_t length) { unsigned long buffAvailSize; uint32_t bufferedCount = 0; uint32_t sendCount = 0; uint8_t *sendPtr; while (bufferedCount != length) { /* Determine the buffer size available */ buffAvailSize = USBBufferSpaceAvailable(&txBuffer); /* Determine how much needs to be sent */ if ((length - bufferedCount) > buffAvailSize) { sendCount = buffAvailSize; } else { sendCount = length - bufferedCount; } /* Adjust the pointer to the data */ sendPtr = (uint8_t *)pStr + bufferedCount; /* Place the contents into the USB BUffer */ bufferedCount += USBBufferWrite(&txBuffer, sendPtr, sendCount); } return (bufferedCount); }
/****************************************************************************** * * * \brief Read as many characters from the UART FIFO as we can and move the * * into the CDC transmit buffer.\n * * * * \param none. * * * * \return UART error flags read during data reception. * * * ******************************************************************************/ static int ReadUARTData(void) { int lChar, lErrors; unsigned char ucChar; unsigned int ulSpace; /* Clear our error indicator. */ lErrors = 0; /* How much space do we have in the buffer? */ ulSpace = USBBufferSpaceAvailable((tUSBBuffer *)&g_sTxBuffer); /* Read data from the UART FIFO until there is none left or we run out of space in our receive buffer. */ while(ulSpace && UARTCharsAvail(USB_UART_BASE)) { /* Read a character from the UART FIFO into the ring buffer if no errors are reported. */ lChar = UARTCharGetNonBlocking(USB_UART_BASE); /* If the character did not contain any error notifications, copy it to the output buffer. */ if(!(lChar & ~0xFF)) { ucChar = (unsigned char)(lChar & 0xFF); USBBufferWrite((tUSBBuffer *)&g_sTxBuffer, (unsigned char *)&ucChar, 1); /* Decrement the number of bytes we know the buffer can accept. */ ulSpace--; } else { /* Update our error accumulator. */ lErrors |= lChar; } /* Update our count of bytes received via the UART. */ g_ulUARTRxCount++; } /* Pass back the accumulated error indicators. */ return(lErrors); }
//***************************************************************************** // // Read as many characters from the UART FIFO as possible and move them into // the CDC transmit buffer. // // \return Returns UART error flags read during data reception. // //***************************************************************************** static long ReadUARTData(void) { long lChar, lErrors; unsigned char ucChar; unsigned long ulSpace; // // Clear the error indicator. // lErrors = 0; // // How much space is available in the buffer? // ulSpace = USBBufferSpaceAvailable(&g_sTxBuffer); // // Read data from the UART FIFO until there is none left or there is no // more space in the receive buffer. // while(ulSpace && ROM_UARTCharsAvail(UART0_BASE)) { // // Read a character from the UART FIFO into the ring buffer if no // errors are reported. // lChar = ROM_UARTCharGetNonBlocking(UART0_BASE); // // If the character did not contain any error notifications, // copy it to the output buffer. // if(!(lChar & ~0xFF)) { ucChar = (unsigned char)(lChar & 0xFF); USBBufferWrite(&g_sTxBuffer, &ucChar, 1); // // Decrement the number of bytes the buffer can accept. // ulSpace--; } else { // // Update the error accumulator. // lErrors |= lChar; } } // // Pass back the accumulated error indicators. // return(lErrors); }
void platform_s_uart_send( unsigned id, u8 data ) { #ifdef BUILD_USB_CDC if( id == CDC_UART_ID ) USBBufferWrite( &g_sTxBuffer, &data, 1 ); else #endif MAP_UARTCharPut( uart_base[ id ], data ); }
/********************************************************************************************************************** * * Subrotina destinada a enviar dados para o display via UART2 * **********************************************************************************************************************/ void send_usb(void){ uint8_t count; checksum_calc_usb(); // Rotina de calculo de CheckSum USBBufferWrite(&g_sTxBuffer, &MensagemUsb.CMD, 1); USBBufferWrite(&g_sTxBuffer, &MensagemUsb.NDADO, 1); if(MensagemUsb.NDADO > 0) { for(count = 0; count < MensagemUsb.NDADO; count++) { USBBufferWrite(&g_sTxBuffer, &MensagemUsb.DADO[count], 1); } } USBBufferWrite(&g_sTxBuffer, &MensagemUsb.CKS, 1); }
// * USBChalkBusSendException ************************************************* // * Sends an exception to the master. * // * * // * offending_function should be the function code that caused the exception * // * code should be the exception code that should be sent to the master, * // * it's value should be one of CBUS_EX_CODE_*. * // **************************************************************************** void USBChalkBusSendException(unsigned char offending_function, unsigned char code) { cbus_slave_exception_t* cbus_exception; // will use this to build an exception cbus_exception = (cbus_slave_exception_t*)ChalkBusBuff; // use ChalkBusBuff to build the exception cbus_exception->function_code = offending_function | CBUS_FN_CODE_EXCEPTION; // exception signaled by setting msb of offending function code cbus_exception->exception_code = code; // load the exception code if(g_bUSBDevConnected) // send exception if there is a device to listen { USBBufferWrite((tUSBBuffer *)&g_sTxBuffer,(unsigned char*)ChalkBusBuff, sizeof(cbus_slave_exception_t)); // queue the exception to send } }
/* * ======== USBCDCD_LoggerIdle_sendData ======== */ int USBCDCD_LoggerIdle_sendData(unsigned char *pStr, int length) { unsigned int bufAvailSize; /* Determine the buffer size available and length to send */ bufAvailSize = USBBufferSpaceAvailable(&txBuffer); if (!bufAvailSize || state != USBCDCD_STATE_IDLE) { return (0); } else if (bufAvailSize < length) { /* Write largest multiple of 4 bytes */ length = bufAvailSize - (bufAvailSize % 4); } /* Place the contents into the USB BUffer */ return (USBBufferWrite(&txBuffer, pStr, length)); }
//***************************************************************************** // // Writes a character to the USB interface. // //***************************************************************************** void USBIFWrite(unsigned char ucChar) { // // Delay until there is some space in the output buffer. // while(g_bUSBConnected) { if(USBBufferSpaceAvailable(&g_sTxBuffer) != 0) { break; } } // // If there is still a USB connection, write this character into the output // buffer. // if(g_bUSBConnected) { USBBufferWrite(&g_sTxBuffer, &ucChar, 1); } }
//***************************************************************************** // // Read as many characters from the UART FIFO as we can and move them into // the CDC transmit buffer. // // \return Returns UART error flags read during data reception. // //***************************************************************************** static int32_t ReadUARTData(void) { int32_t i32Char, i32Errors; uint8_t ui8Char; uint32_t ui32Space; // // Clear our error indicator. // i32Errors = 0; // // How much space do we have in the buffer? // ui32Space = USBBufferSpaceAvailable((tUSBBuffer *)&g_sTxBuffer); // // Read data from the UART FIFO until there is none left or we run // out of space in our receive buffer. // while(ui32Space && ROM_UARTCharsAvail(USB_UART_BASE)) { // // Read a character from the UART FIFO into the ring buffer if no // errors are reported. // i32Char = ROM_UARTCharGetNonBlocking(USB_UART_BASE); // // If the character did not contain any error notifications, // copy it to the output buffer. // if(!(i32Char & ~0xFF)) { ui8Char = (uint8_t)(i32Char & 0xFF); USBBufferWrite((tUSBBuffer *)&g_sTxBuffer, (uint8_t *)&ui8Char, 1); // // Decrement the number of bytes we know the buffer can accept. // ui32Space--; } else { #ifdef DEBUG // // Increment our receive error counter. // g_ui32UARTRxErrors++; #endif // // Update our error accumulator. // i32Errors |= i32Char; } // // Update our count of bytes received via the UART. // g_ui32UARTRxCount++; } // // Pass back the accumulated error indicators. // return(i32Errors); }
//**************************************************************************** // // Handles CDC driver notifications related to the receive channel (data from // the USB host). // // \param pvCBData is the client-supplied callback data value for this // channel. // \param ulEvent identifies the event we are being notified about. // \param ulMsgValue is an event-specific value. // \param pvMsgData is an event-specific pointer. // // This function is called by the CDC driver to notify us of any events // related to operation of the receive data channel (the OUT channel carrying // data from the USB host). // // \return The return value is event-specific. // //**************************************************************************** unsigned long RxHandler(void *pvCBData, unsigned long ulEvent, unsigned long ulMsgValue, void *pvMsgData) { unsigned char ucChar; const tUSBDCDCDevice *psCDCDevice; const tUSBBuffer *pBufferRx; const tUSBBuffer *pBufferTx; // // Which event are we being sent? // switch(ulEvent) { // // A new packet has been received. // case USB_EVENT_RX_AVAILABLE: { // // Create a device pointer. // psCDCDevice = (const tUSBDCDCDevice *)pvCBData; pBufferRx = (const tUSBBuffer *)psCDCDevice->pvRxCBData; pBufferTx = (const tUSBBuffer *)psCDCDevice->pvTxCBData; // // Keep reading and processing characters as long as there are new // ones in the buffer. // while(USBBufferRead(pBufferRx, (unsigned char *)&g_pcCmdBuf[ulCmdIdx], 1)) { // // If this is a backspace character, erase the last thing typed // assuming there's something there to type. // if(g_pcCmdBuf[ulCmdIdx] == 0x08) { // // If our current command buffer has any characters in it, // erase the last one. // if(ulCmdIdx) { // // Delete the last character. // ulCmdIdx--; // // Send a backspace, a space and a further backspace so // that the character is erased from the terminal too. // USBBufferWrite(pBufferTx, (unsigned char *)g_pcBackspace, 3); } } else { // // Feed some the new character into the UART TX FIFO. // USBBufferWrite(pBufferTx, (unsigned char *)&g_pcCmdBuf[ulCmdIdx], 1); // // If this was a line feed then put out a carriage return // as well. // if(g_pcCmdBuf[ulCmdIdx] == 0xd) { // // Set a line feed. // ucChar = 0xa; USBBufferWrite(pBufferTx, &ucChar, 1); // // Indicate that a command has been received. // HWREGBITW(&g_ulFlags, FLAG_COMMAND_RECEIVED) = 1; g_pcCmdBuf[ulCmdIdx] = 0; ulCmdIdx = 0; } // // Only increment if the index has not reached the end of // the buffer and continually overwrite the last value if // the buffer does attempt to overflow. // else if(ulCmdIdx < CMD_BUF_SIZE) { ulCmdIdx++; } } } break; } // // We are being asked how much unprocessed data we have still to // process. We return 0 if the UART is currently idle or 1 if it is // in the process of transmitting something. The actual number of // bytes in the UART FIFO is not important here, merely whether or // not everything previously sent to us has been transmitted. // case USB_EVENT_DATA_REMAINING: { // // Get the number of bytes in the buffer and add 1 if some data // still has to clear the transmitter. // return(0); } // // We are being asked to provide a buffer into which the next packet // can be read. We do not support this mode of receiving data so let // the driver know by returning 0. The CDC driver should not be // sending this message but this is included just for illustration and // completeness. // case USB_EVENT_REQUEST_BUFFER: { return(0); } // // We don't expect to receive any other events. Ignore any that show // up in a release build or hang in a debug build. // default: { break; } } return(0); }
//***************************************************************************** // // Handles CDC driver notifications related to the receive channel (data from // the USB host). // // \param ulCBData is the client-supplied callback data value for this channel. // \param ulEvent identifies the notification event. // \param ulMsgValue is an event-specific value. // \param pvMsgData is an event-specific pointer. // // This function is called by the CDC driver to notify us of any events // related to operation of the receive data channel (the OUT channel carrying // data from the USB host). // // \return The return value is event-specific. // //***************************************************************************** static unsigned long RxHandler(void *pvCBData, unsigned long ulEvent, unsigned long ulMsgValue, void *pvMsgData) { // // Which event was sent? // switch(ulEvent) { // // A new packet has been received. // case USB_EVENT_RX_AVAILABLE: { // // Since data has been received, see if the game is already being // played. // if(g_ulGameIF == GAME_IF_NONE) { // // The game is not being played, so select the USB interface. // g_ulGameIF = GAME_IF_USB; // // Read and discard the character used to activate the game. // USBBufferRead(&g_sRxBuffer, (unsigned char *)&ulEvent, 1); } // // Otherwise, see if the game is being played on an interface other // than USB. // else if(g_ulGameIF != GAME_IF_USB) { // // Write the error message to the USB interface. // USBBufferWrite(&g_sTxBuffer, g_pucErrorMessage, sizeof(g_pucErrorMessage)); // // Read and discard all data that was received over USB. // while(USBBufferDataAvailable(&g_sRxBuffer) != 0) { USBBufferRead(&g_sRxBuffer, (unsigned char *)&ulEvent, 1); } } break; } // // This is a request for how much unprocessed data is still waiting to // be processed. Return 0 if the UART is currently idle or 1 if it is // in the process of transmitting something. The actual number of // bytes in the UART FIFO is not important here, merely whether or // not everything previously sent to us has been transmitted. // case USB_EVENT_DATA_REMAINING: { // // Get the number of bytes in the buffer and add 1 if some data // still has to clear the transmitter. // return(0); } // // This is a request for a buffer into which the next packet can be // read. This mode of receiving data is not supported so let the // driver know by returning 0. The CDC driver should not be sending // this message but this is included just for illustration and // completeness. // case USB_EVENT_REQUEST_BUFFER: { return(0); } // // Other events can be safely ignored. // default: { break; } } return(0); }
// * USBChalkBusPoll ********************************************************** // * Handle communication requests from ChalkBus master. * // * * // * Communication protocol based off of a subset of the Modicon Modbus RTU * // * protocol developed by Modicon, Inc. * // * * // * Note: Among other changes, multi-byte value endianness has been changed * // * to little endian in the ChalkBus implementation for efficient * // * compatibility with the Cortex-M4 core's native little-endian byte * // * order. * // * * // * See structures above (cbus_*_t) for definition of packet structures for * // * different functions. * // * * // * Function codes: * // * 0x03: read registers (pc reading from lm4f) * // * 0x10: multiple register set (pc writing to lm4f) * // * * // * Exception signaling: * // * Offending function code or-ed with 0x80 (msb set), see structure above * // * (cbus_slave_exception_t) for return format. * // * * // * Register read/write from ChalkBusRegs[]. * // * Note: This driver is not written to handle multi-packet transmissions, * // * overall package size (header, data) must fit within a 64B USB bulk * // * transmission. * // **************************************************************************** void USBChalkBusPoll(void) { unsigned long buffer_bytes; // bytes received from/accepted by buffer cbus_function_read_write_t* cbus_rw_header; // header for reading/writing a if(!g_bUSBRxAvailable) // if no Rx is available { return; // exit now (we only send solicited responses) } // else new Rx is in the buffer, let's handle it buffer_bytes = USBBufferRead((tUSBBuffer *)&g_sRxBuffer, (unsigned char*)ChalkBusBuff, CBUS_BUFFER_SIZE); //buffer_bytes = USBDCDCPacketRead(&g_sCDCDevice,unsigned char *pcData,unsigned long ulLength,tBoolean bLast) // read data in from the receive buffer g_bUSBRxAvailable = false; // we have read the new Rx, no more available if(buffer_bytes == 0) // cancel, there wasn't actually any data { return; } // find out what kind of packet this is, validate it cbus_rw_header = (cbus_function_read_write_t*)ChalkBusBuff; // guess that this function is either read or write to save doing this cast in both cases switch(*((unsigned char*)ChalkBusBuff)) // read function code { case CBUS_FN_CODE_READ: // function read case CBUS_FN_CODE_WRITE: // function write, same validation steps { if((CBUS_FN_HDR_SIZE_RD_WR > buffer_bytes) || (CBUS_FN_HDR_SIZE_RD_WR + cbus_rw_header->data_bytes != buffer_bytes)) { USBChalkBusSendException(cbus_rw_header->function_code, CBUS_EX_CODE_NAK); // throw exception, too few bytes even for header or bytes expected != bytes received return; } if(cbus_rw_header->reg_count > CBUS_MAX_REG_COUNT) // more registers requested than are allowed in a single request { USBChalkBusSendException(cbus_rw_header->function_code, CBUS_EX_CODE_NAK); // throw exception, more registers requested than are allowed return; } if((cbus_rw_header->function_code == CBUS_FN_CODE_WRITE) && (cbus_rw_header->reg_count * CBUS_DATA_WORD_SIZE != cbus_rw_header->data_bytes)) { USBChalkBusSendException(cbus_rw_header->function_code, CBUS_EX_CODE_NAK); // throw exception, register count not consistent with data bytes count return; } if( (cbus_rw_header->starting_reg >= CBUS_REG_COUNT) || ((cbus_rw_header->starting_reg + cbus_rw_header->reg_count) > CBUS_REG_COUNT)) { // if starting register or ending register beyond last register USBChalkBusSendException(cbus_rw_header->function_code, CBUS_EX_CODE_ADDRESS); // throw exception, an address is out of range return; } } break; default: // function unknown { USBChalkBusSendException(*((unsigned char*)ChalkBusBuff), CBUS_EX_CODE_FUNCTION); // throw exception, this function code is unknown return; // done } } // handle now validated function switch(*((unsigned char*)ChalkBusBuff)) // read function code { case CBUS_FN_CODE_READ: // function read { unsigned short count; // used to copy data unsigned long* read_ptr; // source pointer (holding registers) read_ptr = ChalkBusRegs + (cbus_rw_header->starting_reg); // initialize starting read pointer for(count = 0; count < (cbus_rw_header->reg_count); count++) { // copy regs a register at a time cbus_rw_header->data[count] = *read_ptr; // copy data at read_ptr into outgoing packet read_ptr++; // increment read_ptr to next register } cbus_rw_header->data_bytes = cbus_rw_header->reg_count * CBUS_DATA_WORD_SIZE; // load number of bytes written into header before returning buffer_bytes = CBUS_FN_HDR_SIZE_RD_WR + cbus_rw_header->data_bytes; // load count of bytes to be queued for tx to host below } break; case CBUS_FN_CODE_WRITE: // function write { unsigned short count; // used to copy data unsigned long* write_ptr; // destination pointer (holding registers) write_ptr = ChalkBusRegs + (cbus_rw_header->starting_reg); // initialize starting write pointer for(count = 0; count < (cbus_rw_header->reg_count); count++) { // copy regs a register at a time *write_ptr = cbus_rw_header->data[count]; // copy data from incoming packet to write_ptr write_ptr++; // increment write_ptr to next register } cbus_rw_header->data_bytes = 0; // returning zero data in response buffer_bytes = CBUS_FN_HDR_SIZE_RD_WR; // acknowledge packet's only bytes to return is header with 0 data byte count } break; default: // function unknown { return; // unknown functions should never get here } } if(g_bUSBDevConnected) // send response if there is a device to listen { USBBufferWrite((tUSBBuffer *)&g_sTxBuffer,(unsigned char*)ChalkBusBuff, buffer_bytes); // queue the data to send } }
//***************************************************************************** // // Write a data record to the serial port. An acquired data record is passed // in and is composed into a binary packet and sent on the serial port. The // host PC, if connected will receive this packet via the virtual serial port, // and can decode and display the data. // // The binary packet has the following format: // - 16-bit header, value 0x5351 // - 32-bit seconds time stamp // - 16-bit fractional seconds time stamp (1/32768 resolution) // - 16-bit data item selection mask (which items are included in the record) // - multiple 16-bit data item values, per selection mask // - 16-bit checksum which when added to the 16-bit sum of the entire packet // will result in 0. // // The entire packet is transmitted bytewise over the virtual serial port, // little-endian format. // //***************************************************************************** int USBSerialWriteRecord(tLogRecord *pRecord) { unsigned long ulIdx; unsigned short usChecksum; unsigned long ulItemCount; unsigned short *pusBuf; // // Check the arguments // ASSERT(pRecord); if(!pRecord) { return(1); } // // Check state for ready device // if(!g_bUSBDevConnected) { return(1); } // // Determine how many channels are to be logged // ulIdx = pRecord->usItemMask; ulItemCount = 0; while(ulIdx) { if(ulIdx & 1) { ulItemCount++; } ulIdx >>= 1; } // // Add to item count the equivalent number of 16-bit words for timestamp // and selection mask. // ulItemCount += 4; // // Put the header word in the USB buffer // usChecksum = 0x5351; USBBufferWrite((tUSBBuffer *)&g_sTxBuffer, (unsigned char *)&usChecksum, 2); // // Compute the checksum over the entire record // pusBuf = (unsigned short *)pRecord; for(ulIdx = 0; ulIdx < ulItemCount; ulIdx++) { usChecksum += pusBuf[ulIdx]; } // // Convert item count to bytes. This now represents the entire record // size in bytes, not including the checksum. The header has already // been sent // ulItemCount *= 2; // // Transmit the record, which includes the time stamp, selection mask // and all selected data item, to the USB buffer // USBBufferWrite((tUSBBuffer *)&g_sTxBuffer, (unsigned char *)pusBuf, ulItemCount); // // Adjust the checksum so that when added (as unsigned short) to the // sum of the rest of the packet, the result will be 0 // usChecksum = (unsigned short)(0x10000L - (unsigned long)usChecksum); // // Transmit the checksum which is the end of the packet // USBBufferWrite((tUSBBuffer *)&g_sTxBuffer, (unsigned char *)&usChecksum, 2); // // Return success to the caller // return(0); }