Does anybody have experience with the UART and DMA on the 1769 lpcxpresso board without the baseboard? I can get it to transmit the FIFO buffer but I am not able to get it to acknowledge any received chars. If it matters I am using the MCB1700, DMA-UART example code. Is there any place where I can get code examples to get this to work?
I am using the MCB1700 example code which comes with the lpcxpresso code_red. This uses UART0 and UART1 thru a RS-232 cable and 2 DMA channels. but the RS232 connection to connect the 2 ports is on the baseboard but I don't have one. I am just using wires on a breadboard to hook up UART0 TX to UART1 RX and the UART1 TX to the UART0 RX. I am notified that I received the 16 byte FIFO buffer from UART1 but when UART0 transmits to UART1, I am not getting the flag set saying I received the characters on the other DMA channel. I am wondering if something is not being initialized correctly
Related
I'm developing a RF modem based on a new protocol, which has a feature of streaming 96 Bytes in one frame - but they are sent on and on, before communication ends. I plan using two 96 Bytes buffers in STM32 - in next lines I will explain why.
I want to send first 96 Byte frames by the USB-CDC to STM32 - then external modem chip will generate a "9600bps" clock and STM will have to write Payload bits by bits on specified output pin(at the trailing edge of the each clock pulse).
When STM32 will notice that it had sent a half of 96 Byte frame - that it sent to PC notification to send more data - PC will refill second 96 Byte buffer by USB-CDC immediately. When STM32 will end sending first buffer - immediately starts sending second buffer content. When it will send half of second buffer - as previous will ask PC for another 96Byte frame.
And that way all the time, before PC will sent command to stop tx.
This transfer mode - a serial, with using a "trigger clock".
Is this possible using DMA, and how could I set it?
I want to use DMA to have ability to use USB while already streaming data to the radio modem chip. Is this the right approach?
I'm working in project building an opensource radiocommunication system project with both packet and stream capatibilities & digital voice. I'm designing and electronics for PC radiomodem. Project is called M17 and is maintained by Wojtek SP5WWP.
Re. general architecture. Serial communication over USB ACM does not have to use buffer of the same size and be synchronized with the downstream communication over SPI. You could use buffers as big as practically possible so PC can send data in advance. This will reduce the chance of buffer underflow if PC does not provide data fast enough. Use a circular buffer and fill it when a packet arrives from USB.
DMA is the right approach. Although people often say that DMA is only necessary for high bandwidth operations, it may be actually easier to work with DMA than handling interrupts per every byte, even when you only handle 9600 bits per second.
DMA controller in STM32F3 has a Half-Transfer Complete (HTIF in DMA_ISR) bit that you can poll or make it generate and interrupt. In conjunction with the Transfer Complete status (TCIF) and the Circular bit (CIRC in DMA_CCR) you can organize a double-buffered data pipe so that transfers can overlap with whatever else the MCU is doing. The application will reload the first half of the DMA buffer on the HTIF event. When the TCIF event happens, it reloads the second half. It has to be done quickly, before the other half is also completed. However, you need a double buffered pipeline only when you need to constantly stream data, i.e. overall amount is larger than can the size of the DMA buffer.
Stopping a circular DMA may be tricky. I suppose both the STM32 and external chip know how many bytes to send. In that case, after this amount is received, disable the DMA.
It seems you need a slave SPI in STM32 as the external chip generates SPI clock.
DMA is not difficult to set up, however, it needs multiple things to work properly. I assume register-level programming, if you use some kind of framework, you'll need to find out how it implements these features. Enable clocks for SPI, GPIO port for SPI pins, and DMA, configure the pins as AF. Find the right DMA channel for the SPI peripheral. In case of SPI DMA you usually need two channels: TX and RX, but with the slave SPI, you may get away with one. Configure SPI, pay attention to clock polarity and phase, and set it to generate a DMA request for each TX and/or RX. Set the DMA CPAR channel register pointing to the SPI DR register in channel(s) and program all other DMA channel registers appropriately. Enable the DMA channel(s). Enable SPI in slave mode. When the SPI master clocks data on the MOSI/SCK pins, the DMA controller will put them in memory. When the buffer is half-full and full-full, the channel will set the HTIF and TCIF bits and generate and interrupt, if you told it to. Use these events to implement flow control.
I am trying to communicate with a serial device via a ch341 based usb-serial adapter (wemos.cc / ch340). Since the target device has limited buffer size it uses a signal line to indicate if it is safe to send bytes.
I have confirmed that the level of the CTS# pin is connected correctly: the state of the pin is visible with the "statserial" utility and is propagated to the "Clear To Send" flag (logically inverted, which matches the "datasheet" of the ch341).
I am enabling RTS/CTS flow control via the CRTSCTS flag in tcsetattr(), also the CLOCAL flag is set to avoid waiting for the DCD signal.
However, this does not seem to have an effect on the behaviour of the ch341. When connecting the CTS# pin to either VCC or GND the ch341 happily accepts all the data sent to the chip via the /dev/ttyUSB0 device. I'd expect it to block when the chip-internal buffers are filled up until CTS# gets low, allowing it to send the data to the TX pin...
Is there something I am missing? Or is CTS not implemented on the ch341?
Thanks,
Simon.
When I upload code to my Arduino while the TX and RX pins are connected to my HC-05 module, a bunch of random characters are sent to the TX buffer, and when I connect to a device, those characters are sent and mess up communication. Is there a way that I can clear this buffer after uploading the code? I've just been disconnecting the wires whenever I upload, but I'd like to find an easier way. Thanks!
Well, if you use a serial port to both send data and the program of course you will see it on the other side of the BT... Possible solutions:
disconnect the BT module every time you want to program the Arduino
shut down the other BT device (or just disconnect it) when you have to program the Arduino
shut down the HC-05 (or keep it in reset state) until the arduino says that it is communicating (so use a GPIO to control the reset pin or a transistor to power the BT on at the beginning of the program)
use a 3-state driver between the HC-05 and the Arduino serial ports (one driver for TX and one for RX) and activate its outputs at the beginning of the arduino program.
I don't like djUniversal's solution because you cannot control what the PC transmits; if, for instance, you decide to use the byte 0xAA to signal the start of the transmission then if the PC sends 0xAA the other device thinks that the Arduino is transmitting. Choosing longer bytes sequences helps, because the sequence becomes less probable, but.....
Moreover you have to send it at EVERY command, not just at the beginning, because you have to reset the arduino to program it (and so the other device is not aware of WHEN to stop considering the data).
The only other way around it is to send a header of maybe a couple of bytes each time to send a message. The other program can wait for these characters before it starts to take commands. Until those characters are read from the buffer you would just do a Serial.read() loop to get rid of the garbage.
Also, if garbage characters are going to screw up your program really badly you might want to think about creating some kind of crude checksum also to confirm the correct transmission.
Need help coding? Let me know.
I have an application that sends 8000 audio packets per second. Now initially for experimenting purpose I am preparing a buffer of 8 audio packets and then making an IOCTL call and passing the buffer to my driver.
I am using "USB analyser". From the USB analyser I got that the inter packet gap(IPG) is around 20-40 usec. That is fine. But sometimes the IPG shows 200-300usec. Is it the USB subsystem(USB core/HCD) that is playing the role or the implementation of ioctl ?. Making >1000 ioctl calls and "copy_from_user"per second may be the culprit behind the late submission of packets. And moreover i am using USB3.0 which is capable of supporting 5 GBps data rate.
The code flow in my driver is like :
switch(cmd)
{
case SEND_AUDIO:
copy_from_user(...,....,...);
for(i=0; i<8; i++);
usb_bulk_msg();
break;
}
I created a WP8 App. It connects to the Bluetooth and detected it.and the Bluetooth module connected as well. But the data are not coming from the Arduino to the phone :(
error code
if(btSerial.available()) {
Serial.println(distance);
btSerial.write(distance);
}
else {
Serial.println("error"); -> always prints this
}
in the code always the error part is printing in the serial monitor. I have attached the pins in the Bluetooth device to below pins.
RXD - 11,
TXD - 10,
GND - GND,
VCC - 5v,
Please help me why is btSerial.available() is not firing ?
You have the logic backwards. available() tests whether the Arduino has data in its receive buffer. It does not test if the connection is ready. So the overall pattern of a serial program
if(someserial.available()) {
someserial.read... loop to get input
print stuff received
}
To write, just write.
//no if's just go
someserial.write("my output")
You do not need to wait. With the two wire serial connection, you have no flow control. In other words, there is no signalling between arduino and bluetooth transceiver about ready or other status. Because the baud rate of the bluetooth link exceeds the baud rate of the arduino serial link, you can't really overflow the bluetooth transmit stream.
The bluetooth aspect of negotiating the connection is meant to be transparent to the Arduino. In other words, your program is the same as if you where using a hardware serial port. If for some reason, you need details into the connection, there are special byte sequences that allow communication with the bluetooth hardware.