Cannot send packets over USBSerial on KL25Z - mbed

I have tried many different drivers and cannot successfully send data from the uC to the computer over USBSerial. I am trying the mbed-official USBSerial driver but have had the same results with the KL25Z fork and the ST micro fork as well as mbed OS2 an OS5. I am able to receive bytes freely from the computer to the uC but I cannot send data the other direction.
I have tried 3 different methods to send data to the computer: _putc(), writeBlock(), and printf(). For all three methods, the first byte is sent back to the computer successfully but then the device gets stuck in an endless while loop on line 863 in USBDevice.cpp. This is the 'Wait for completion' portion of the USBDevice::write() function.
I do not feel that I have enough knowledge about USB interfaces to properly debug this driver.
I have published my test program here.
#include "mbed.h"
#include "USBSerial.h"
//Virtual serial port over USB
USBSerial serial;
DigitalOut thisLED(LED1);
char temp[1];
void receiveSerial()
{
while (serial.readable())
{
temp[0] = serial._getc();
serial._putc(temp[0]);
//serial.writeBlock((uint8_t *) temp,1);
//serial.printf(temp);
}
}
int main(void) {
serial.attach(&receiveSerial);
while(1)
{
thisLED = !thisLED;
wait(1);
}
}

Related

STM32 USB CDC some data lost with Win 10

I use USB device - STMicroelectronics development board. Use firmware, that support usb hardware. Its works as USB serial port.
On host PC (win10 21H1) i use serial terminal ("Tera Term") for get data from my device. I use standart windows usbserial driver.
My device sending data. If data flow is small (1-2-5 kByte/s) - all work fine. But if i speed up (flow about 100 kByte/s or more) - i see data loss.
I communicated with STMicroelectronics support. We checked issue. We saw USB communication with USB analyzer. We think, than it's windows side problem.
Also, I use a custom port read utility. Data integrity problem persists.
In received data i saw lost 64 or 128... multiple of 64 bytes. 64bytes - endpoint size in my case. See linked data for more information.
I create USB_test project in CubeMx. And add simple code for sending data to PC. Loop data sending if previous CDC transmit complete. Adding delays is unacceptable: firstly, it is not 100% elimination of losses; secondly, it has a bad effect on the bandwidth of the channel.
//in main() function
uint8_t is_transmit = 0;
HAL_Delay(5000);
uint8_t Buf[2048];
uint8_t k = 48;
// fill the array with printable characters
for(uint16_t i=0; i<sizeof(Buf)-2; i++){
if(k > 100) {
k = 48;
}
Buf[i] = k++;
}
// array - is a one string line
Buf[sizeof(Buf)-2] = '\r';
Buf[sizeof(Buf)-1] = '\n';
while (1)
{
if(is_transmit == 0){
is_transmit = 1;
//HAL_Delay(1); // add delay on 1 ms reduces the likelihood of losses by an order of magnitude
CDC_Transmit_FS(Buf, sizeof(Buf));
}
}
In CDC_TransmitCplt_FS() i flash is_transmit.
static int8_t CDC_TransmitCplt_FS(uint8_t *Buf, uint32_t *Len, uint8_t epnum)
{
---
extern uint8_t is_transmit;
is_transmit = 0;
---
return result;
}
Information from ST support communication and USB analyzer log file.
https://drive.google.com/drive/folders/1CvTPfaFGmcFxD4V5zTvsVE6U26DNwG2v?usp=sharing
How i fix this issue? I need data flow from device to host 500 kB/s or more.
Best regards, Andrey.

STM32 USB programming, jump to bootloader for DFU

I was having trouble on the STM32L462xx with setting the device up for flashing over USB without having access to the BOOT0 pin. Going off of the tutorial on the ST site didn't seem to accomplish the task. Has anyone successfully set the STM32L4 into bootloader mode from software?
https://stm32f4-discovery.net/2017/04/tutorial-jump-system-memory-software-stm32/
I was able to set the device into a mode which it can be programmed with STM32Cube Programmer or the DFU-util program using the following code. This is partly a signal boost for this programmers solution which went against the ST tutorial on their site saying how to put jump the device memory to bootloader for USB programming
https://github.com/markusgritsch/SilF4ware/blob/94bb679119a0b9879fedc62a5e22f40623433242/SilF4ware/drv_reset.c
void jump_to_bootloader(void)
{
__enable_irq();
HAL_RCC_DeInit();
HAL_DeInit();
SysTick->CTRL = SysTick->LOAD = SysTick->VAL = 0;
__HAL_SYSCFG_REMAPMEMORY_SYSTEMFLASH();
const uint32_t p = (*((uint32_t *) 0x1FFF0000));
__set_MSP( p );
void (*SysMemBootJump)(void);
SysMemBootJump = (void (*)(void)) (*((uint32_t *) 0x1FFF0004));
SysMemBootJump();
while( 1 ) {}
}

Receive infrared number from circuit playground express on arduino

On the circuit playground express theres a network function, where you can send a number through ir. Now I would like my arduino to read this number, and respond when it reads the number.
I've already connected a IR Receiver Diode to my arduino and used the following code with library:
#include <IRremote.h>
int RECV_PIN = 11;
IRrecv irrecv(RECV_PIN);
decode_results results;
void setup()
{
Serial.begin(9600);
irrecv.enableIRIn(); // Start the receiver
}
void loop()
{
if (irrecv.decode(&results))
{
Serial.println(results.value);
irrecv.resume(); // Receive the next value
}
}
The serial monitor, doesn't show the circuit playground number when I send it.
Does somebody now how to read the number send by the circuit playground express?

Connecting Arduino Ethernet Shield and reading data issue PROCESSING

i am new to this forum and the whole thing with Processing.
I have a specific question to ask and thanks a lot for your time and thoughts!
How can i connect my Arduino with Ethernet Shield, getting temperature values from a sensor so they can be seen to a processing script?
In a straight Arduino script, one gets the value, connects from the ethernet shield to a server and does what one likes. I have accomplished that.
In my case i want Arduino to just run the script of reading an analog input value from the sensor.
Is it possible?
I have made the serial connection work and read the values alright through the usb, but with ethernet shield? How can i get the value that arduino reads WITHOUT USB/Serial connection?
ps. i am using WAMP server etc, Windows 7
I am trying the UDP connection script example for both arduino and processing from http://arduino.cc/en/Tutorial/UDPSendReceiveString, but
1)i ain't sure if that's what i need,
2)i have excluded from firewall ports 6000, 8888 for my tests and have put the IP address of my Arduino at the Arduino script and "localhost" at the Processing script
THE CODE COPIED FOR BETTER USE HERE
/*
UDPSendReceive.pde:
This sketch receives UDP message strings, prints them to the serial port
and sends an "acknowledge" string back to the sender
A Processing sketch is included at the end of file that can be used to send
and received messages for testing with a computer.
created 21 Aug 2010
by Michael Margolis
This code is in the public domain.
*/
#include <SPI.h> // needed for Arduino versions later than 0018
#include <Ethernet.h>
#include <EthernetUdp.h> // UDP library from: bjoern#cs.stanford.edu 12/30/2008
// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = {
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192, 168, 1, 177);
unsigned int localPort = 8888; // local port to listen on
// buffers for receiving and sending data
char packetBuffer[UDP_TX_PACKET_MAX_SIZE]; //buffer to hold incoming packet,
char ReplyBuffer[] = "acknowledged"; // a string to send back
// An EthernetUDP instance to let us send and receive packets over UDP
EthernetUDP Udp;
void setup() {
// start the Ethernet and UDP:
Ethernet.begin(mac,ip);
Udp.begin(localPort);
Serial.begin(9600);
}
void loop() {
// if there's data available, read a packet
int packetSize = Udp.parsePacket();
if(packetSize)
{
Serial.print("Received packet of size ");
Serial.println(packetSize);
Serial.print("From ");
IPAddress remote = Udp.remoteIP();
for (int i =0; i < 4; i++)
{
Serial.print(remote[i], DEC);
if (i < 3)
{
Serial.print(".");
}
}
Serial.print(", port ");
Serial.println(Udp.remotePort());
// read the packet into packetBufffer
Udp.read(packetBuffer,UDP_TX_PACKET_MAX_SIZE);
Serial.println("Contents:");
Serial.println(packetBuffer);
// send a reply, to the IP address and port that sent us the packet we received
Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
Udp.write(ReplyBuffer);
Udp.endPacket();
}
delay(10);
}
/*
Processing sketch to run with this example
=====================================================
// Processing UDP example to send and receive string data from Arduino
// press any key to send the "Hello Arduino" message
*/
import hypermedia.net.*;
UDP udp; // define the UDP object
void setup() {
udp = new UDP( this, 6000 ); // create a new datagram connection on port 6000
//udp.log( true ); // <-- printout the connection activity
udp.listen( true ); // and wait for incoming message
}
void draw()
{
}
void keyPressed() {
String ip = "192.168.1.177"; // the remote IP address
int port = 8888; // the destination port
udp.send("Hello World", ip, port ); // the message to send
}
void receive( byte[] data ) { // <-- default handler
//void receive( byte[] data, String ip, int port ) { // <-- extended handler
for(int i=0; i < data.length; i++)
print(char(data[i]));
println();
}
Read those values into a file and use that file to send data to processing. http://py.processing.org/reference/createReader.html
Great scheme. Only one problem. It works perfectly on my system. I loaded my Arudino Uno R3 with your Arduino sketch and loaded the Processing sketch as well. Worked like a charm, first try. Didn't change anything on my Arduino, Windows system, Processing (2.0.3), network, etc.
Could be you have a Arduino board problem (unlikely) or an Ethernet shield problem (sadly, more likely). You could have a network problem (even more likely).
Try Wireshark. You will really just be guessing until you take a look at the Wireshark output. Note that Wireshark has filters. You will need them. Filter out all of the non-UDP traffic.

Arduino Ethernet UDPSendReceive example disables all pin outputs?

The UDPSendReceive.pde example bundled with the IDE works fine out of the box and displays the correct output on the serial monitor when it receives UDP packets, but seems to disable all the pinOutputs?
#include <SPI.h> // needed for Arduino versions later than 0018
#include <Ethernet.h>
#include <EthernetUdp.h> // UDP library from: bjoern#cs.stanford.edu 12/30/2008
// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = {
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192, 168, 1, 177);
unsigned int localPort = 8888; // local port to listen on
// buffers for receiving and sending data
char packetBuffer[UDP_TX_PACKET_MAX_SIZE]; //buffer to hold incoming packet,
char ReplyBuffer[] = "acknowledged"; // a string to send back
// An EthernetUDP instance to let us send and receive packets over UDP
EthernetUDP Udp;
void setup() {
// start the Ethernet and UDP:
Ethernet.begin(mac,ip);
Udp.begin(localPort);
Serial.begin(9600);
pinMode(12, OUTPUT);
}
void loop() {
// if there's data available, read a packet
int packetSize = Udp.parsePacket();
if(packetSize)
{
Serial.print("Received packet of size ");
Serial.println(packetSize);
Serial.print("From ");
IPAddress remote = Udp.remoteIP();
for (int i =0; i < 4; i++)
{
Serial.print(remote[i], DEC);
if (i < 3)
{
Serial.print(".");
}
}
Serial.print(", port ");
Serial.println(Udp.remotePort());
// read the packet into packetBufffer
Udp.read(packetBuffer,UDP_TX_PACKET_MAX_SIZE);
Serial.println("Contents:");
Serial.println(packetBuffer);
// send a reply, to the IP address and port that sent us the packet we received
Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
Udp.write(ReplyBuffer);
Udp.endPacket();
digitalWrite(12, HIGH); // set the LED on
}
delay(10);
}
Even just changing the loop to be
void loop() {
// if there's data available, read a packet
int packetSize = Udp.parsePacket();
if(packetSize)
{
digitalWrite(12, HIGH);
}
means nothing happens on my outputs (in this case an LED)
Update - Just noticed the SPI include in your code.The SPI library uses pin 12 (for MOSI) so its already reserved.
Previous:
Not sure which Ethernet shield/board you are using, but typically they use SPI protocol to communicate over pins 10-13. Pin 12 is used for MISO. (That's Master In, Slave Out - so its used by the Ethernet device (Slave) as output to the Aurduino's in (Master).
So pins 1 thru 9 should be fine to use as an LED indicator.
The information provided by JDH is correct. Ethernet/SPI uses several pins to communicate with the Ethernet shield. The rest are free for your use. See http://arduino.cc/en/Reference/SPI for some details. The Connections section shows what pins are used by several common Arduino boards. For the Uno and Duemilanove it's pins 10-13.