Skip to main content
Associate III
April 17, 2022
Solved

Enabling Serial receive interrupt(UART)

  • April 17, 2022
  • 9 replies
  • 4080 views

Hello

I'm working with spc560p and I want to enable serial receiv​e interrupt, that whenever data received, it save the data and so on.

I could send data by serial driver as sd_dll_write command and its ok. But when I want to use sd_dll_read, actually mcu stopped. It is cleared that I should use interrupt. But need some help.

Thanks​

    This topic has been closed for replies.
    Best answer by ODOUV.1

    Hello,

    happy that it works now.

    You must set sync to 0 before each time you call sd_lld_read:

    if (sync == 1) {

    sync = 0;

    sd_lld_read(...);

    }

    Would you please put a best answer if you are happy of my support.

    Best Regards,

    -Olivier

    9 replies

    ODOUV.1
    ST Employee
    April 25, 2022

    Hello,

    you can look at this example "SPC560Bxx_RLA SERIAL DMA Test Application for Discovery"

    in low level driver, a RX callback is configured in Low Level Drivers Component->LINFkex Settings->SERIAL configurations

    and the configuration structure is given to sd_lld_start in main

    Best Regards,

    -Olivier

    DNewm.1Author
    Associate III
    April 26, 2022

    Thanks Olivier :smiling_face_with_smiling_eyes: ​

    DNewm.1Author
    Associate III
    May 10, 2022

    Hello

    I think this interrupt will be enable when the receive was complete. In this case, I can't read my receive buffer. So as the uart protocol is active low, we need interrupt that enable with falling edge.

    Would you please interduce me interrupt ​that would be enable with falling edge?

    Thanks​

    ODOUV.1
    ST Employee
    May 13, 2022

    Hello,

    we have roughly 2 main ways to read on UART driver.

    1) In synchronous mode (SerialConfig.api_mode=SPC5_LIN_API_MODE_SYNCHRONOUS)

    you call function sd_lld_read(buffer, N) and when it returns, the buffer was fulfilled with N bytes so you can process them.

    2) In asynchronous mode (SerialConfig.api_mode=SPC5_LIN_API_MODE_ASYNCHRONOUS)

    you configure a callback function in SerialConfig.rx_end_cb = myRXCB;

    you reset a global variable sync = 0;

    you call function sd_lld_read(buffer, N) and when it returns, the RX process was started but the buffer is empty.

    when the buffer will be full with N bytes, your callback function will be called:

    void myRXCB(SerialDriver *sdp)

    {

    sync = 1;

    }

    after calling sd_lld_read, you must wait your buffer is full before to process it:

    while(sync == 0);

    Best regards,

    -Olivier

    DNewm.1Author
    Associate III
    May 14, 2022

    Hello Olivier

    Thanks for your attention and answering. I enabled myRXCB and wrote below code:

    void myRXCB(SerialDriver *sdp)

    {

    (void​)sdp;

    sync = 1;

    ​while(sync ==1){

    pal_togglepad(portD, pad7); ​

    }

    }

    Or​

    void myRXCB(SerialDriver *sdp)​

    {

    ​(void​)sdp;​

    sync = 1;​

    ​while(sync ==1){

    sd_lld_write(&SD1, 0xAA, 1); ​​

    }​

    }

    ​and I have another mcu as master to send uart code to my spc560.

    ​But in these two case, nothing happened. No led blinks an no 0xAA.

    ODOUV.1
    ST Employee
    May 16, 2022

    Hello,

    I would recommend you to not put too much code in the callback function, because it should return as soon as possible and avoit re-entrance calling UART interface (such as sd_lld_write)

    at minimum, do never put a while instruction in the callback because you never know how many time you will spend in.

    you could just write it like this:

    void myRXCB(SerialDriver *sdp)

    {

    (void​)sdp;

    sync = 1;

    pal_togglepad(portD, pad7); ​

    }

    and register this myRXCB into the structure passed as second parameter of sd_lld_start

    be sure that your portD and pad7 are well configured and wired to your LED on your PCB

    in order to see the LED toggling, you need to wait at least 200ms between two sd_lld_read in your main program:

      sd_lld_read(&SD1, ... );

       osalThreadDelayMilliseconds(200);

    Best regards,

    -Olivier

    DNewm.1Author
    Associate III
    May 17, 2022

    Hello,

    Thanks for your answering, I tried this method and it works correctly:thumbs_up:. But callback function works once so when sync rest to zero after all, it doesn't work again and callback didn't work as sync = 1 .

    So how should it works again an callback put 1 in sync again too?

    My code:

    ​void myRXCB(SerialDriver *sdp)

    {

    (void​)sdp;

    sync = 1;

    }

    .

    .

    .

    for(; ;){

    if(sync == 1){

    ​sd_lld_read(&SD1, buffer,1);

    ​if(buffer ==0xAA){

    pal_togglepad(portD, pad7);

    }​

    sync=0;

    }

    else{

    sync=0;

    }

    }​

    ODOUV.1
    ST Employee
    May 16, 2022

    Do you use your own PCB ? or do you use one of our Discovery boards ? (SPC56P-Discovery - Discovery Kit for SPC56 P line - with SPC560P50L5 MCU - STMicroelectronics)

    DNewm.1Author
    Associate III
    May 17, 2022

    Hello,​

    I use my own PCB​.

    ODOUV.1
    ST Employee
    May 17, 2022

    Thank you for your answer.

    ODOUV.1
    ODOUV.1Best answer
    ST Employee
    May 17, 2022

    Hello,

    happy that it works now.

    You must set sync to 0 before each time you call sd_lld_read:

    if (sync == 1) {

    sync = 0;

    sd_lld_read(...);

    }

    Would you please put a best answer if you are happy of my support.

    Best Regards,

    -Olivier

    DNewm.1Author
    Associate III
    May 17, 2022

    Thanks for your answering. My problem is solved now.

    Thank you :folded_hands:​

    ODOUV.1
    ST Employee
    May 17, 2022

    Great :ok_hand:

    Have a nice day

    DNewm.1Author
    Associate III
    October 30, 2022

    Hello

    In other projects, I worte below codes but interrupt don't work correctly. It just send 0xAA but it don't recognize any messages.

    int sync =0;

    ​void myRXCB(SerialDriver *sdp){

    (void​)sdp;

    sync = 1;

    }

    for(;;){

    sd_lld_write(0xAA);

    if(sync ==1){

    sync=0;

    sd_lld_read(Buffer);

    }​

    }​

    And when I write below codes, it recognize messages but it just send 0xAA when receive was complete.

    ​for(;;){

    sd_lld_write(0xAA);

    sd_lld_read(Buffer);

    }

    Would you please help me out with this method that MCU send 0xAA and recognize massages ​by uart interrupt.

    Thanks ​