Do UART RX interrupts require support from the transmitter? - microcontroller

I'm trying to understand why I am seeing RX interrupts when tying RX to TX of my SAMR34 but not when I connect it to the transmitting device. The transmitting device notes the following restrictions:
Serial hardware flow controls (RTS/CTS and DTR/DSR) are not used and will be ignored. In addition, the receiver must not use software flow control (XON/XOFF)
I do see data from the transmitter when I poll. Does interrupt driven UART require support from the transmitter? Should I switch to DMA to resolve this issue? Here is my setup

A UART receiver doesn't need support from the transmitter to generate a RX interrupt. A RX interrupt can be enabled and will generate a RX interrupt when a new data unit (7/8/9 bits depending on settings) is received by the UART.
Serial flow control RTS/CTS and DTR/DSR are in most situations not used and can mostly be ignored/disabled. They have some merit in some situations as noted by Peter Smith here on electronics.stackexchange.
You are probably seeing data when you do a loopback because it is doing everything sequentially and as such will do a transmit -> receive -> transmit -> receive. When connecting to an external device the pattern will look like this when transmitting is done in a blocking manner:
transmitter: Transmit Transmit Transmit Transmit Transmit
receive transmitter: Receive->Transmit Receive->Transmit Receive->
This will at least result in missing data because the CPU is busy waiting for the transmit to complete before trying to receive another byte.
DMA is used to move data around without involvement of the CPU. And can be used to transfer incomming data from the IDR to ODR. (Incoming Data Register and Outgoing Data Register)
Another solution would be to have the RX interrupt write the data to a buffer and manage how much of the buffer is used. The TX can then be done on the data without blocking the RX.

Related

What is the "Early Transmit Interrupt" in the STM32F4x Ethernet MAC DMA status register?

My FreeRTOS Ethernet driver pop-out a lot of "Early transmit interrupt" on my STM32F4x board. I did not find any explanation about this "abnormal" interrupt despite :
Indicates that the packet to be transmitted was fully transferred into
the FIFO
So what's the problem ? It looks like everything is going well.
What does it mean ?
Datasheet STM32F401xx :
Ethernet DMA status register (ETH_DMASR) p.1228
BIT 10 ETS: Early transmit status
Ethernet DMA interrupt enable register (ETH_DMAIER) p.1233
BIT 10 ETIE: Early transmit interrupt enable
The Datasheet of PCI 10/100 Ethernet controller STE10/100A gives a good description of what's going on.
As shown on this scheme, there is two possible interrupts on TX :
Normal Transmit Interrupt (TS : bit 0) (summarized among "normal interrupts").
This bit indicates that frame transmission is finished.
Early Transmit Interrupt (ETS : bit 10) (summarized among "abnormal interrupts").
This bit indicates that the frame to be transmitted was fully transferred to the Transmit FIFO. This is the first step in the transmit process.
The second one (ETS) just let the possibility for the Host to detect
and prevent under-run on TX. It is quite a blurry naming for a
simple trick.
Furthermore, this case can occur in "normal" situations when there is only one frame < 1500 bytes to be transmitted.

How to the same DMA Stream with different DMA channel on the Cortex-M7(STM32F746)?

I want to use SPI2 and UART4 peripherals with DMA but, as I see DMA1-SPI2-Tx and DMA1-UART4-Tx uses the same dma stream.
SPI2_TX - DMA1_Stream4 (channel 0)
UART4_TX - DMA1_Stream4 (channel 4)
Is there any way to use the same DMA stream for the different peripherals at the same time?
Is there any way to use the same DMA stream for the different peripherals at the same time?
No, there isn't. Only a single channel can be selected for each stream. Of course if you are not transmitting on both ports at the same time, then you can switch back and forth between channels.
Use another stream
Although it seems that both SPI2 TX and UART4 TX are confined to Stream 4, it is possible to control transmit channels by other means.
Note: this works only with SPI master or UART with no flow control. i.e. as long as the MCU is in complete control of the timing.
There is no rule saying that a DMA transfer should access the same peripheral the request came from (however they must be on the same APB bus for DMA1). It is possible to use e.g. TIM6 (or any other timer connected to DMA1) to generate periodic DMA requests on a stream other than 4, and set up that stream to transfer data from memory to SPI2->DR.
Just set the timer frequency to generate update DMA requests with 1/8 of your SPI bitrate, write a few bytes into SPI2->DR to fill the FIFO, and start the timer.
It would be more tricky with an UART with its various framing options, but it should generally work.

I2C SCL line, clock issue on STM32F4

In I2C interface,
SCL, clock line will transmit clock signals even if there are no devices on the bus?
How can we debug the I2C?
The I2C bus master does not know if there are slave devices connected to the bus.
All it can do is to initiate communication with a certain device by sending the slave's address to the bus (it can be a read or write operation). If the master receives an ACK, acknowledge, then that means the slave is ready (and presented on the bus) to communicate. A NACK, not acknowledge can mean that the slave is not ready. If the request time outs that means, there is no available devices on the bus with the specific address.
Now, back to your question:
SCL, clock line will transmit clock signals even if there are no devices on the bus?
Yes, the clock line will be driven when the master initiates the communication, even if there are not any slaves. The clock is used, as there are data on the bus, the slave device address.
It looks like in the image below, the only difference that the ACK won't be there if there are no slave device on the bus (with that address).
Now as for the debug, the best would be if you could buy a logic analyzer, (cheaper versions are available on eBay or aliexpress) to capture what is going on actually on the bus. The image above has been made using one.

There is any way to disable start and stop bit in serial communication on Linux?

I need a serial communication in 'raw' mode when only the data byte will be transmitted . The purpose is transmitting information using any RF tx module to boards around using bi-phase codification. The start e stop bit don't permit do this with flexibility.

Wire High&Low Address

With regards to Arduino EEPROM when writing and reading to certain EEPROM devices it asks for a transmission of the following format:
Wire.beginTransmission(ADDR);
Wire.write(highADDR);
Wire.write(lowADDR);
Wire.write(data);
Wire.endTransmission();
What do the high address and low address mean? Why can I not just tell it to write to the byte at address 4. Why do I need to prove a high and low?
It looks to me like you are using I2C, I am going to make that assumption and base my answer off of it. Perhaps you should clarify which EEPROM you are using.
The way I2C works is that you can have one master (your Arduino) communicate with multiple slaves (your EEPROM for example) on the same I2C bus. Since it is possible to have multiple slaves connected on the same bus, I2C protocol requires you to specify what slave device you are communicating with. This is what Wire.beginTransmission(ADDR) does. It is selecting which device it wants to initiate communication with. If you want to communicate with your EEPROM you will need to send the address of your EEPROM (you should be able to find the address in the EEPROM datasheet).
Next, you need to specify the memory location inside your EEPROM where you want to access. This is done using the two bytes highADDR and lowADDR. If for instance you wanted to access the address 0x01AB, then set highADDR to 0x01 and lowADDR to 0xAB.
The rest is fairly simple. You send your data then end the transmission.
To Summarize:
Select device to communicate with (Select your EEPROM)
Wire.beginTransmission(ADDR);
Tell your EEPROM what memory address you want to write to
Wire.write(highADDR); // Send the most significant address bits
Wire.write(lowADDR); // Send the least significant address bits
Send data to write.
Wire.write(data);
End the transmission
Wire.endTransmission();
I strongly recommend reading more about how the I2C protocol works. http://en.wikipedia.org/wiki/I%C2%B2C#Message_protocols

Resources