4 Replies Latest reply on Mar 30, 2020 4:10 AM by BragadeeshV_41

    Modus Toolbox 2.0 FreeRTOS UART

    JeGa_1293081

      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);

        }

      }

        • 1. Re: Modus Toolbox 2.0 FreeRTOS UART
          BragadeeshV_41

          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

          • 2. Re: Modus Toolbox 2.0 FreeRTOS UART
            JeGa_1293081

            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 demonstrates the impleme…

            • 3. Re: Modus Toolbox 2.0 FreeRTOS UART
              JeGa_1293081

              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 ?

              • 4. Re: Modus Toolbox 2.0 FreeRTOS UART
                BragadeeshV_41

                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

                1 of 1 people found this helpful