- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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);
}
}
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
Bragadeesh
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
Bragadeesh
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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...
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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 ?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
Bragadeesh