void HardwareSerial::primeTransmit(unsigned long ulBase) { // // Do we have any data to transmit? // if(!TX_BUFFER_EMPTY) { // // Disable the UART interrupt. If we don't do this there is a race // condition which can cause the read index to be corrupted. // ROM_IntDisable(g_ulUARTInt[uartModule]); // // Yes - take some characters out of the transmit buffer and feed // them to the UART transmit FIFO. // while(!TX_BUFFER_EMPTY) { while(ROM_UARTSpaceAvail(ulBase) && !TX_BUFFER_EMPTY) { ROM_UARTCharPutNonBlocking(ulBase, txBuffer[txReadIndex]); txReadIndex = (txReadIndex + 1) % SERIAL_BUFFER_SIZE; } } // // Reenable the UART interrupt. // ROM_IntEnable(g_ulUARTInt[uartModule]); } }
//***************************************************************************** // UART interrupt handler. //***************************************************************************** void UART0_IntHandler(void) { uint32_t status = ROM_UARTIntStatus(UART0_BASE, true); ROM_UARTIntClear(UART0_BASE, status); // drain rx FIFO while(ROM_UARTCharsAvail(UART0_BASE)) { char ch = ROM_UARTCharGetNonBlocking(UART0_BASE); if(inputRB.nbytes < DBG_IN_BUFFER_SIZE) { RB_Push(dbg_inputBuffer, inputRB, ch, DBG_IN_BUFFER_SIZE); if(ch == '\r') ++newlines; } else { // Attempt to report overflow and clear buffer // Must do this to avoid condition where buffer is full and code // is waiting for a newline that can not fit in the buffer. dbg_putstr_nb("\rRXOVF\r\n"); RB_Clear(inputRB); newlines = 0; } } // feed tx FIFO // Echo received characters while(ROM_UARTSpaceAvail(UART0_BASE) && echoPtr != inputRB.wp) { ROM_UARTCharPutNonBlocking(UART0_BASE, dbg_inputBuffer[echoPtr]); echoPtr = (echoPtr + 1) % DBG_IN_BUFFER_SIZE; } // Write pending characters while(ROM_UARTSpaceAvail(UART0_BASE) && outputRB.nbytes > 0) { ROM_UARTCharPutNonBlocking(UART0_BASE, RB_Front(dbg_outputBuffer, outputRB)); RB_Pop(outputRB, DBG_OUT_BUFFER_SIZE); } } // UART0_IntHandler()
int dbg_putc_nb(char ch, void * userdata) { if(ROM_UARTSpaceAvail(UART0_BASE) && outputRB.nbytes == 0) { ROM_UARTCharPutNonBlocking(UART0_BASE, ch); } else { if(!RB_Full(outputRB, DBG_OUT_BUFFER_SIZE)) RB_Push(dbg_outputBuffer, outputRB, ch, DBG_OUT_BUFFER_SIZE); } return 0; }
//***************************************************************************** // // Take as many bytes from the transmit buffer as we have space for and move // them into the USB UART's transmit FIFO. // //***************************************************************************** static void USBUARTPrimeTransmit(uint32_t ui32Base) { uint32_t ui32Read; uint8_t ui8Char; // // If we are currently sending a break condition, don't receive any // more data. We will resume transmission once the break is turned off. // if(g_bSendingBreak) { return; } // // If there is space in the UART FIFO, try to read some characters // from the receive buffer to fill it again. // while(ROM_UARTSpaceAvail(ui32Base)) { // // Get a character from the buffer. // ui32Read = USBBufferRead((tUSBBuffer *)&g_sRxBuffer, &ui8Char, 1); // // Did we get a character? // if(ui32Read) { // // Place the character in the UART transmit FIFO. // ROM_UARTCharPutNonBlocking(ui32Base, ui8Char); // // Update our count of bytes transmitted via the UART. // g_ui32UARTTxCount++; } else { // // We ran out of characters so exit the function. // return; } } }
//***************************************************************************** // // Take as many bytes from the transmit buffer as there is space for and move // them into the USB UART's transmit FIFO. // //***************************************************************************** static void USBUARTPrimeTransmit(void) { unsigned long ulRead; unsigned char ucChar; // // If a break condition is currently being sent, don't receive any more // data. Transmission will resume once the break is turned off. // if(g_bSendingBreak) { return; } // // If there is space in the UART FIFO, try to read some characters // from the receive buffer to fill it again. // while(ROM_UARTSpaceAvail(UART0_BASE)) { // // Get a character from the buffer. // ulRead = USBBufferRead(&g_sRxBuffer, &ucChar, 1); // // Was a character read? // if(ulRead) { // // Place the character in the UART transmit FIFO. // ROM_UARTCharPutNonBlocking(UART0_BASE, ucChar); } else { // // There are no more characters so exit the function. // return; } } }
//***************************************************************************** // // Handles interrupts from the UART. // //***************************************************************************** void UART0IntHandler(void) { unsigned long ulStatus; unsigned char ucChar; // // Get the interrupts that are being asserted by the UART. // ulStatus = ROM_UARTIntStatus(UART0_BASE, true); // // Clear the asserted interrupts. // ROM_UARTIntClear(UART0_BASE, ulStatus); // // Indicate that the UART link is good. // ControllerLinkGood(LINK_TYPE_UART); // // See if the receive interrupt has been asserted. // if(ulStatus & (UART_INT_RX | UART_INT_RT)) { // // Loop while there are more characters to be read from the UART. // while(ROM_UARTCharsAvail(UART0_BASE)) { // // Read the next character from the UART. // ucChar = ROM_UARTCharGet(UART0_BASE); // // See if this is a start of packet byte. // if(ucChar == 0xff) { // // Reset the length of the UART message. // g_ulUARTLength = 0; // // Set the state such that the next byte received is the size // of the message. // g_ulUARTState = UART_STATE_LENGTH; } // // See if this byte is the size of the message. // else if(g_ulUARTState == UART_STATE_LENGTH) { // // Save the size of the message. // g_ulUARTSize = ucChar; // // Subsequent bytes received are the message data. // g_ulUARTState = UART_STATE_DATA; } // // See if the previous character was an escape character. // else if(g_ulUARTState == UART_STATE_ESCAPE) { // // See if this 0xfe, the escaped version of 0xff. // if(ucChar == 0xfe) { // // Store a 0xff in the message buffer. // g_pucUARTMessage[g_ulUARTLength++] = 0xff; // // Subsequent bytes received are the message data. // g_ulUARTState = UART_STATE_DATA; } // // Otherwise, see if this is 0xfd, the escaped version of 0xfe. // else if(ucChar == 0xfd) { // // Store a 0xfe in the message buffer. // g_pucUARTMessage[g_ulUARTLength++] = 0xfe; // // Subsequent bytes received are the message data. // g_ulUARTState = UART_STATE_DATA; } // // Otherwise, this is a corrupted sequence. Set the receiver // to idle so this message is dropped, and subsequent data is // ignored until another start of packet is received. // else { g_ulUARTState = UART_STATE_IDLE; } } // // See if this is a part of the message data. // else if(g_ulUARTState == UART_STATE_DATA) { // // See if this character is an escape character. // if(ucChar == 0xfe) { // // The next byte is an escaped byte. // g_ulUARTState = UART_STATE_ESCAPE; } else { // // Store this byte in the message buffer. // g_pucUARTMessage[g_ulUARTLength++] = ucChar; } } // // See if the entire message has been received but has not been // processed (i.e. the most recent byte received was the end of the // message). // if((g_ulUARTLength == g_ulUARTSize) && (g_ulUARTState == UART_STATE_DATA)) { // // Process this message. // UARTIFCommandHandler(); // // The UART interface is idle, meaning all bytes will be // dropped until the next start of packet byte. // g_ulUARTState = UART_STATE_IDLE; } } // // Tell the controller that CAN activity was detected. // ControllerWatchdog(LINK_TYPE_UART); } // // See if the transmit interrupt has been asserted. // if(ulStatus & UART_INT_TX) { // // Loop while there are more characters to be transmitted and more // space in the UART FIFO. // while((g_ulUARTXmitRead != g_ulUARTXmitWrite) && ROM_UARTSpaceAvail(UART0_BASE)) { // // Put the next character into the UART FIFO. // ROM_UARTCharPut(UART0_BASE, g_pucUARTXmit[g_ulUARTXmitRead]); // // Increment the read pointer. // g_ulUARTXmitRead = (g_ulUARTXmitRead + 1) % UART_XMIT_SIZE; } } // // See if an enumeration response needs to be sent. // if(HWREGBITW(&g_ulUARTFlags, UART_FLAG_ENUM) != 0) { // // Send the enumeration response for this device. // UARTIFSendMessage(CAN_MSGID_API_ENUMERATE | g_sParameters.ucDeviceNumber, 0, 0); // // Clear the enumeration response flag. // HWREGBITW(&g_ulUARTFlags, UART_FLAG_ENUM) = 0; } // // See if periodic status messages need to be sent. // if(HWREGBITW(&g_ulUARTFlags, UART_FLAG_PSTATUS) != 0) { // // Send out the first periodic status message if it needs to be sent. // if(g_ulPStatFlags & 1) { UARTIFSendMessage(LM_API_PSTAT_DATA_S0 | g_sParameters.ucDeviceNumber, g_ppucPStatMessages[0], g_pucPStatMessageLen[0]); } // // Send out the second periodic status message if it needs to be sent. // if(g_ulPStatFlags & 2) { UARTIFSendMessage(LM_API_PSTAT_DATA_S1 | g_sParameters.ucDeviceNumber, g_ppucPStatMessages[1], g_pucPStatMessageLen[1]); } // // Send out the third periodic status message if it needs to be sent. // if(g_ulPStatFlags & 4) { UARTIFSendMessage(LM_API_PSTAT_DATA_S2 | g_sParameters.ucDeviceNumber, g_ppucPStatMessages[2], g_pucPStatMessageLen[2]); } // // Send out the fourth periodic status message if it needs to be sent. // if(g_ulPStatFlags & 8) { UARTIFSendMessage(LM_API_PSTAT_DATA_S3 | g_sParameters.ucDeviceNumber, g_ppucPStatMessages[3], g_pucPStatMessageLen[3]); } // // Clear the periodic status message flag. // HWREGBITW(&g_ulUARTFlags, UART_FLAG_PSTATUS) = 0; } }
//***************************************************************************** // // Sends a character to the UART. // //***************************************************************************** static void UARTIFPutChar(unsigned long ulChar) { // // See if the character being sent is 0xff. // if(ulChar == 0xff) { // // Send 0xfe 0xfe, the escaped version of 0xff. A sign extended // version of 0xfe is used to avoid the check below for 0xfe, thereby // avoiding an infinite loop. Only the lower 8 bits are actually sent, // so 0xfe is what is actually transmitted. // UARTIFPutChar(0xfffffffe); UARTIFPutChar(0xfffffffe); } // // Otherwise, see if the character being sent is 0xfe. // else if(ulChar == 0xfe) { // // Send 0xfe 0xfd, the escaped version of 0xfe. A sign extended // version of 0xfe is used to avoid the check above for 0xfe, thereby // avoiding an infinite loop. Only the lower 8 bits are actually sent, // so 0xfe is what is actually transmitted. // UARTIFPutChar(0xfffffffe); UARTIFPutChar(0xfd); } // // Otherwise, simply send this character. // else { // // Disable the UART interrupt to avoid having characters stick in the // local buffer. // ROM_UARTIntDisable(UART0_BASE, UART_INT_TX); // // See if the local buffer is empty and there is space available in the // UART FIFO. // if((g_ulUARTXmitRead == g_ulUARTXmitWrite) && ROM_UARTSpaceAvail(UART0_BASE)) { // // Simply write this character into the UART FIFO. // ROM_UARTCharPut(UART0_BASE, ulChar); } else { // // Write this character into the local buffer. // g_pucUARTXmit[g_ulUARTXmitWrite] = ulChar; // // Increment the local write buffer pointer. // g_ulUARTXmitWrite = (g_ulUARTXmitWrite + 1) % UART_XMIT_SIZE; } // // Re-enable the UART interrupt. // ROM_UARTIntEnable(UART0_BASE, UART_INT_TX); } }