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

How to generate UART RX INTERRUPT WITH SPC58EC-DISP

  • February 12, 2021
  • 6 replies
  • 4971 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

    6 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 Technical Moderator
    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

    In order to give better visibility on the answered topics, please click on 'Best answer' on the reply which solved your issue or answered your question.