2021-02-11 10:59 PM
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
Solved! Go to Solution.
2021-02-17 06:58 AM
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 :
Best Regards
Erwan
2021-02-12 02:23 AM
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();
}
2021-02-12 04:18 AM
2021-02-15 11:16 AM
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);
}
}
2021-02-16 03:01 AM
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?
static uint16_t sd_rx(SerialDriver* sdp, uint8_t* buffer, uint16_t len)
2021-02-17 04:13 AM
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.
2021-02-17 06:58 AM
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 :
Best Regards
Erwan