Modus Toolbox 2.0 FreeRTOS UART

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
JeGa_1293081
Level 1
Level 1
Welcome! 5 questions asked First question asked

Hi, This is a question based on an old thread, but my case is a bit different,

the original post is Modus Toolbox FreeRTOS UART , I have downloaded the code, and ported into Modus Toolbox 2.0 project.

I am using the cyhal_uart_t cy_retarget_io_uart_obj, with following:

/* Uart object used for reading character from terminal */

extern cyhal_uart_t cy_retarget_io_uart_obj;

/* Lock handle for UART device */

static SemaphoreHandle_t uartSemaphore;

/* Create the Interrupt Config Structure,*/

const cy_stc_sysint_t uart_isr_config = {

  .intrSrc = cy_retarget_io_uart_obj.irq_cause,            // here is what failed!!

  .intrPriority = 1

};

/*******************************************************************************

* Function Name: void cliTask(void *arg)

********************************************************************************

*

* Summary: UART Cli Task

*

*

* Parameters:

*  None

*

* Return:

*  None

*

*******************************************************************************/

void cliTask(void *arg)

{

// UART init

cy_retarget_io_init(CYBSP_DEBUG_UART_TX, CYBSP_DEBUG_UART_RX, CY_RETARGET_IO_BAUDRATE);

/* Show the startup screen */

  ShowStartupText();

  // CLI Init

cli_init();

for(;;)

{

    xSemaphoreTake(uartSemaphore, portMAX_DELAY);

Cli_SysCmd_Prompt(Text_put("User"));

    Cy_SCB_SetRxInterruptMask(cy_retarget_io_uart_obj.base, CY_SCB_RX_INTR_NOT_EMPTY);

}

}

/*******************************************************************************

* Function Name: cli_init

********************************************************************************

* Summary:

*  This function initializes the cli Host and Controller, configures UART

*  interrupt, and registers Command line Application Host callbacks.

*

*******************************************************************************/

static void cli_init(void)

{

/* Creates a new binary semaphore instance */

  uartSemaphore = xSemaphoreCreateBinary();

/* Configure and initialize UART interrupt */

Cy_SysInt_Init(&uart_isr_config, &UART_Isr);

NVIC_EnableIRQ(uart_isr_config.intrSrc);

Cy_SCB_SetRxInterruptMask(cy_retarget_io_uart_obj.base, CY_SCB_RX_INTR_NOT_EMPTY);

}

/*******************************************************************************

* Function Name: UART_isr

********************************************************************************

* Summary:

*  Wrraper function for UART interrupt

*

*******************************************************************************/

static void UART_Isr(){

  Cy_SCB_SetRxInterruptMask(cy_retarget_io_uart_obj.base, 0);

  Cy_SCB_ClearRxInterrupt(cy_retarget_io_uart_obj.base, CY_SCB_RX_INTR_NOT_EMPTY);

  NVIC_ClearPendingIRQ(uart_isr_config.intrSrc);

  BaseType_t xHigherPriorityTaskWoken;

  xHigherPriorityTaskWoken = pdFALSE;

  xSemaphoreGiveFromISR(uartSemaphore, &xHigherPriorityTaskWoken);

  if(xHigherPriorityTaskWoken == pdTRUE){

    portYIELD_FROM_ISR(xHigherPriorityTaskWoken);

  }

}

0 Likes
1 Solution
lock attach
Attachments are accessible only for community members.

Hi JeGa_1293081​,

Thank you for more insight.

The retarget-io uses HAL to initialize the UART interface. In case you wish to add any functionality to the existing UART interface, we recommend using the UART HAL APIs.

To add an interrupt on every byte received, do the following:

1. Create a new task called task_uart_receive(), that receives and processes the commands from the serial terminal.

2. In the task, register a callback function to notify the event CYHAL_UART_IRQ_RX_NOT_EMPTY (RF FIFO NOT EMPTY) using cyhal_uart_register_callback().

3. Enable the event using cyhal_uart_enable_event();

The task function would look something like below:

void task_uart_receive(void *param)

{

uartSemaphore = xSemaphoreCreateBinary();

  /* UART interface is already enabled using ReTarget - IO. Here let us enable the Event CYHAL_UART_IRQ_RX_NOT_EMPTY  */

cyhal_uart_register_callback(&cy_retarget_io_uart_obj, uart_event_callback, NULL);

cyhal_uart_enable_event(&cy_retarget_io_uart_obj, CYHAL_UART_IRQ_RX_NOT_EMPTY, 3u, true);

for(;;)

{

    xSemaphoreTake(uartSemaphore, portMAX_DELAY);

     // Your processing code, I'm simply printing here

    task_debug_printf(info,&c);

}

}

4. Create a callback function to handle the event CYHAL_UART_IRQ_RX_NOT_EMPTY like below:

void uart_event_callback(void *callback_arg, cyhal_uart_event_t event)

{

    size_t size = 1;

    BaseType_t xHigherPriorityTaskWoken;

    xHigherPriorityTaskWoken = pdFALSE;

    if((event & CYHAL_UART_IRQ_RX_NOT_EMPTY) != 0u)

    {

         while(cyhal_uart_readable(&cy_retarget_io_uart_obj))

         {

              cyhal_uart_read(&cy_retarget_io_uart_obj, (void *)&c ,&size );

         }

         /* Data is received in the RX FIFO */

         xSemaphoreGiveFromISR(uartSemaphore, &xHigherPriorityTaskWoken);

         if(xHigherPriorityTaskWoken == pdTRUE)

         {

            portYIELD_FROM_ISR(xHigherPriorityTaskWoken);

         }

     }

}

Note: You can choose to have queue to unblock the uart_receive task.

I've also attached the uart_receive .c/.h files and MTB project file with this response. Let us know if this helps.

Refer to Hardware Abstraction Layer (HAL) for UART HAL APIs.

Regards,

Bragadeesh

Regards,
Bragadeesh

View solution in original post

4 Replies
BragadeeshV
Moderator
Moderator
Moderator
First question asked 1000 replies posted 750 replies posted

Hi JeGa_1293081​,

Could you please highlight the issue you are facing so that we can debug at our end? I do not see any questions in your post.

Thanks,

Bragadeesh

Regards,
Bragadeesh
0 Likes
lock attach
Attachments are accessible only for community members.

hi, my task is to make Debug UART able to read user keyboard input. attachment is debug uart task file from GitHub - cypresssemiconductorco/mtb-example-psoc6-ble-battery-level-freertos: This code example demo...

0 Likes

after some code digging,  I found the main difference is the ISR

in file cyhal_uart.c there is a ISR

static void cyhal_uart_irq_handler(void)

{

    cyhal_uart_t *obj = (cyhal_uart_t*) cyhal_scb_get_irq_obj();

    Cy_SCB_UART_Interrupt(obj->base, &(obj->context));

}

but in uartTask.c from Modus Toolbox FreeRTOS UART we have ISR below

static void UART_Isr(){

    Cy_SCB_SetRxInterruptMask(UART_HW, 0);

    Cy_SCB_ClearRxInterrupt(UART_HW, CY_SCB_RX_INTR_NOT_EMPTY);

    NVIC_ClearPendingIRQ(uart_isr_config.intrSrc);

    BaseType_t xHigherPriorityTaskWoken;

    xHigherPriorityTaskWoken = pdFALSE;

    xSemaphoreGiveFromISR(uartSemaphore, &xHigherPriorityTaskWoken);

    if(xHigherPriorityTaskWoken == pdTRUE){

        portYIELD_FROM_ISR(xHigherPriorityTaskWoken);

    }

}

so How can we rewrite the ISR to make our FreeRTOS task able to read UART input ?

0 Likes
lock attach
Attachments are accessible only for community members.

Hi JeGa_1293081​,

Thank you for more insight.

The retarget-io uses HAL to initialize the UART interface. In case you wish to add any functionality to the existing UART interface, we recommend using the UART HAL APIs.

To add an interrupt on every byte received, do the following:

1. Create a new task called task_uart_receive(), that receives and processes the commands from the serial terminal.

2. In the task, register a callback function to notify the event CYHAL_UART_IRQ_RX_NOT_EMPTY (RF FIFO NOT EMPTY) using cyhal_uart_register_callback().

3. Enable the event using cyhal_uart_enable_event();

The task function would look something like below:

void task_uart_receive(void *param)

{

uartSemaphore = xSemaphoreCreateBinary();

  /* UART interface is already enabled using ReTarget - IO. Here let us enable the Event CYHAL_UART_IRQ_RX_NOT_EMPTY  */

cyhal_uart_register_callback(&cy_retarget_io_uart_obj, uart_event_callback, NULL);

cyhal_uart_enable_event(&cy_retarget_io_uart_obj, CYHAL_UART_IRQ_RX_NOT_EMPTY, 3u, true);

for(;;)

{

    xSemaphoreTake(uartSemaphore, portMAX_DELAY);

     // Your processing code, I'm simply printing here

    task_debug_printf(info,&c);

}

}

4. Create a callback function to handle the event CYHAL_UART_IRQ_RX_NOT_EMPTY like below:

void uart_event_callback(void *callback_arg, cyhal_uart_event_t event)

{

    size_t size = 1;

    BaseType_t xHigherPriorityTaskWoken;

    xHigherPriorityTaskWoken = pdFALSE;

    if((event & CYHAL_UART_IRQ_RX_NOT_EMPTY) != 0u)

    {

         while(cyhal_uart_readable(&cy_retarget_io_uart_obj))

         {

              cyhal_uart_read(&cy_retarget_io_uart_obj, (void *)&c ,&size );

         }

         /* Data is received in the RX FIFO */

         xSemaphoreGiveFromISR(uartSemaphore, &xHigherPriorityTaskWoken);

         if(xHigherPriorityTaskWoken == pdTRUE)

         {

            portYIELD_FROM_ISR(xHigherPriorityTaskWoken);

         }

     }

}

Note: You can choose to have queue to unblock the uart_receive task.

I've also attached the uart_receive .c/.h files and MTB project file with this response. Let us know if this helps.

Refer to Hardware Abstraction Layer (HAL) for UART HAL APIs.

Regards,

Bragadeesh

Regards,
Bragadeesh