Hello, I am using two RM48L952 Hercules microcontrollers.
WHAT HAPPENED
I need to exchange data using the SCI (using the SCI module and NOT the LIN module in SCI mode). The communication can happen anywhere, so the second microcontroller can't wait forever for the communication.
I wrote the init, send, receive and hasData functions. I can see in the oscilloscope the microcontroller sending data without any problems. When I use the hasData function to check if any data was received I can see that the flag was not set, but when I put a breakpoint in the code and check the registers I can see that the data has been received correctly but it hasn't set the flag.
I didn't pay it any attention and simply removed the hasData function and started receiving the data by using the read function. I saw that I received the correct data and then keep on going. At that moment both microcontrollers get stuck in a send function. Apparently after doing this, reading the byte by force the tx and rx flags never get set anymore and then they get stuck forever waiting for the tx ready bit to be set or the rx bit, when I put the hasData function in.
Here's my code:
/*SCI FUNCTIONS*/ void init(void) { SCIReg->SCIGCR0 = 0U; /*Get the module out of reset*/ SCIReg->SCIGCR0 |= 1U; /*Clear interrupts*/ SCIReg->SCICLEARINT = 0xFFFFFFFFU; SCIReg->SCICLEARINTLVL = 0xFFFFFFFFU; /*Configure Global Control Register*/ SCIReg->SCIGCR1 = ((1 << 1) | /*Asynchronous mode*/ (1 << 5) | /*Use internal clock*/ (1 << 4) | (1 << 24) | /*Enable RX*/ (1 << 25)); /*Enable TX*/ SCIReg->BRS = (53 | (4 << 24)); SCIReg->SCIFORMAT = 7; SCIReg->SCIPIO0 = (1 << 1) | /*RX pin is SCI RX*/ (1 << 2); /*TX pin is SCITX*/ SCIReg->SCIPIO1 = (0 << 2); /*RX pin is SCI RX*/ /*TODO: verificar linha*/ SCIReg->SCIPIO8 = (1 << 1) | (1 << 2); /**/ SCIReg->SCIGCR1 |= (1U << 7); } void send(const uint8_t *data, uint32_t size) { uint32_t i; for(i = 0; i < size; i++) { while((SCIReg->SCIFLR & SCI_TXMASK) == 0) {} uint8_t test = *data++; SCIReg->SCITD = test; } } void receive(uint8_t *buf) { while((SCIReg->SCIFLR & SCI_RXMASK) == 0) {} *buf++ = (uint8_t)SCIReg->SCIRD; } void receiveByte(uint8_t *byte) { *byte = (uint8_t)SCIReg->SCIRD; } bool hasData(void) { bool f = (SCIReg->SCIFLR & SCI_RXMASK != 0); if(f != false) { SCIReg->SCIFLR |= SCI_RXMASK; } return f; } /*MY USAGE OF THE FCUNTIONS first hercules*/ uint8_t firstByte = 50; uint8_t received[12]; send(&firstByte, 1); if(hasData()) receiveByte(&received[0]); send("myString",9); /*MY USAGE OF THE FCUNTIONS second hercules*/ uint8_t received[12]; if (hasData()) { receiveByte(&received[0]); if(received[0] != expected) return; send("otherString", 12); }
The code above is a very simplified usage of my code, but it still fails. Literally the flags are not signalling the module, which may mean that there's something wrong with my code, but I verified it against HALcogen and I can't see a problem.
By the way, DMA is out of the question as well as receiving by interrupt.
MY INTENTIONS
From what I understand this module is double-buffered meaning that it can store 2 bytes in the TX and RX buffers (am I right?) before being overrun. This checks out in the code because it can send and receive the byte in the register 2 times before halting (both channels literally send 2 times before halting in the send function).
As I can't guarantee that both micorcontrollers will be at the same time at the same place in order to send and receive the buffer and the microcontroller's internal buffer consists of only 2 bytes, I intended to send one byte to synchronize both channels (micro1 sends a byte and waits for a response) so that it can send the rest of the buffer as well as receive a buffer from micro2