Skip to main content
Orazio
Associate II
February 12, 2021
Solved

How to generate UART RX INTERRUPT WITH SPC58EC-DISP

  • February 12, 2021
  • 4 replies
  • 4897 views

Hello All,

I am working on UART on SPC58EC-disp Discovery board importing and using example source code "SPC58ECxx_RLA SERIAL DMA Test Application for Discovery" in SPC5Studio.

I can transmit the data but unable to receive the data by interrupt method to avoid blocking.

In the original project, I have only changed, in the main.c file,  the two highlighted row as follow:

#include "components.h"

#include "serial_lld_cfg.h"

void sddmatxcb(SerialDriver *sdp) {

 (void)sdp;

 pal_lld_togglepad(PORT_F, PF_LED1);

}

void sddmarxcb(SerialDriver *sdp) {

 (void)sdp;

 pal_lld_togglepad(PORT_F, PF_LED2);

}

int main(void) {

 uint8_t message[]= "Hello World!\r\n";

 /* Enable Interrupts */

 irqIsrEnable();

 sd_lld_start(&SD1, &serial_config_sddmacfg);

 /* Application main loop.*/

 for ( ; ; ) {

  (void)sd_lld_write(&SD1,message,(uint16_t)(sizeof(message)/sizeof(message[0])));

  osalThreadDelayMilliseconds(1500);

  //pal_lld_togglepad(PORT_F, PF_LED2);

 }

}

Doing Debug firmware with UDE STK 5.0, and putting a breakpoint in "sddmarxcb" callback function, i observe that never entry in this function. Please guide me with Rx interrupt initialization so that I can receive the data without blocking.

Thank You,

Orazio

    This topic has been closed for replies.
    Best answer by Erwan YVIN

    Hello ,

    Sorry for the late answer ;)

    Good to see that your have solved your issue.

    Adapt the driver is a good choice.

    For the big project relative to collect some data coming from UART. (Near-space balloon, Automotive project and so on ..)

    we are using :

    • Chibios / FreeRTOS threads to save CPU
    • some functions serial_input.c / .h with Runtime Components (cf Screenshot)

    0693W000008GRgIQAW.png 

    Best Regards

    Erwan

    4 replies

    Orazio
    OrazioAuthor
    Associate II
    February 12, 2021

    I would like to add more details.

    Debugging fw with UDE STK 5.0 and putting a breakpoint in "spc5_linflex.c" file and exactly in IRQ_HANDLER(SPC5_LINFLEX0_ERR_HANDLER) function

    I observe that arrive in this function . So it means that when i send a byte in rx channel, it rise an error interrupt managed by SPC5_LINFLEX0_ERR_HANDLER.

    But i don't understand the cause. Can some one help me ?

    IRQ_HANDLER(SPC5_LINFLEX0_ERR_HANDLER) {

     IRQ_PROLOGUE();

     LinflexD1.err_lincallback(LinflexD1.device);

     IRQ_EPILOGUE();

    }

    Orazio
    OrazioAuthor
    Associate II
    February 12, 2021

    ..

    Orazio
    OrazioAuthor
    Associate II
    February 15, 2021

    I changed the code, as indicated in the attached file. Now the uart is able to receive the data and to enter the "sddmarxcb" callback function but only once.

    Any suggestions ?

    Thanks

    #include "components.h"

    #include "serial_lld_cfg.h"

    #include <string.h>

    uint8_t typedChar[1] = " ";

    void sddmatxcb(SerialDriver *sdp) {

     (void)sdp;

     pal_lld_togglepad(PORT_F, PF_LED1);

    }

    void sddmarxcb(SerialDriver *sdp) {

     (void)sdp;

     pal_lld_togglepad(PORT_F, PF_LED2);

     (void)sd_lld_read(&SD1, typedChar, 1);

    }

    int main(void) {

     char message[64];

     componentsInit();

     /* Enable Interrupts */

     irqIsrEnable();

     /*

      * Activates the serial driver 1 using the driver default configuration.

      */

     sd_lld_start(&SD1, &serial_config_sddmacfg);

      

     (void)sd_lld_read(&SD1, typedChar, 1);

      

     /* Application main loop.*/

     for ( ; ; ) {

    strncpy (message, "Type a character - Last char typed was :", sizeof("Type a character - Last char typed was :"));//uint8_t message[]= "Hello World!\r\n";

      strcat(message, (char *)typedChar);

      strcat(message, "\r\n");

      (void)sd_lld_write(&SD1, (uint8_t *) message,(uint16_t)(sizeof(message)/sizeof(message[0])));

      osalThreadDelayMilliseconds(1500);  

     }

    }

    Orazio
    OrazioAuthor
    Associate II
    February 16, 2021

    In this post, someone describe the same issue.

    https://community.st.com/s/question/0D53W000005pnUKSAY/how-can-i-programming-uart-interruptsdlldread

    Please Erwan YVIN can you explaine how to adapt the driver, so to have interrupts run whenever I receive data?

    1. **
    2. * @brief Serial read without DMA
    3. *
    4. * @param[in] sdp pointer to a @p SerialDriver object
    5. * @param[out] buffer data buffer receiver
    6. * @param[out] len number of bytes received
    7. *
    8. * @return The number of bytes effectively read.
    9. *
    10. * @notapi
    11. */

    static uint16_t sd_rx(SerialDriver* sdp, uint8_t* buffer, uint16_t len)

    Orazio
    OrazioAuthor
    Associate II
    February 17, 2021

    Hi to all. Thanks a lot for the support received.

    I have solved my issue, using a workaround. I would share the solution for two reasons. First one oriented to have a feedback from you about the actions applied by me to adapt the driver. Second one oriented to share a solution for otherone afflicted by the same issue.

    The work around consist in adapt spc5xx_serve_rxi interrupt function in the serial_lld.c file as follow

    /**
     
     * @brief Common RXI IRQ handler.
     
     *
     
     * @param[in] sdp pointer to a @p SerialDriver object
     
     */
     
    static void spc5xx_serve_rxi_interrupt(uint32_t isdp) {
     
     SerialDriver *sdp = (SerialDriver *) isdp;
     
     uint16_t sr = sdp->linflexlp->UARTSR.R;
     
     
     
     sdp->linflexlp->UARTSR.R = (uint16_t)(SPC5_UARTSR_NF | SPC5_UARTSR_DRF | SPC5_UARTSR_PE0);
     
     
     
     if ((sr & SPC5_UARTSR_DRF) == SPC5_UARTSR_DRF) {
     
     if(sdp->config->api_mode != SPC5_LIN_API_MODE_BUFFERED_IO) {
     
     *sdp->rx_buf = (uint8_t)sdp->linflexlp->BDRM.B.DATA4;
     
     //sdp->rx_buf++; // opistara 2021-02-17
     
     sdp->linflexlp->UARTSR.R = (uint16_t)SPC5_UARTSR_RMB;
     
     //sdp->rx_len--; // opistara 2021-02-17
     
     sdp->rx_len = 0; // opistara 2021-02-17
     
     
     
     if (sdp->rx_len == 0UL) {
     
     //sdp->linflexlp->UARTCR.B.RXEN = 0; // opistara 2021-02-17
     
     //sdp->linflexlp->LINIER.B.DRIE = 0; /* Interrupts disabled. */ // opistara 2021-02-17
     
     if (sdp->linflexlp->UARTCR.B.TXEN == 0UL) {
     
     sdp->linflexlp->LINIER.R &= ~((uint16_t)(SPC5_LIN_INTERRUPTS));
     
     }
     
     
     
     /* Call the related callback.*/
     
     if (sdp->config->rx_end_cb != NULL){
     
     sdp->config->rx_end_cb(sdp);
     
     }
     
     
     
     SPC5_LIN_RX_DONE(sdp);
     
     }
     
     } else {
     
     *sdp->rx_write_ptr = (uint8_t)sdp->linflexlp->BDRM.B.DATA4;
     
     sdp->rx_write_ptr++;
     
     if (sdp->rx_write_ptr == sdp->rx_end_ptr) {
     
     sdp->rx_write_ptr = sdp->rx_buffered_io;
     
     }
     
     if (sdp->rx_write_ptr == sdp->rx_read_ptr) {
     
     sdp->rx_read_ptr++;
     
     if (sdp->rx_read_ptr == sdp->rx_end_ptr) {
     
     sdp->rx_read_ptr = sdp->rx_buffered_io;
     
     }
     
     }
     
     }
     
     }
     
    }
     

    I attach both main.c and serial_ldd.c file.

    /****************************************************************************
    *
    * Copyright © 2018-2019 STMicroelectronics - All Rights Reserved
    *
    * License terms: STMicroelectronics Proprietary in accordance with licensing
    * terms SLA0089 at www.st.com.
    * 
    * THIS SOFTWARE IS DISTRIBUTED "AS IS," AND ALL WARRANTIES ARE DISCLAIMED, 
    * INCLUDING MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
    *
    * EVALUATION ONLY – NOT FOR USE IN PRODUCTION
    *****************************************************************************/
     
    /* Inclusion of the main header files of all the imported components in the
     order specified in the application wizard. The file is generated
     automatically.*/
    #include "components.h"
     
    #include "serial_lld_cfg.h"
    #include <string.h>
     
    uint8_t typedChar[1] = " ";
    char message[64];
    char text[50];
     
     
    void sddmatxcb(SerialDriver *sdp) {
     (void)sdp;
     pal_lld_togglepad(PORT_F, PF_LED1);
    }
     
     
     
    void sddmarxcb(SerialDriver *sdp) {
     (void)sdp;
     pal_lld_togglepad(PORT_F, PF_LED2);
     if (typedChar[0] == 33) strncpy (text, "", sizeof("")); //ascii code for ! is 33
     else strcat(text, (char *)typedChar);
    }
     
     
     
     
    /*
     * Application entry point.
     */
    int main(void) {
     
     
     /* Initialization of all the imported components in the order specified in
     the application wizard. The function is generated automatically.*/
     componentsInit();
     
     /* Enable Interrupts */
     irqIsrEnable();
     
     /*
     * Activates the serial driver 1 using the driver default configuration.
     */
     sd_lld_start(&SD5, &serial_config_sddmacfg);
     (void)sd_lld_read(&SD5, typedChar, 1);
     
     
     
     /* Application main loop.*/
     for ( ; ; ) {
    	strncpy (message, "\r\nType a char (! to clear Text) - Last char typed was:", sizeof("\r\nType a char (! to clear Text) - Last char typed was:"));//uint8_t message[]= "Hello World!\r\n";
     strcat(message, (char *)typedChar);
     strcat(message, "\r\nText: ");
     
     (void)sd_lld_write(&SD5, (uint8_t *) message, (uint16_t) strlen(message) );
     
     osalThreadDelayMilliseconds(100);
     
     (void)sd_lld_write(&SD5, (uint8_t *) text, (uint16_t) strlen(text) );
     
     osalThreadDelayMilliseconds(1500);
     }
    }

    I will check your feedback regarding the workaround adopted.

    Thank you very much.

    Erwan YVIN
    Erwan YVINBest answer
    ST Employee
    February 17, 2021

    Hello ,

    Sorry for the late answer ;)

    Good to see that your have solved your issue.

    Adapt the driver is a good choice.

    For the big project relative to collect some data coming from UART. (Near-space balloon, Automotive project and so on ..)

    we are using :

    • Chibios / FreeRTOS threads to save CPU
    • some functions serial_input.c / .h with Runtime Components (cf Screenshot)

    0693W000008GRgIQAW.png 

    Best Regards

    Erwan