UART ISR for M0

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

cross mob
TeMa_1467596
Level 5
Level 5
5 sign-ins 5 likes given First like received

This is for a PSoC6 running on a CY8CKIT-062-BLE board.

I'm trying to implement an ISR that's called when the UART receives a character so I can get chars from the UART non-blocking, build a command in an input buffer, and then set a flag that that command needs processing when the CR char is received.  I found the example CE219656 UART Low Level User ISR which is pretty much what I need except it runs on the M4 and I want it to run on the M0+.

I tried to move the code over to the M0+ (see below) but it chokes on UART_SCB_IRQ_cfg which is an undeclared identifier error.

Is there something different about how this is supposed to work on the M0+

Ted

/* ========================================

*

* Copyright YOUR COMPANY, THE YEAR

* All Rights Reserved

* UNPUBLISHED, LICENSED SOFTWARE.

*

* CONFIDENTIAL AND PROPRIETARY INFORMATION

* WHICH IS THE PROPERTY OF your company.

*

* ========================================

*/

#include "project.h"

#include <stdio.h>

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

*        Function Prototypes

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

void handle_error(void);

void ISR_UART(void);

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

*        Constants

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

#define LED_ON  (0x00u)

#define LED_OFF (!LED_ON)

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

*        Global variables

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

uint32_t read_data;

uint32_t data_received;

uint8_t uart_error;

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

* Function Name: handle_error

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

*

* Summary:

* This function processes unrecoverable errors such as any component

* initialization errors etc. In case of such error the system will switch on

* RED_LED_ERROR and stay in the infinite loop of this function.

*

* Parameters:

*  None

*

* Return:

*  None

*

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

void handle_error(void)

{

     /* Disable all interrupts */

    __disable_irq();

   

    /* Switch on error LED */

    Cy_GPIO_Write(RED_LED_ERROR_0_PORT, RED_LED_ERROR_0_NUM, LED_ON);

    while(1u) {}

}

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

* Function Name: ISR_UART

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

*

* Summary:

*  This function is registered to be called when UART interrupt occurs.

*  (Note that only RX fifo not empty interrupt is unmasked)

*  Whenever there is a data in UART RX fifo, Get that data and Put it into

*  UART TX fifo which will be transmitted to terminal

*

* Parameters:

*  None

*

* Return:

*  None

*

* Side Effects:

*  None

*

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

void ISR_UART(void)

{

    /* Check for "RX fifo not empty interrupt" */

    if((UART1_HW->INTR_RX_MASKED & SCB_INTR_RX_MASKED_NOT_EMPTY_Msk ) != 0)

{

        /* Clear UART "RX fifo not empty interrupt" */

UART1_HW->INTR_RX = UART1_HW->INTR_RX & SCB_INTR_RX_NOT_EMPTY_Msk;       

           

        /* Get the character from terminal */

read_data = Cy_SCB_UART_Get(UART1_HW);

       

        /* Update data_received flag */

        data_received = 1;       

}  

    else

    {

        /* Error if any other interrupt occurs */

        uart_error = 1;

    }

}

int main(void)

{

    __enable_irq(); /* Enable global interrupts. */

    /* Enable CM4.  CY_CORTEX_M4_APPL_ADDR must be updated if CM4 memory layout is changed. */

    Cy_SysEnableCM4(CY_CORTEX_M4_APPL_ADDR);

    /* Place your initialization/startup code here (e.g. MyInst_Start()) */

//    UART1_Start();

    setvbuf (stdin, NULL, _IONBF, 0);

    cy_en_scb_uart_status_t init_status;

       

    /* Start UART operation. */

    init_status = Cy_SCB_UART_Init(UART1_HW, &UART1_config, &UART1_context);

    if(init_status!=CY_SCB_UART_SUCCESS)

    {

        handle_error();

    }

    Cy_SCB_UART_Enable(UART1_HW);  

    char c;

   

    printf("Started UART\r\n");

   

    /* Unmasking only the RX fifo not empty interrupt bit */

    UART1_HW->INTR_RX_MASK = SCB_INTR_RX_MASK_NOT_EMPTY_Msk;

   

    /* Interrupt Settings for UART */   

    Cy_SysInt_Init(&UART_SCB_IRQ_cfg, ISR_UART);

   

    /* Enable the interrupt */

    NVIC_EnableIRQ(UART_SCB_IRQ_cfg.intrSrc);

   

    /* Initialize flags */

    data_received = 0;

    uart_error = 0; 

   

    /* Enable global interrupts. */

    __enable_irq();  

   

   

    for(;;)

    {

        /* Handle received data from terminal */

        if(data_received == 1)

        {

            data_received = 0;

           

            /* Echo the character to terminal */

            while (0UL == Cy_SCB_UART_Put(UART1_HW,read_data))

            {

            }

        }

       

        /* Handle UART error */

        if(uart_error == 1)

        {

            handle_error();

        }

    }

}

/* [] END OF FILE */

0 Likes
1 Solution
ShipingW_81
Moderator
Moderator
Moderator
500 replies posted 250 solutions authored 250 replies posted

Ted,

Did you re-match the interrupt "UART_SCB_IRQ" to cm0+ in Interrupts.dwr?

If not, please uncheck "ARM CM4 Enable" and then check "ARM CM0+ Enable".

If you already did that, can you please attach your project?

View solution in original post

0 Likes
6 Replies
ShipingW_81
Moderator
Moderator
Moderator
500 replies posted 250 solutions authored 250 replies posted

Ted,

Did you re-match the interrupt "UART_SCB_IRQ" to cm0+ in Interrupts.dwr?

If not, please uncheck "ARM CM4 Enable" and then check "ARM CM0+ Enable".

If you already did that, can you please attach your project?

0 Likes

Thanks fwan.  I didn't re match the interrupt which is probably why it doesn't work but I don't see where to do that.  Both the CE219656 example and my code use a standard SCB UART with the Interrupt Mode set to 'internal' under the Advanced tab; I could change it to 'external' and then add a system interrupt but, given that it's working in the CE219656 example, I don't think that's what you mean.

Where do I go to... uncheck "ARM CM4 Enable" and then check "ARM CM0+ Enable"?

Ted

0 Likes
lock attach
Attachments are accessible only for community members.
SuRa_2245351
Level 4
Level 4
First like received First like given

I have attached project in which UART receive ISR is hooked to CM0+. See if it helps you

thanks fwan & rauinst

I'm familiar with PSoC Creator but less so with PSoC6 dual core architecture.  The simple answer to those following in my footsteps is that there is an 'interrupts tab under Deign Wide Resources (see picture) where you can select which core the interrupts for the various modules  you've added belong to - my problem was that UART1_SCB_IRQ was assigned to ARM CM4 and all I did was change it over to ARM CM0+ to make my code work.

DWR_ISR.PNG

0 Likes

rautinst, your code works well but I'm confused as to why the UART delivers 32 bits of data as a time i.e. RxData is uint32_t

I want to capture single characters and store them in a string until I encounter a CR (0x13) at which point I'll flag the string for processing, I also want to add stdio to use printf fro output formatting but I think I already know how to do that.  Any comments on the best way to meet my needs?

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

As you can see in picture data width is 8bit, hence you will receive only one byte.Your requirement to capture single character will be fulfilled also you can typecast it to uint8_t for storing in 8bit variable.