Reputation: 167
I am writing code to communicate with an stm32 device (stm32l412kb) using the serial port and the MCU's UART. The aim of the code is that the MCU will send an instruction/request byte to the host computer. The host computer will act on this instruction. For example, the first instruction sent is the ACK (acknowledge) byte = 0x79. When the computer receives this, an ACK is sent back.
This first byte works perfectly. However, the second byte meant to send is the VERSION_REQUEST byte = 0x01. While the stm32 code loops through just waiting for a response, the stm32 keeps sending this byte and this byte only. The problem is on the host side, the computer -no matter the delay- is reading a pattern of bytes: 1B, 08, D4, 9F, 79 (acted on as = ACK). The computer will loop through reading these, with no appearance of 01.
As there is code on both the stm32 and host side, I'm not sure where the problem lies. The code (macros and main()) for the host side is:
#include <windows.h>
#include <cstdio>
#include <stdint.h>
HANDLE hSerial;
/*Macros*/
#define ACK 0x79 //Acknowledge byte used in UART communication
#define NACK 0x1F //Not acknowledged byte used in UART communication
//Manually change the version number of the latest update
#define VERSION_NUMBER 0x0001
/*Instruction Macros*/
#define VERSION_REQUEST 0x01
#define DOWNLOAD_REQUEST 0x02
/*Function Prototypes*/
char receiveInstruction();
int sendACK();
int sendVersionNumber();
void initialiseSerialPort();
void readData(char Rx_Buffer[], int numberOfBytes);
void writeData(char Tx_Buffer[], int numberOfBytes);
int main(){
/*Error Handling*/
char lastError[1024];
initialiseSerialPort();
while (1) {
uint8_t instruction = 0;
printf("Searching for incoming instruction...\n");
//This odd while requirements were to try and enclose the problem
//Wait until familiar instruction is read
while ((instruction != ACK) && (instruction != VERSION_REQUEST)) {
instruction = receiveInstruction();
printf("Received Instruction: %X \n", instruction);
}
printf("Received Instruction: %X \n", instruction);
if (instruction == ACK) {
sendACK();
}
else if (instruction == VERSION_REQUEST) {
sendVersionNumber();
}
else {
printf("Unknown request received.\n");
}
Sleep(100);
}
/*Close Down*/
CloseHandle(hSerial); //Without closing - may not be able to access the port until reboot
FormatMessage(
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
lastError,
1024,
NULL);
return 0 ;
}
The readData and readInstruction functions are:
void readData(char Rx_Buffer[], int numberOfBytes)
{
/*Clear Buffer*/
for (int i = 0; i < numberOfBytes; i++) {
Rx_Buffer[i] = 0 ;
}
DWORD dwBytesRead = 0;
/*Read Bytes*/
if (!ReadFile(hSerial, Rx_Buffer, numberOfBytes, &dwBytesRead, NULL)) {
//error occurred. Report to user.
}
}
char receiveInstruction()
{
//Initialise reading buffer, this decides which mode of transmission to use.
char Rx_Buffer[1];
Rx_Buffer[0] = 0;
//While the buffer is empty, read for an instruction
while (Rx_Buffer[0] == 0) {
readData(Rx_Buffer, 1);
Sleep(100);
}
return Rx_Buffer[0];
}
If code is required for the stm32 side I can provide that, but it looks to be just looping through sending the request for the version number (which is not received by the host).
Sorry this is quite a vague question, I really don't know where to look. If any further details are required, I can provide them.
Many thanks as always for the time given for the help, it is much appreciated.
Upvotes: 2
Views: 802
Reputation: 2326
0x01
, 0x55
, 0xFF
Note what you read from the STM.
Note what you read from the host
If you are sure you are always sending one byte from one side and you get different reading from the other side (like your pattern), it very looks like a synchronization issue. Meaning : baudrate, not the parity or stop bit because in that case the pattern would be always the same like 0x01 converted in a 0x10.
But it will be much easier with a logic analyzer :)
I could also be noise. When you look at your pattern bytes, it's very different from 0x01:
0x01 : 0b00000001
0x1B : 0b00011011
0x08 : 0b00001000
0xD4 : 0b11010100
0x9F : 0b10011111
0x79 : 0b01111001
Upvotes: 2