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

cross mob
lock attach
Attachments are accessible only for community members.
Manoj_Kumar
Level 3
Level 3
50 sign-ins 25 replies posted 10 questions asked

I want to write and read the data transmitted through RS485. Am using CY8C6245LQI-S3D72 BSP. 

But the issue arises when am trying to read the data, but when i put some breakpoints its reading, and without it, it won't read. So I want the program to read the data with the help of step-in/breakpoints. To verify that, there is a rxCount which should not be 0 once the data is received. Am writing the data via terminal so it should receive that data and the count should increase and it should not be stuck in the loop. Please refer the code provided below.

0 Likes
1 Solution
Gautami_12
Moderator
Moderator
Moderator
50 likes received 100 solutions authored 250 replies posted

Hi @Manoj_Kumar ,

The Rx interrupt was not firing mainly because you were not starting the asynchronous read operation with the API cyhal_uart_read_async().
Please use cyhal_uart_read_async() API instead of cyhal_uart_read() .
Also, I believe you are using an older version of the HAL Library. 
Please update the HAL library from Library Manager as shown below :

Gautami_12_2-1688623367911.png

 

Also please take a look at the PDL based firmware that has been mentioned in this thread as I believe this would be a better implementation compared to the HAL one.

Hope this helps.

Warm Regards,
Gautami J

View solution in original post

0 Likes
9 Replies
Gautami_12
Moderator
Moderator
Moderator
50 likes received 100 solutions authored 250 replies posted

Hi @Manoj_Kumar ,

Please refer to UART to RS485 and Specifications of RS485 TXDEN for CY7C65213A-32LTXI .
Please let us know if you face any problem.

 

Warm Regards,
Gautami J

0 Likes

@Gautami_12 , Thanks for the response.

I have read all these specifications.

I believe if you look at the code, after sending the bytes and getting CYHAL_UART_IRQ_TX_DONE interrupt I am setting the RS485  to be in receiving mode.

Now if the external entity transmits ,I believe I should get the Uart interrupt as the FIF0 may have some data.I am not getting the receive interrupt. I only get data , if I call cyhal_uart_read . 

I am expecting without  cyhal_uart_read in task I should get interrupt as soon as the FIFO has data and then I can read data there.

Let me know if you want any clarifications.

0 Likes
Gautami_12
Moderator
Moderator
Moderator
50 likes received 100 solutions authored 250 replies posted

Hi @Manoj_Kumar ,

The Rx interrupt was not firing mainly because you were not starting the asynchronous read operation with the API cyhal_uart_read_async().
Please use cyhal_uart_read_async() API instead of cyhal_uart_read() .
Also, I believe you are using an older version of the HAL Library. 
Please update the HAL library from Library Manager as shown below :

Gautami_12_2-1688623367911.png

 

Also please take a look at the PDL based firmware that has been mentioned in this thread as I believe this would be a better implementation compared to the HAL one.

Hope this helps.

Warm Regards,
Gautami J

0 Likes

We want to make use of HAL instead of SCB. We don't want to mix-up the usage of both the packages, So please suggest changes using the HAL and not SCB.

0 Likes
MSS
Level 3
Level 3
5 likes given 50 sign-ins 10 replies posted

Gautami,

Thanks for the response. Because of you we have made quick progress.

I am able to send and receive but few blockers.

Please go over the below code. The code configures 4 RS485 over UART and it receives bytes and sends the count of bytes transmitted.(Count may not be accurate due to circular count which is ok, I will fix that later ). Currently receive is happing over event CYHAL_UART_IRQ_RX_DONE, I want to make the same over CYHAL_UART_IRQ_RX_NOT_EMPTY event. Can you please tell me what I need to change to get it.

Blockers:

  1. How to get event CYHAL_UART_IRQ_RX_NOT_EMPTY?
  2. I don't want to miss any data in receiving.
Regards,
Madhav
 
#define CYHAL_UART_DATA_BITS_8     8
#define CYHAL_UART_STOP_BITS_1     1
#define CYHAL_UART_BAUD_115200     115200
 
#define BUFFER_SIZE                64
 
/*******************************************************************************
* Macros
*******************************************************************************/
 
/*******************************************************************************
* Global Variables
*******************************************************************************/
uint8 buff[30] = {0};
/*******************************************************************************
* Function Prototypes
*******************************************************************************/
typedef void (*UartISR)(void *callback_arg, cyhal_uart_event_t event);
typedef void (*SetDirection)(void *obj, bool dir);
 
cyhal_uart_cfg_t uart_config = {
   .data_bits = CYHAL_UART_DATA_BITS_8,
   .stop_bits = CYHAL_UART_STOP_BITS_1,
   .parity = CYHAL_UART_PARITY_NONE,
   .rx_buffer = NULL,
   .rx_buffer_size = 0
};
 
//Madhav  : Struct to keep UART Data / Configuration 
typedef struct {
    UartISR mFunc;
    SetDirection mSetDir;
    cyhal_uart_t uart_obj;
    uint32_t rxCount; 
    uint32_t txCount;  // Just for testing 
    volatile bool isTransmitComplete;
    uint8_t rxBuffer[BUFFER_SIZE];
    uint8_t rxByte;
    cyhal_gpio_t mRE;
    cyhal_gpio_t mDE;
} cbUartData;
 
static cy_rslt_t result;
static cy_rslt_t res;
 
cbUartData cbUartDataObj0;
cbUartData cbUartDataObj1;
cbUartData cbUartDataObj2;
cbUartData cbUartDataObj3;
 
// Madhav : Set direction of RS485 true for transmit and false for receive.
void SetDirectionFunc(void * obj,bool dir ){
cbUartData *uartObj = (cbUartData *)obj;
if(dir){
cyhal_gpio_write(uartObj->mDE, 1);
cyhal_gpio_write(uartObj->mRE, 1);
}else{
cyhal_gpio_write(uartObj->mDE, 0);
cyhal_gpio_write(uartObj->mRE, 0);
}
}
// Madhav: Uart ISR for interrupt.
void UartISRFunc(void *callback_arg,cyhal_uart_event_t event) {
cbUartData *Obj = callback_arg;
if(event == CYHAL_UART_IRQ_RX_NOT_EMPTY) {
// Madhav, Unable to get this event, this is the issue.
bool isBufferEmpty = cyhal_uart_readable(&Obj->uart_obj);
if (!isBufferEmpty) {
uint8_t data;
int len = 1;
cyhal_uart_read(&Obj->uart_obj, &data, &len);
if (Obj->rxCount < BUFFER_SIZE) {
Obj->rxBuffer[Obj->rxCount++] = data;
}
if (Obj->rxCount == BUFFER_SIZE) {
Obj->rxCount = 0;
}
}
cyhal_uart_read_async(&Obj->uart_obj, (void*)Obj->rxBuffer,1);
} else if(event == CYHAL_UART_IRQ_TX_DONE) {
Obj->isTransmitComplete = true;
Obj->mSetDir(Obj,false);
} else if(event == CYHAL_UART_IRQ_RX_DONE) {
if (Obj->rxCount < BUFFER_SIZE) {
Obj->rxBuffer[Obj->rxCount++] = Obj->rxByte;
}
if (Obj->rxCount == BUFFER_SIZE) {
Obj->rxCount = 0;
}
cyhal_uart_read_async(&Obj->uart_obj, (void*)&Obj->rxByte,1);
}
}
 
 
/*******************************************************************************
* Function Definitions
*******************************************************************************/
void uart_interrupt_handler0(void *callback_arg, cyhal_uart_event_t event) {
UartISRFunc( callback_arg,event);
}
 
void InitializeUart(cbUartData *uartObjData, cyhal_gpio_t tx, cyhal_gpio_t rx, cyhal_uart_cfg_t *pUartConfig) {
    /* Initialize the UART peripheral */
    res = cyhal_uart_init(&uartObjData->uart_obj, tx, rx, NC, NC,NULL,pUartConfig);
    if (res != CY_RSLT_SUCCESS) {
        CY_ASSERT(0);
    }
    res = cyhal_uart_configure(&uartObjData->uart_obj, pUartConfig);
    if (res != CY_RSLT_SUCCESS) {
        CY_ASSERT(0);
    }
    res = cyhal_uart_set_baud(&uartObjData->uart_obj, CYHAL_UART_BAUD_115200,NULL);
    if (res != CY_RSLT_SUCCESS) {
        CY_ASSERT(0);
    }
    /* Set up the UART interrupt */
    cyhal_uart_register_callback(&uartObjData->uart_obj, uartObjData->mFunc, uartObjData);
    res = cyhal_uart_set_fifo_level(&uartObjData->uart_obj, CYHAL_UART_FIFO_RX ,1);
    if (res != CY_RSLT_SUCCESS) {
CY_ASSERT(0);
}
    cyhal_uart_enable_event(&uartObjData->uart_obj, CYHAL_UART_IRQ_RX_NOT_EMPTY | CYHAL_UART_IRQ_TX_DONE| CYHAL_UART_IRQ_RX_DONE, 3, true);
}
 
void rs485_pin_init() {
 
res=cyhal_gpio_init(RS485_3_RE_PIN, CYHAL_GPIO_DIR_OUTPUT, CYHAL_GPIO_DRIVE_STRONG, CYHAL_GPIO_VALUE_HIGH);
if (res != CY_RSLT_SUCCESS) {
CY_ASSERT(0);
}
 
res=cyhal_gpio_init(RS485_3_DE_PIN, CYHAL_GPIO_DIR_OUTPUT, CYHAL_GPIO_DRIVE_STRONG, CYHAL_GPIO_VALUE_HIGH);
if (res != CY_RSLT_SUCCESS) {
CY_ASSERT(0);
}
 
res=cyhal_gpio_init(RS485_0_DE_PIN, CYHAL_GPIO_DIR_OUTPUT, CYHAL_GPIO_DRIVE_STRONG, CYHAL_GPIO_VALUE_HIGH);
if (res != CY_RSLT_SUCCESS) {
CY_ASSERT(0);
}
res=cyhal_gpio_init(RS485_0_RE_PIN, CYHAL_GPIO_DIR_OUTPUT, CYHAL_GPIO_DRIVE_STRONG, CYHAL_GPIO_VALUE_HIGH);
if (res != CY_RSLT_SUCCESS) {
CY_ASSERT(0);
}
 
res=cyhal_gpio_init(RS485_1_DE_PIN, CYHAL_GPIO_DIR_OUTPUT, CYHAL_GPIO_DRIVE_STRONG, CYHAL_GPIO_VALUE_HIGH);
if (res != CY_RSLT_SUCCESS) {
CY_ASSERT(0);
}
res=cyhal_gpio_init(RS485_1_RE_PIN, CYHAL_GPIO_DIR_OUTPUT, CYHAL_GPIO_DRIVE_STRONG, CYHAL_GPIO_VALUE_HIGH);
if (res != CY_RSLT_SUCCESS) {
CY_ASSERT(0);
}
 
res=cyhal_gpio_init(RS485_2_DE_PIN, CYHAL_GPIO_DIR_OUTPUT, CYHAL_GPIO_DRIVE_STRONG, CYHAL_GPIO_VALUE_HIGH);
if (res != CY_RSLT_SUCCESS) {
CY_ASSERT(0);
}
res=cyhal_gpio_init(RS485_2_RE_PIN, CYHAL_GPIO_DIR_OUTPUT, CYHAL_GPIO_DRIVE_STRONG, CYHAL_GPIO_VALUE_HIGH);
if (res != CY_RSLT_SUCCESS) {
CY_ASSERT(0);
}
}
 
void InitializePins(){
rs485_pin_init();
cbUartDataObj0.mFunc = UartISRFunc;
cbUartDataObj0.mSetDir = SetDirectionFunc;
cbUartDataObj0.isTransmitComplete =true;
cbUartDataObj0.rxCount =0;
cbUartDataObj0.mDE = RS485_0_DE_PIN;
cbUartDataObj0.mRE = RS485_0_RE_PIN;
InitializeUart(&cbUartDataObj0, UART_0_TX_PIN , UART_0_RX_PIN , &uart_config);
cbUartDataObj0.mSetDir(&cbUartDataObj0,false);
 
 
cbUartDataObj1.mFunc = UartISRFunc;
cbUartDataObj1.mSetDir = SetDirectionFunc;
cbUartDataObj1.isTransmitComplete =true;
cbUartDataObj1.rxCount =0;
cbUartDataObj1.mDE = RS485_1_DE_PIN;
cbUartDataObj1.mRE = RS485_1_RE_PIN;
InitializeUart(&cbUartDataObj1, UART_1_TX_PIN , UART_1_RX_PIN , &uart_config);
cbUartDataObj1.mSetDir(&cbUartDataObj1,false);
 
cbUartDataObj2.mFunc = UartISRFunc;
cbUartDataObj2.mSetDir = SetDirectionFunc;
cbUartDataObj2.isTransmitComplete =true;
cbUartDataObj2.rxCount =0;
cbUartDataObj2.mDE = RS485_2_DE_PIN;
cbUartDataObj2.mRE = RS485_2_RE_PIN;
InitializeUart(&cbUartDataObj2, UART_2_TX_PIN, UART_2_RX_PIN, &uart_config);
cbUartDataObj2.mSetDir(&cbUartDataObj2,false);
 
cbUartDataObj3.mFunc = UartISRFunc;
cbUartDataObj3.mSetDir = SetDirectionFunc;
cbUartDataObj3.isTransmitComplete =true;
cbUartDataObj3.rxCount =0;
cbUartDataObj3.mDE = RS485_3_DE_PIN;
cbUartDataObj3.mRE = RS485_3_RE_PIN;
InitializeUart(&cbUartDataObj3, UART_3_TX_PIN, UART_3_RX_PIN, &uart_config);
cbUartDataObj3.mSetDir(&cbUartDataObj3,false);
 
}
 
void UartTask(cbUartData *cbUartDataObj) {
//result=cyhal_uart_writable(&cbUartDataObj1.uart_obj);
int cnt=0;
if(cbUartDataObj->rxCount != cbUartDataObj->txCount){
cbUartDataObj->txCount = cbUartDataObj->rxCount;
int len = sprintf(buff,"Rx Count %d \n",cbUartDataObj->rxCount);
cbUartDataObj->mSetDir(cbUartDataObj,true);
cbUartDataObj->isTransmitComplete = false;
result = cyhal_uart_write_async(&cbUartDataObj->uart_obj, buff, len);
// vTaskDelay(100);
while (!cbUartDataObj->isTransmitComplete) {
vTaskDelay(100);
}
}
cyhal_uart_read_async(&cbUartDataObj->uart_obj, (void*)&cbUartDataObj->rxByte,1);
vTaskDelay(10);
}
 
void UART_Comm(){
//InitializePins();
while(1){
UartTask(&cbUartDataObj0);
UartTask(&cbUartDataObj1);
UartTask(&cbUartDataObj2);
UartTask(&cbUartDataObj3);
vTaskDelay(10);
}
}
 
 

 

0 Likes
MSS
Level 3
Level 3
5 likes given 50 sign-ins 10 replies posted

@Gautami_12 , It's still not solved as we want to use CYHAL_UART_IRQ_RX_NOT_EMPTY event in our flow please let me know how to get those event, any example will be appreciated.

0 Likes
Manoj_Kumar
Level 3
Level 3
50 sign-ins 25 replies posted 10 questions asked

@Gautami_12 The question 1 & 2 asked by @MSS , If I send too many bytes(20-30 bytes) then the number of received bytes is wrong. It means we are losing some bytes. If I send few bytes like 2-10 bytes then the count is correct and all the bytes are received. So we wants to read the bytes in such a way that it should handle  all the incoming bytes (bytes may be more than 30 also) and we don't miss any bytes. 

0 Likes
Gautami_12
Moderator
Moderator
Moderator
50 likes received 100 solutions authored 250 replies posted

Hi @MSS ,

You need to create buffer-array of char and a variable as counter of the received char. 

#define UART_RX_BUFFER_SIZE		64
char uart_rx_buffer[UART_RX_BUFFER_SIZE];
size_t rx_count = 0;

void rx_cback(void *handler_arg, cyhal_uart_event_t event)
{
    (void) handler_arg;
    BaseType_t xYieldRequired = pdFALSE;
    if ( ((event&CYHAL_UART_IRQ_RX_DONE) == CYHAL_UART_IRQ_RX_DONE ) || ((event & CYHAL_UART_IRQ_RX_NOT_EMPTY) == CYHAL_UART_IRQ_RX_NOT_EMPTY) )
    {
    	uart_rx_buffer[rx_count] = rx_buffer;
		rx_count++;
    	if( rx_count >= UART_RX_BUFFER_SIZE )
			rx_count=0;
		while(cyhal_uart_read_async(&cy_retarget_io_uart_obj, &rx_buffer, 1)==CY_SCB_UART_RECEIVE_BUSY );
    	xQueueSendFromISR( xUARTQueue, &rx_buffer, &xYieldRequired);
    	portYIELD_FROM_ISR(xYieldRequired);
    }
}

void print_buffer()
{
	my_printf(" %d - %s \r\n", rx_count, uart_rx_buffer);
	// clear the buffer and reset the counter
	memset(uart_rx_buffer,'\0',UART_RX_BUFFER_SIZE);
	rx_count = 0;
}


You can call the print_buffer to print the received characters. Hope this helps.

Warm Regards,
Gautami J

0 Likes
Manoj_Kumar
Level 3
Level 3
50 sign-ins 25 replies posted 10 questions asked

@Gautami_12 , We want to raise an interrupt during reading process, and we have enabled the read_async() at start itself, so it will be continuously waiting  for reading and giving us the interrupt. I believe we should instead of getting  CYHAL_UART_IRQ_RX_DONE  interrupt, is it possible to get CYHAL_UART_IRQ_RX_NOT_EMPTY ?

I want to understand the flow of how to get CYHAL_UART_IRQ_RX_NOT_EMPTY  interrupt.

An explanation with example would be appreciable.

0 Likes