Using KSDK for interrupt driven UART?

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Using KSDK for interrupt driven UART?

Jump to solution
4,601 Views
surrealist14
Contributor III

Hi folks,

 

It seems like there should be examples, but can anyone point me to information about using KSDK 1.1.0 to initialize and use UART0 for interrupt-driven transmit and receive?

 

I may also need to use CTS and RTS for flow control.  Specifically, I am using a K60 (MK60DN512VLQ10) with a bare-metal configuration (no OS).

 

What I'd like are examples showing how to configure the pins, initialize the UART, install the ISR, and handle character transmission and reception using interrupts instead of polling.  Since UART0 has a FIFO, it would also be nice to use that to get some better throughput with lower overhead.

 

Thanks for your help.  There may be a great example somewhere, but I just can't find it, and it isn't obvious to me from the KSDK 1.1.0 documentation.

 

Scott

Labels (1)
1 Solution
1,468 Views
Jorge_Gonzalez
NXP Employee
NXP Employee

Hello Scott Whitney:

To have the ISR function you have to pull a Driver IRQ file to your project (fsl_<peripheral>_irq.c). In this case for UART the file is fsl_uart_irq.c and it is in the path "C:\Freescale\KSDK_1.1.0\platform\drivers\src\uart). Just copy that file or link it to your project.

There is a document I shared about interrupt handling with KSDK, it is focused for Kinetis Design Studio, but all the concepts apply for any IDE:

Interrupt handling with KSDK and Kinetis Design Studio

Regards!

Jorge Gonzalez

View solution in original post

6 Replies
1,468 Views
surrealist14
Contributor III

Let me add some more details from experimentation.  I believe that the first thing I need to do is configure the pins I want to use for UART0:


     PORT_HAL_SetMuxMode(PORTA_BASE,14u,kPortMuxAlt3); // UART0_TX

     PORT_HAL_SetMuxMode(PORTA_BASE,15u,kPortMuxAlt3); // UART0_RX

     PORT_HAL_SetMuxMode(PORTA_BASE,16u,kPortMuxAlt3); // UART0_CTS_b

     PORT_HAL_SetMuxMode(PORTA_BASE,17u,kPortMuxAlt3); // UART0_RTS_b

I also need to allocate space for the UART configuration and state info, and then initialize the UART configuration:

     uart_user_config_t uart0Config; // UART configuration for PC comms

     uart_state_t uart0State;        // Memory for UART driver state structure

     uart0Config.baudRate = 115200;

     uart0Config.bitCountPerChar = kUart8BitsPerChar;

     uart0Config.parityMode = kUartParityDisabled;

     uart0Config.stopBitCount = kUartOneStopBit;

Then, I call the driver initialization function for the UART:

    UART_DRV_Init(HW_UART0, &uart0State, &uart0Config);

Here's where I get lost.  I'd like to do a non-blocking transmit, for example.  I can define a buffer to transmit, and then call the non-blocking driver function to send it:

    char *txBuffer = "Hello from UART0\n\r";

    size_t txLen = strlen(txBuffer);

    UART_DRV_SendData(HW_UART0, (const uint8_t *)txBuffer, txLen);

The documentation shows that I should be able to check the status of the transmit by calling another driver function, e.g.:

     uint32_t txBytesRemaining;

     while (kStatus_UART_TxBusy == UART_DRV_GetTransmitStatus(HW_UART0, &txBytesRemaining))

     {

          // Can do something else instead of just busy-waiting here.

     }

Presumably this starts sending data and will use a Tx interrupt to handle sending the remaining bytes via the uart_state_t structure as the transmitter empties.  However, it appears that the interrupt handler is not being installed correctly.  In IAR, I end up at the DefaultISR handler, which just keeps branching back to itself.

File fsl_uart_driver.c has the IRQ handler for the UART, but I do not see where it gets installed, or how I should install it:

     void UART_DRV_IRQHandler(uint32_t instance)

This function looks like it has the code to handle pending transmits and receives using the uart_state_t structure, but it must get called from some actual ISR, and I do not see where that happens.

What do I need to do to install the UART's IRQ handler correctly?  There is a function in fsl_interrupt_manager.c to install an interrupt handler and IRQ, but the handler does not take a parameter (instance):

     void * INT_SYS_InstallHandler(IRQn_Type irqNumber, void (*handler)(void))

So, after I call UART_DRV_Init(), is there something I have to do to install the IRQ handler for the UART?

Your help is greatly appreciated, and I hope this example will help others struggling to use the drivers provided by Freescale.

Thanks!

Scott

0 Kudos
1,468 Views
DavidS
NXP Employee
NXP Employee

Hi Scott,

We will have UART non-blocking example in the KDS_3.0.0/KSDK_1.2.0 early next month.

Can you wait?

Regards,

David

1,468 Views
albertolubeiro
Contributor III

Hi David,

I am workig with KDS 3.0 and KSDK1.2.0 and over MQX

I am working with UART1 and UART3 on a K64 device.

Both UART are configured in the same way but curiously UART3 sends data and UART1 doesn't. The fact is that when data must be sent through UART1, the interrupt isn't triggered.

Please find attached the file.

Any help will be apreciated.

Thanks and regards

0 Kudos
1,468 Views
surrealist14
Contributor III

Hi David,

Unfortunately I am on a very tight schedule, and can't put off finding a solution.  I'd be happy to discuss a solution or work-around with you on the phone or via e-mail if it's not ready for the community, or to try out a beta version if it would get me to an answer more quickly.  I think that I am very close to having a solution, but the sticking point is that I do not see documentation on how to install the handler for the UART's ISR.  I supposed that I could use other fsl_* calls to install my own handler for the ISR, and then have that call the void UART_DRV_IRQHandler(uint32_t instance) with an instance of HW_UART0, but I am not sure if that is the correct or Freescale-recommended way.

Is there any way you can provide some help or examples to get me past this hurdle?  I think it's excellent that KSDK is continuing to evolve and more examples are coming, but I really need to get this piece working ASAP.  It's crucial for my application.

Many thanks, and I appreciate the quick response!

Scott

0 Kudos
1,469 Views
Jorge_Gonzalez
NXP Employee
NXP Employee

Hello Scott Whitney:

To have the ISR function you have to pull a Driver IRQ file to your project (fsl_<peripheral>_irq.c). In this case for UART the file is fsl_uart_irq.c and it is in the path "C:\Freescale\KSDK_1.1.0\platform\drivers\src\uart). Just copy that file or link it to your project.

There is a document I shared about interrupt handling with KSDK, it is focused for Kinetis Design Studio, but all the concepts apply for any IDE:

Interrupt handling with KSDK and Kinetis Design Studio

Regards!

Jorge Gonzalez

1,468 Views
surrealist14
Contributor III

Jorge, thank you very much.  This is exactly what I needed to get me unstuck.  What I was missing is that the fsl_<peripheral>_irq.c files are not part of the KSDK platform library build, as you clearly stated in your reply and on page 8 of the document you provided.  Once I added fsl_uart_irq.c to my project, the default vector for the UART0 interrupt was replaced, and things started making sense again.

Great answer, and very timely and helpful.  I hope this helps others, and I'm looking forward to KSDK_1.2.0 soon.

Best regards,

Scott