Hi NXP,
I am using the LPC Link2 as a dev board and am trying to print data to the USART2 pins, and read the data with an FTDI serial cable to a Mac computer running PySerial. My computer is also running my Link2 code on MCUXpresso which is simply sending test data using UART functions I sourced from embedded artist.
I have read some other posts about the USART2_Rx and Tx pins on the Link2 but they aren't exactly clear about whether the USART2 pins work or not. I haven't been successful in getting any data yet.
Can someone tell me if my setup will yield results? Please let me know if you need more information about my cables, code etc.
-Quinn
Solved! Go to Solution.
Hi,
maybe your following code has issue. Pls poll the THRE bit in LSR register with the line before you write the transmitter reg.
while((LPC_UART1_Type *)UARTx)->LSR&0x20) {} //check the THRE bit, if not empty, waiting
BR
XiangJun Rong
void UART_SendByte(LPC_USARTn_Type* UARTx, uint8_t Data)
{
CHECK_PARAM(PARAM_UARTx(UARTx));
if (((LPC_UART1_Type *)UARTx) == LPC_UART1)
{
while((LPC_UART1_Type *)UARTx)->LSR&0x20) {} //check the THRE bit, if not empty, waiting
((LPC_UART1_Type *)UARTx)->/*RBTHDLR.*/THR = Data & UART_THR_MASKBIT;
}
else
{
UARTx->/*RBTHDLR.*/THR = Data & UART_THR_MASKBIT;
}
}
Hi,
Pls download LPCOpen package and try to run the example code for the usart.
BR
XiangJun Rong
Hi XJR,
Ok I am now getting data from the link2 into pyserial, but I am still not reading correct data. I think there is a flow control problem because I am only receiving around 20 bytes in pyserial but am sending 4096.
PySerial has an xonxoff software flow control option. Is there an equivalent xonxoff flow control option in the Link2? What would I have to do to set it up?
Regards,
Quinn
Hi,
Regarding your question that you can see waveform on the usart2_Tx pin, but the received data on Mac PC is incorrect, I think the only reason is baudrate does not match between PC and LPC-Link2 usart2, pls check the baudrate on the LPC board
BR
XiangJun Rong
Hi XJR,
I am now getting the correct amount of bytes in PySerial but the data is not right. I am sending 16 bytes at a time then pausing transmission for a very short period of time using a for loop.
I am sure my baud rate is the same in MCUXpresso and PySerial. I even go as far as printing the actual calculated baud rate from my UART initialisation code 115384 for 115200 and 9603 for 9600. I have also tested setting at 115200 and 9603.
Could my issue be that the Link2 is sending the bytes in a LSB/MSB (big or small endian) way that I am not expecting?
Please see images of the UART Tx code and the PySerial output.
Quinn
Hi,
I think your solution is okay.
As I said that you have to program the usart2 module of LPC4370 so that it can output character to the usart2_Tx pin continously. Pls connect usart2_tx pin to the oscilloscope and check if there is signal on the pin.
BTW, I suppose that you can use a simple tools of mac OS, which can receive character from usart.
Hope it can help you
BR
XiangJun Rong
Hi XiangJun,
I have done what you said, I have code that is running a continuous print to USART2 pins using the following code:
--------------------------------------------------------------------------------
UART_CFG_Type UART;
UART.Baud_rate = 115200;
UART.Parity = UART_PARITY_NONE;
UART.Databits = UART_DATABIT_8;
UART.Stopbits = UART_STOPBIT_1;
UART.Clock_Speed = 0;
/* Initialize UART */
UART_Init(LPC_USART2,&UART);
while(1){
UART_Send(LPC_USART2,test,5,NONE_BLOCKING);
UART_Init(LPC_USART2,&UART);
UART_Send(LPC_USART2,test2,5,NONE_BLOCKING);
UART_Init(LPC_USART2,&UART);
}
--------------------------------------------------------------------------------
*Function: UART_Init();*
--------------------------------------------------------------------------------
/********************************************************************//**
* @brief Initializes the UARTx peripheral according to the specified
* parameters in the UART_ConfigStruct.
* @param[in] UARTx UART peripheral selected, should be:
* - LPC_UART0 :UART0 peripheral
* - LPC_UART1 :UART1 peripheral
* - LPC_UART2 :UART2 peripheral
* - LPC_UART3 :UART3 peripheral
* @param[in] UART_ConfigStruct Pointer to a UART_CFG_Type structure
* that contains the configuration information for the
* specified UART peripheral.
* @return None
*********************************************************************/
void UART_Init(LPC_USARTn_Type *UARTx, UART_CFG_Type *UART_ConfigStruct)
{
uint32_t tmp;
// For debug mode
CHECK_PARAM(PARAM_UARTx(UARTx));
CHECK_PARAM(PARAM_UART_DATABIT(UART_ConfigStruct->Databits));
CHECK_PARAM(PARAM_UART_STOPBIT(UART_ConfigStruct->Stopbits));
CHECK_PARAM(PARAM_UART_PARITY(UART_ConfigStruct->Parity));
#ifdef _UART0
if(UARTx == LPC_USART0)
{
/* Set up peripheral clock for UART0 module */
//LPC_CGU->BASE_UART0_CLK = (SRC_PL160M_0<<24) | (1<<11);// Use PLL1 and auto block
CGU_EntityConnect(CGU_CLKSRC_XTAL_OSC, CGU_BASE_UART0);
}
#endif
#ifdef _UART1
if(((LPC_UART1_Type *)UARTx) == LPC_UART1)
{
/* Set up peripheral clock for UART1 module */
//LPC_CGU->BASE_UART1_CLK = (SRC_PL160M_0<<24) | (1<<11);// Use PLL1 and auto block
CGU_EntityConnect(CGU_CLKSRC_PLL1, CGU_BASE_UART1);
}
#endif
#ifdef _UART2
if(UARTx == LPC_USART2)
{
/* Set up peripheral clock for UART2 module */
//LPC_CGU->BASE_UART2_CLK = (SRC_PL160M_0<<24) | (1<<11);// Use PLL1 and auto block
CGU_EntityConnect(CGU_CLKSRC_XTAL_OSC, CGU_BASE_UART2);
}
#endif
#ifdef _UART3
if(UARTx == LPC_USART3)
{
/* Set up peripheral clock for UART3 module */
//LPC_CGU->BASE_UART3_CLK = (SRC_PL160M_0<<24) | (1<<11);// Use PLL1 and auto block
CGU_EntityConnect(CGU_CLKSRC_XTAL_OSC, CGU_BASE_UART3);
}
#endif
if (((LPC_UART1_Type *)UARTx) == LPC_UART1)
{
/* FIFOs are empty */
((LPC_UART1_Type *)UARTx)->/*IIFCR.*/FCR = ( UART_FCR_FIFO_EN \
| UART_FCR_RX_RS | UART_FCR_TX_RS);
// Disable FIFO
((LPC_UART1_Type *)UARTx)->/*IIFCR.*/FCR = 0;
// Dummy reading
while (((LPC_UART1_Type *)UARTx)->LSR & UART_LSR_RDR)
{
tmp = ((LPC_UART1_Type *)UARTx)->/*RBTHDLR.*/RBR;
}
((LPC_UART1_Type *)UARTx)->TER = UART1_TER_TXEN;
// Wait for current transmit complete
while (!(((LPC_UART1_Type *)UARTx)->LSR & UART_LSR_THRE));
// Disable Tx
((LPC_UART1_Type *)UARTx)->TER = 0;
// Disable interrupt
((LPC_UART1_Type *)UARTx)->/*DLIER.*/IER = 0;
// Set LCR to default state
((LPC_UART1_Type *)UARTx)->LCR = 0;
// Set ACR to default state
((LPC_UART1_Type *)UARTx)->ACR = 0;
// Set Modem Control to default state
((LPC_UART1_Type *)UARTx)->MCR = 0;
// Set RS485 control to default state
((LPC_UART1_Type *)UARTx)->RS485CTRL = 0;
// Set RS485 delay timer to default state
((LPC_UART1_Type *)UARTx)->RS485DLY = 0;
// Set RS485 addr match to default state
((LPC_UART1_Type *)UARTx)->RS485ADRMATCH = 0;
//Dummy Reading to Clear Status
tmp = ((LPC_UART1_Type *)UARTx)->MSR;
tmp = ((LPC_UART1_Type *)UARTx)->LSR;
}
else
{
/* FIFOs are empty */
UARTx->/*IIFCR.*/FCR = ( UART_FCR_FIFO_EN | UART_FCR_RX_RS | UART_FCR_TX_RS);
// Disable FIFO
UARTx->/*IIFCR.*/FCR = 0;
// Dummy reading
while (UARTx->LSR & UART_LSR_RDR)
{
tmp = UARTx->/*RBTHDLR.*/RBR;
}
UARTx->TER = UART0_2_3_TER_TXEN;
// Wait for current transmit complete
while (!(UARTx->LSR & UART_LSR_THRE));
// Disable Tx
UARTx->TER = 0;
// Disable interrupt
UARTx->/*DLIER.*/IER = 0;
// Set LCR to default state
UARTx->LCR = 0;
// Set ACR to default state
UARTx->ACR = 0;
// set HDEN to default state
UARTx->HDEN = 0;
// set SCICTRL to default state
UARTx->SCICTRL = 0;
// set SYNCCTRL to default state
UARTx->SYNCCTRL =0;
// Set RS485 control to default state
UARTx->RS485CTRL = 0;
// Set RS485 delay timer to default state
UARTx->RS485DLY = 0;
// Set RS485 addr match to default state
UARTx->RS485ADRMATCH = 0;
// Dummy reading
tmp = UARTx->LSR;
}
if (UARTx == LPC_USART3)
{
// Set IrDA to default state
UARTx->ICR = 0;
}
// Set Line Control register ----------------------------
uart_set_divisors(UARTx, (UART_ConfigStruct->Baud_rate), UART_ConfigStruct->Clock_Speed);
if (((LPC_UART1_Type *)UARTx) == LPC_UART1)
{
tmp = (((LPC_UART1_Type *)UARTx)->LCR & (UART_LCR_DLAB_EN | UART_LCR_BREAK_EN)) \
& UART_LCR_BITMASK;
}
else
{
tmp = (UARTx->LCR & (UART_LCR_DLAB_EN | UART_LCR_BREAK_EN)) & UART_LCR_BITMASK;
}
switch (UART_ConfigStruct->Databits){
case UART_DATABIT_5:
tmp |= UART_LCR_WLEN5;
break;
case UART_DATABIT_6:
tmp |= UART_LCR_WLEN6;
break;
case UART_DATABIT_7:
tmp |= UART_LCR_WLEN7;
break;
case UART_DATABIT_8:
default:
tmp |= UART_LCR_WLEN8;
break;
}
if (UART_ConfigStruct->Parity == UART_PARITY_NONE)
{
// Do nothing...
}
else
{
tmp |= UART_LCR_PARITY_EN;
switch (UART_ConfigStruct->Parity)
{
case UART_PARITY_ODD:
tmp |= UART_LCR_PARITY_ODD;
break;
case UART_PARITY_EVEN:
tmp |= UART_LCR_PARITY_EVEN;
break;
case UART_PARITY_SP_1:
tmp |= UART_LCR_PARITY_F_1;
break;
case UART_PARITY_SP_0:
tmp |= UART_LCR_PARITY_F_0;
break;
default:
break;
}
}
switch (UART_ConfigStruct->Stopbits){
case UART_STOPBIT_2:
tmp |= UART_LCR_STOPBIT_SEL;
break;
case UART_STOPBIT_1:
default:
// Do no thing
break;
}
// Write back to LCR, configure FIFO and Disable Tx
if (((LPC_UART1_Type *)UARTx) == LPC_UART1)
{
((LPC_UART1_Type *)UARTx)->LCR = (uint8_t)(tmp & UART_LCR_BITMASK);
}
else
{
UARTx->LCR = (uint8_t)(tmp & UART_LCR_BITMASK);
}
}
--------------------------------------------------------------------------------
*Function: UART_Send();*
--------------------------------------------------------------------------------
/*********************************************************************//**
* @brief Send a block of data via UART peripheral
* @param[in] UARTx Selected UART peripheral used to send data, should be:
* - LPC_UART0 :UART0 peripheral
* - LPC_UART1 :UART1 peripheral
* - LPC_UART2 :UART2 peripheral
* - LPC_UART3 :UART3 peripheral
* @param[in] txbuf Pointer to Transmit buffer
* @param[in] buflen Length of Transmit buffer
* @param[in] flag Flag used in UART transfer, should be
* - NONE_BLOCKING
* - BLOCKING
* @return Number of bytes sent.
*
* Note: when using UART in BLOCKING mode, a time-out condition is used
* via defined symbol UART_BLOCKING_TIMEOUT.
**********************************************************************/
uint32_t UART_Send(LPC_USARTn_Type *UARTx, uint8_t *txbuf,
uint32_t buflen, TRANSFER_BLOCK_Type flag)
{
uint32_t bToSend, bSent, timeOut, fifo_cnt;
uint8_t *pChar = txbuf;
bToSend = buflen;
// blocking mode
if (flag == BLOCKING) {
bSent = 0;
while (bToSend){
timeOut = UART_BLOCKING_TIMEOUT;
// Wait for THR empty with timeout
while (!(UARTx->LSR & UART_LSR_THRE)) {
if (timeOut == 0) break;
timeOut--;
}
// Time out!
if(timeOut == 0) break;
fifo_cnt = UART_TX_FIFO_SIZE;
while (fifo_cnt && bToSend){
UART_SendByte(UARTx, (*pChar++));
fifo_cnt--;
bToSend--;
bSent++;
}
}
}
// None blocking mode
else {
bSent = 0;
while (bToSend) {
if (!(UARTx->LSR & UART_LSR_THRE)){
break;
}
fifo_cnt = UART_TX_FIFO_SIZE;
while (fifo_cnt && bToSend) {
UART_SendByte(UARTx, (*pChar++));
bToSend--;
fifo_cnt--;
bSent++;
}
}
}
return bSent;
}
--------------------------------------------------------------------------------
*Function: UART_SendByte();*
--------------------------------------------------------------------------------
/*********************************************************************//**
* @brief Transmit a single data through UART peripheral
* @param[in] UARTx UART peripheral selected, should be:
* - LPC_UART0 :UART0 peripheral
* - LPC_UART1 :UART1 peripheral
* - LPC_UART2 :UART2 peripheral
* - LPC_UART3 :UART3 peripheral
* @param[in] Data Data to transmit (must be 8-bit long)
* @return None
**********************************************************************/
void UART_SendByte(LPC_USARTn_Type* UARTx, uint8_t Data)
{
CHECK_PARAM(PARAM_UARTx(UARTx));
if (((LPC_UART1_Type *)UARTx) == LPC_UART1)
{
((LPC_UART1_Type *)UARTx)->/*RBTHDLR.*/THR = Data & UART_THR_MASKBIT;
}
else
{
UARTx->/*RBTHDLR.*/THR = Data & UART_THR_MASKBIT;
}
}
--------------------------------------------------------------------------------
I have had the Tx and GND pins connected to an oscilloscope while the above code is running, however I have only had a continuous ~3V signal without any data.
Any other suggestions?
I will try CMSIS USART package next.
Regards,
Quinn
Hi,
maybe your following code has issue. Pls poll the THRE bit in LSR register with the line before you write the transmitter reg.
while((LPC_UART1_Type *)UARTx)->LSR&0x20) {} //check the THRE bit, if not empty, waiting
BR
XiangJun Rong
void UART_SendByte(LPC_USARTn_Type* UARTx, uint8_t Data)
{
CHECK_PARAM(PARAM_UARTx(UARTx));
if (((LPC_UART1_Type *)UARTx) == LPC_UART1)
{
while((LPC_UART1_Type *)UARTx)->LSR&0x20) {} //check the THRE bit, if not empty, waiting
((LPC_UART1_Type *)UARTx)->/*RBTHDLR.*/THR = Data & UART_THR_MASKBIT;
}
else
{
UARTx->/*RBTHDLR.*/THR = Data & UART_THR_MASKBIT;
}
}
I finally have my system working! That line of code you sent was key. It seemed as though my Tx buffer was overflowing but there was nothing slowing down the code sending the data to the buffer.
Also, I must note that PySerial was letting me down a bit as well. It doesn't have the ability to change the endianness of the incoming data, a feature which I needed, and one that the MATLAB 2021a 'instrument communication toolbox' was able to provide.
Thank you for all your help Xiangjun.
Best Regards,
Quinn
Thanks for this line of code. However, shouldn't it be while not true?
while(!((LPC_UART1_Type *)UARTx)->LSR & 0x20) //check the THRE bit, if not empty, waiting.
^
As when this is true the THR is empty and we want to wait while it's not true?
Hi,
As you know that the USART2_TX is multiplexed with PIO2-10, CTOUT_2, EMC_A1, so you have to write SFSPF2_10 as 0x02 so that the P2_10 pin functions as usart2_Tx pin.
Pls refer to the following screenshots.
BR
XiangJun Rong
Hi XJR,
I think there is still an issue with my pin configuration. No matter what I print to UART, the pin voltage remains at around 3V. I believe the voltage should swing between 0 and 3V for 0,1 bits.
Is there anything else you could think that might need to be configured with my pins?
Regards,
Quinn
Hi,
Can you configure the usart tx pin as GPIO output mode then you toggle the pin? After you can toggle the pin successfully, then configure the pin as usart_tx, then run your usart code, if you still have issue, we can narrow that the usart code has issue.
BR
XiangJun Rong
Ok so I think I have my pin settings correct now. P2_10 was set to Function 0 for some reason. This is now function 2 for the UART_TX.
I have also tried disabling synchronous mode but still no luck.
Maybe a silly question but what should my voltage levels be for logic high and logic low? I have no pull up or pull down resistors enabled at the moment and all of the signal is sitting very close to 3V. I thought it would be something like 0V for low and 3V for high (0,1, respectively).
Quinn
Hi XiangJun,
Yes I have two Link2 boards, one as the LPC4370 target and one as the Link2 debug. I want to take data from the target quickly (~8kB/s) and plot in real time using PySerial (or MATLAB).
Have you tried a setup like this using the UART USB chip you posted and the Link2 board UART pins?
I'm trying to use the cable in the data sheet attached by just using GND, Tx and Rx pins but I probably need something like you have?
Quinn
Hi, Quinn,
Regarding your question, I suppose that you use LPC Link2 as an evaluation board to test the LPC4370 on LPC link2 board, you have the other adapter so that you can download/debug code to LPC4370.
The uart2 pin of LPC4370 are connected to pin7 and pin8 of J3 connector on LPC-Link2 board as the following Fig
You can connect the pin7&8 and GND of J3 of lpc-link2 to the UART-USB board, which can be ordered on market.
This is my Uart-USB board.
You have to programe the uart2 of LPC4370 so that it can communicate.
Hope it can help you
BR
XiangJun Rong