Related
I am a beginner in ESP32-S2 programming and I find it hard to link all the data and produce one output in the form of queue on serial monitor. I am sorry for the imperfect coding skills as I am still learning and doing my best but can someone please help me out and identify how can I correct this code.
Thank You!
#include <WiFi.h>
#include "time.h"
#include "sntp.h"
#include <esp_task_wdt.h>
#include <esp_sleep.h>
#include <queue.h>
#include <Arduino_HTS221.h>
#define WDT_TIMEOUT 200
#define Freertos/queue.h
int i = 0;
int last = millis();
int h;
int temp;
int chk = 0;
u_int32_t Freq = 0;
hw_timer_t *timer0 = NULL;
hw_timer_t *timer1 = NULL;
portMUX_TYPE timerMux0 = portMUX_INITIALIZER_UNLOCKED;
portMUX_TYPE timerMux1 = portMUX_INITIALIZER_UNLOCKED;
QueueHandle_t queue;
const char* ssid = "V2027";
const char* password = "oblivious101";
const char* ntpServer1 = "th.pool.ntp.org";
const long gmtOffset_sec = 3600*7;
const int daylightOffset_sec = 0;
const int wakeup_time_sec = 10;
const int ledTimeout = 10000;
const int SCLpin = 40;
const int SDApin = 41;
const byte button=0;
int counter = 1;
static QueueHandle_t xQueue1 = NULL, xQueue2 = NULL, xQueue3 = NULL, xQueue4 = NULL;
static QueueSetHandle_t xQueueSet = NULL;
TaskHandle_t TaskHandle_1;
TaskHandle_t TaskHandle_2;
TaskHandle_t TaskHandle_3;
TaskHandle_t TaskHandle_4;
void first_task (void *parameter)
{
while(1)
{
printLocalTime();
vTaskDelay(10000/portTICK_PERIOD_MS);
//Serial.println("Real Time Clock (RTC) : ");
const char * const pcMessage = "Real Time Clock (RTC) : ";
xQueueSend( xQueue1, &pcMessage, 0 );
}
}
void second_task (void *parameter)
{
for(;;)
{
configTime(gmtOffset_sec , daylightOffset_sec, ntpServer1);
printLocalTime();
vTaskDelay(20000/ portTICK_PERIOD_MS);
//Serial.println("Network Time Protocol (NTP) : ");
const char * const pcMessage = "Network Time Protocol (NTP) : ";
xQueueSend( xQueue2, &pcMessage, 0 );
}
}
void third_task (void *parameter)
{
for(;;)
{
if (millis() - last >= 5000 && i < 10 ) {
Serial.println("Watchdog Timer Reset Initiated");
esp_task_wdt_reset();
last = millis();
i++;
if (i == 10) {
esp_err_t task_wdt_delete(NULL);
//Serial.println("Watchdog Timer Disabled");
const char * const pcMessage = "Watchdog Timer Disabled";
xQueueSend( xQueue3, &pcMessage, 0 );
delay (40000);
}
}
}
}
void printLocalTime()
{
struct tm timeinfo;
if(!getLocalTime(&timeinfo)){
Serial.println("Failed to Configure Time");
return;
}
Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S");
h = timeinfo.tm_min;
if (chk == 0){
temp = h;
chk = 1;
}
if (h > (temp+1))
{
Serial.println("Deep Sleep Mode Initiated");
esp_sleep_enable_timer_wakeup(wakeup_time_sec * 1000000);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
esp_deep_sleep_start();
chk = 0;
}
delay(1000);
}
void fourth_task (void *parameter)
{
for(;;)
{
float temperature = HTS.readTemperature();
//Serial.println("Temperature: "+String(temperature)+" °C");
String pcMessage = "Temperature: "+String(temperature)+" °C";
xQueueSend( xQueue4, &pcMessage, 0 );
delay(3000);
}
}
void IRAM_ATTR turnOffLed() {
portENTER_CRITICAL_ISR(&timerMux1);
Serial.println("Interrupt Routin Switch LED Turned Off");
digitalWrite(LED_BUILTIN, LOW);
portEXIT_CRITICAL_ISR(&timerMux1);
}
void IRAM_ATTR turnOnLed(){
if (digitalRead(button)==0){
digitalWrite(LED_BUILTIN, HIGH);
Serial.println("Interrupt Routine Switch Activated");
timerWrite(timer1, 0);
}
}
void vReceiverTask( void *pvParameters )
{
QueueHandle_t xQueueThatContainsData;
char *pcReceivedString;
for( ;; )
{
xQueueThatContainsData = ( QueueHandle_t )
xQueueSelectFromSet( xQueueSet,portMAX_DELAY );
xQueueReceive( xQueueThatContainsData, &pcReceivedString, 0 );
Serial.println(pcReceivedString);
}
delay(1000);
}
void setup()
{
Serial.begin(115200);
Serial.printf("Synching Connection with %s ", ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println(" Connected");
Freq = getCpuFrequencyMhz();
Serial.print("CPU Frequency = ");
Serial.print(Freq);
Serial.println("MHz");
setCpuFrequencyMhz(80);
Freq = getCpuFrequencyMhz();
Serial.print("CPU Frequency = ");
Serial.print(Freq);
Serial.println("MHz");
Serial.println("CPU Frequency reduced from 240 MHz to 80 MHz");
Serial.println("Watchdog Timer Configuration Initiated....");
esp_task_wdt_init(WDT_TIMEOUT, false);
esp_task_wdt_add(NULL);
queue = xQueueCreate(3, sizeof(float));
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, LOW);
pinMode(button, INPUT);
attachInterrupt(digitalPinToInterrupt(button), turnOnLed, CHANGE);
xTaskCreate(first_task,"sec",10000,NULL,1,NULL);
xTaskCreate(second_task,"min",10000,NULL,2,NULL);
xTaskCreate(third_task,"WDT",10000,NULL,1,NULL);
xTaskCreate(fourth_task,"readTemp",10000,NULL,2,NULL);
xQueue1 = xQueueCreate( 1, sizeof( char * ) );
xQueue2 = xQueueCreate( 1, sizeof( char * ) );
xQueue3 = xQueueCreate( 1, sizeof( char * ) );
xQueue4 = xQueueCreate( 1, sizeof( char * ) );
xQueueSet = xQueueCreateSet( 1 * 4 );
xQueueAddToSet( xQueue1, xQueueSet );
xQueueAddToSet( xQueue2, xQueueSet );
xQueueAddToSet( xQueue3, xQueueSet );
xQueueAddToSet( xQueue4, xQueueSet );
xTaskCreate(vReceiverTask, "Receiver", 100, NULL, 4, NULL );
vTaskStartScheduler();
delay(500);
}
void loop()
{
Serial.println("Inserting Data in Queue");
delay(7000);
}
I am implementing a MQTT communication. I want to send CAN frames over MQTT through a graphical interfaces (realized in python). I am able to send messages from the GUI to one topic and I am able to see messages arrived on the same topic (using paho library) when I use the board. The function is below and the topic is diagnostic_request/topic:
void onMessageArrived
(
const char* topic,
const uint8_t* payload,
size_t payloadLen,
void* context
)
{
//LE_FATAL("The publisher received a message!");
//GIMP
char payloadStr[payloadLen + 1];
memcpy(payloadStr, payload, payloadLen);
payloadStr[payloadLen] = '\0';
LE_INFO("Received message! topic: \"%s\", payload: \"%s\"", topic, payloadStr);
//GIMP principio di conversione
if (strcmp(subscribeTopic, topic)==0)
LE_INFO("Sei sul topic di richiesta diagnostica!");
can_send();
}
At this point I have a difficulty. My can_send function (that works!) is:
int can_send(void)
{
const char* subscribeTopic = "diagnostic_request/topic";
LE_FATAL_IF(
mqtt_Subscribe(MQTTSession, subscribeTopic, MQTT_QOS0_TRANSMIT_ONCE) != LE_OK,
"failed to subscribe to %s",
subscribeTopic);
LE_INFO("Subscribed to topic (%s)", subscribeTopic);
int nbytesWrite;
// USE SEND STANDARD FRAME
frameWrite.can_id = 0x750; //codice identificativo di una richiesta diagnostica per centralina simulata
frameWrite.can_id &= CAN_SFF_MASK;
frameWrite.can_dlc = 8;
//strcpy((char *)frameWrite.data, "MGATE");
frameWrite.data[0] = 0x03;
frameWrite.data[1] = 0x22;
frameWrite.data[2] = 0xF1;
frameWrite.data[3] = 0x89;
frameWrite.data[4] = 0x00;
frameWrite.data[5] = 0x00;
frameWrite.data[6] = 0x00;
frameWrite.data[7] = 0x00;
if ((nbytesWrite = write(sdw, &frameWrite, sizeof(frameWrite))) != sizeof(frameWrite))
{
canwrite = false;
LE_INFO ("Writing error, nbytesWrite = %d", nbytesWrite);
return SOCK_WRITING_ERROR;
}
canwrite = true;
return 0;
}
So I have to call can_send in the onMessageArrived function when is statement is ok. I am able to see when I send a publish on diagnostic_request/topic. The only problem is to send the payloadStr value to the can_send function and unpackage it in the frameWrite.data[]. Can someone help me to understand how to modify the can_send function in order that the values
frameWrite.data[0] = 0x03;
frameWrite.data[1] = 0x22;
frameWrite.data[2] = 0xF1;
frameWrite.data[3] = 0x89;
frameWrite.data[4] = 0x00;
frameWrite.data[5] = 0x00;
frameWrite.data[6] = 0x00;
frameWrite.data[7] = 0x00;
are values that I send through mqtt in the payloadStr? I send a string of 8 bytes but I can't unpackage it.
Any help will be appreciated
Regards
Taking the approach of "write the test first".....
int convertNybble (char const hex)
{
if (hex >= '0' && hex <= '9')
{
return hex - '0';
}
else if (hex >= 'a' && hex <= 'f')
{
return 10 + (hex - 'a');
}
else if (hex >= 'A' && hex <= 'F')
{
return 10 + (hex - 'A');
}
return -1; // invalid hex character
}
#define ERR_NOT_EVEN_NUMBER_OF_DIGITS -1
#define ERR_STRING_TOO_LONG -2
#define ERR_INVALID_CHAR -3
int preparePayload(char const* hexString, unsigned char* canBuffer, size_t const bufLen)
{
size_t hexLen = strlen(hexString);
if (0 != (hexLen % 2))
{
// Expect an even number of digits.
return ERR_NOT_EVEN_NUMBER_OF_DIGITS;
}
size_t payloadLen = hexLen / 2;
// buffer will contain payload-length, followed by payload data.
// so payloadLen+1 must be able to fit into bufLen - fail if payloadLen+1 > bufLen, which is the same as payloadLen >= bufLen
if (payloadLen >= bufLen)
{
// will not be able to fit the decoded string into the payload buffer
return ERR_STRING_TOO_LONG;
}
unsigned char* bufEnd = canBuffer;
bufEnd += bufLen;
*canBuffer++ = (unsigned char)payloadLen;
while (payloadLen > 0)
{
payloadLen--;
int hexDigit[2];
hexDigit[0] = convertNybble(*hexString++);
hexDigit[1] = convertNybble(*hexString++);
if ((hexDigit[0] < 0) || (hexDigit[1] < 0))
{
return ERR_INVALID_CHAR;
}
*canBuffer++ = (hexDigit[0] << 4) | hexDigit[1];
}
// fill any leftovers with zero
while (canBuffer < bufEnd)
{
*canBuffer++ = 0;
}
return (0);
}
int performTests()
{
char const* testStr[5] =
{
"12345",
"0123456789ABCDEF",
"#ABC",
"0AF9",
"0123456789ABCD"
};
#define MARKER 0xFF
#define PAYLOAD_LEN 8
unsigned char payload[PAYLOAD_LEN+1];
payload[PAYLOAD_LEN] = MARKER;
int decodeResult = preparePayload(testStr[0], payload, PAYLOAD_LEN);
if (ERR_NOT_EVEN_NUMBER_OF_DIGITS != decodeResult) { return -1; } //not expected result
decodeResult = preparePayload(testStr[1], payload, PAYLOAD_LEN);
if (ERR_STRING_TOO_LONG != decodeResult) { return -1; }
decodeResult = preparePayload(testStr[2], payload, PAYLOAD_LEN);
if (ERR_INVALID_CHAR != decodeResult) { return -1; }
// here we are checking the character decoding
decodeResult = preparePayload(testStr[3], payload, PAYLOAD_LEN);
if (0 != decodeResult) { return -1; }
if (payload[0] != 2) { return -1; }
if (payload[1] != 0x0A) { return -1; }
if (payload[2] != 0xF9) { return -1; }
if (payload[3] != 0) { return -1; }
if (payload[7] != 0) { return -1; }
// payload contains - 02 0a f9 00 00 00 00 00 00
// here we are checking the limit of the payload capacity
decodeResult = preparePayload(testStr[4], payload, PAYLOAD_LEN);
if (0 != decodeResult) { return -1; }
// payload contains - 07 01 23 45 67 89 ab cd
// check we haven't overrun the buffer
if (payload[8] != MARKER) { return -1; }
// all tests pass
return 0;
}
int main()
{
int testResult = performTests();
return testResult;
}
You can then embody the decoder as follows:
convertNybble, preparePayload etc as above....
int canbusSend(unsigned char const* canbusPayload)
{
//etc
// - copy payloadBytes to frameWrite.data....
//etc
}
void onMessageArrived
(
const char* topic,
const uint8_t* mqttPayload,
size_t payloadLen,
void* context
)
{
#define CANBUS_PAYLOAD_BUFFER_LEN 8
unsigned char canbusPayload[CANBUS_PAYLOAD_BUFFER_LEN];
int decodeResult = preparePayload((char const*)mqttPayload, canbusPayload, CANBUS_PAYLOAD_BUFFER_LEN);
if (0 == decodeResult)
{
int canbusSendResult = canbusSend(canbusPayload);
// TODO : report error if failed
}
else
{
//TODO : report error
}
}
I have some problems with transmiting and receiving using usart. First informations that I want transmit are writen to circle buffer. Then indormations are send but some informations are lost.
Variables
enum {
BUF_SIZE = 100
};
char BUF_T[BUF_SIZE], BUF_R[BUF_SIZE];
uint8_t R_EMPTY = 0, R_BUSY = 0, T_EMPTY = 0, T_BUSY = 0;
Transmiting
void Send(void) {
uint8_t index = T_EMPTY;
for (int i = 0; i < 10; i++) {
BUF_T[index] = i+'0';
index++;
if (index >= BUF_SIZE) {
index = 0;
}
}
__disable_irq();
if (T_BUSY == T_EMPTY
&& __HAL_UART_GET_FLAG(&huart2,UART_FLAG_TXE) == SET) {
T_EMPTY = index;
T_BUSY++;
uint8_t tmp = BUF_T[T_BUSY];
if (T_BUSY >= BUF_SIZE) {
T_BUSY = 0;
}
HAL_UART_Transmit_IT(&huart2, (uint8_t*) &tmp, 1);
} else {
T_EMPTY = index;
}
__enable_irq();
}
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) {
//if (huart->Instance == USART2) {
if (T_BUSY != T_EMPTY) {
__disable_irq();
T_BUSY++;
uint8_t tmp = BUF_T[T_BUSY];
if (T_BUSY >= BUF_SIZE) {
T_BUSY = 0;
}
HAL_UART_Transmit_IT(&huart2, (uint8_t*) &tmp, 1);
__enable_irq();
}else {
Send();
}
//}
}
Screen from hterm
On picture can be seen that from time to time one char is lost. I don't understant why?
Regarding receiving can somebody tell mi if it OK?
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
//if (huart->Instance == USART2) {
uint8_t tmp = BUF_R[R_EMPTY];
R_EMPTY++;
if (R_EMPTY >= BUF_SIZE) {
R_EMPTY = 0;
}
HAL_UART_Receive_IT(&huart2, (uint8_t*) &tmp, 1);
//}
}
I'm very novice at C but I'm trying to learn. I'm trying right now to make a program read from a csv file and take only it's integers from it, and write those out to a seperate .txt file. I'm not seeing why it will create a file, but why it won't write anything to it. Here's the code. in the methods 'getTokensFromLineforOutput' and 'writeOutput' is where I try to do my writing, everything else works fine, and if you were to take away those two methods and run it as just a program reading from a csv file it operates as intended. But writing is where I'm running into. IDK if i'm able to attach a document so for reference here's the csv file I made from notepad:
3,1, joe
45,0, sandy
5,1, mary
12,0, eugene
11,0, alex
#include <stdio.h>
#include <stdbool.h>
#define NAMESIZE 30
#define ARRAYSIZE 100
#define ROWLENGTH 300
#define TOKENLENGTH 10
typedef struct {
int nWeeks;
bool isCensored;
char identifier[NAMESIZE];
}SurvivalPatientData;
bool giveMeALine(FILE * source, char * dest)
{
bool status = false;
char * where = dest;
char ch;
int ch_ctr = 0;
while(((ch = getc(source)) != EOF) && (ch != '\n') && (ch != '\r'))
{
*where = ch;
where++;
ch_ctr++;
status = true;
}
for (int i=ch_ctr; i<ROWLENGTH && status ;i++)
{
*where= '\0'; /*null*/
where++;
}
printf("giveMeALine returning status = %d\n",status);
return status;
}
bool getTokensFromLineforOutput(char *theLine, SurvivalPatientData *sdp) {
bool status = false;
FILE * file = fopen("C:/Users/Default/Desktop/CCSU/CCSU SPRING 18/CS_3//output.txt", "w");
char * inTheLine = theLine;
char theToken[TOKENLENGTH];
char * inToken = theToken;
char ch = '\0';
for (int i = 0; i<TOKENLENGTH; i++)
{
theToken[i]='\0'; /*null char*/
}
int value = 0;
while((ch=*inTheLine)!=',')
{
value *= 10;
value += ch - '0';
inTheLine++;
}
sdp->nWeeks=value;
fprintf(file, "%d\n",sdp->nWeeks);
inTheLine++;
for (int i = 0; i<TOKENLENGTH; i++)
{
theToken[i]='\0'; /*null char*/
}
inToken = theToken;
inTheLine++;
while((ch=*inTheLine)!=',')
{
*inToken = ch;
inToken++;
inTheLine++;
}
inToken--;
if (*inToken == '0')
{
sdp->isCensored=false;
}
else
{
sdp->isCensored= true;
}
fprintf(file, "%d\n",sdp->isCensored);
inTheLine++;
for (int i = 0; i<TOKENLENGTH; i++)
{
theToken[i]='\0'; /*null char*/
}
inToken = sdp->identifier;
while((ch=*inTheLine)!=',' && ch!= EOF)
{
*inToken = ch;
inToken++;
inTheLine++;
}
status=true;
return status;
}
bool getTokensFromLine(char * theLine,
SurvivalPatientData * sdp);
bool getTokensFromLine(char *theLine, SurvivalPatientData *sdp) {
bool status = false;
char * inTheLine = theLine;
char theToken[TOKENLENGTH];
char * inToken = theToken;
char ch = '\0';
for (int i = 0; i<TOKENLENGTH; i++)
{
theToken[i]='\0'; /*null char*/
}
int value = 0;
while((ch=*inTheLine)!=',')
{
value *= 10;
value += ch - '0';
inTheLine++;
}
sdp->nWeeks=value;
printf("Weeks is %d\n",sdp->nWeeks);
inTheLine++;
for (int i = 0; i<TOKENLENGTH; i++)
{
theToken[i]='\0'; /*null char*/
}
inToken = theToken;
inTheLine++;
while((ch=*inTheLine)!=',')
{
*inToken = ch;
inToken++;
inTheLine++;
}
inToken--;
if (*inToken == '0')
{
sdp->isCensored=false;
}
else
{
sdp->isCensored= true;
}
printf("isCensored is %d\n",sdp->isCensored);
inTheLine++;
for (int i = 0; i<TOKENLENGTH; i++)
{
theToken[i]='\0'; /*null char*/
}
inToken = sdp->identifier;
while((ch=*inTheLine)!=',' && ch!= EOF)
{
*inToken = ch;
inToken++;
inTheLine++;
}
printf("The identifier is %s\n",sdp->identifier);
status=true;
return status;
}
bool writeOutput(FILE * source, SurvivalPatientData * gotIt){
bool status = false;
bool write = false;
for (int j = 0; j<ARRAYSIZE; j++){
for (int i = 0; i<NAMESIZE; i++){
(gotIt[j].identifier)[i]='\x20';
}
gotIt[j].nWeeks = 0;
gotIt[j].isCensored = false;
}
int nrows = 0;
int row = 0;
char readALine[ROWLENGTH];
bool lines2Read = true;
bool gotTokens = false;
while (lines2Read){
bool gotALine = giveMeALine(source, readALine);
if(!gotALine){
lines2Read = false;
} else {
gotTokens = getTokensFromLineforOutput(readALine, &(gotIt[row]));
if(gotTokens){
status = true;
row++;
nrows++;
}
}
}
return status;
}
bool getInputFancy(FILE * source, SurvivalPatientData * gotIt){
bool status = false;
for (int j = 0; j<ARRAYSIZE; j++){
for (int i = 0; i<NAMESIZE; i++){
(gotIt[j].identifier)[i]='\x20';
}
gotIt[j].nWeeks = 0;
gotIt[j].isCensored = false;
}
int nrows = 0;
int row = 0;
char readALine[ROWLENGTH];
bool lines2Read = true;
bool gotTokens = false;
while (lines2Read){
bool gotALine = giveMeALine(source, readALine);
if(!gotALine){
lines2Read = false;
} else {
puts(readALine);
gotTokens = getTokensFromLine(readALine, &(gotIt[row]));
if(gotTokens){
printf("found %d row\n", row);
status = true;
row++;
nrows++;
}
}
}
printf("found %d rows\n", nrows);
return status;
}
int main() {
printf("Hello, World!\n");
bool readIt = false;
bool write = false;
SurvivalPatientData gotIt[ARRAYSIZE];
FILE * whereInputIs = fopen("C:/Users/Default/Desktop/CCSU/CCSU SPRING 18/CS_3//retake.csv", "r");
FILE * whereOutputIs = fopen("C:/Users/Default/Desktop/CCSU/CCSU SPRING 18/CS_3//output.txt", "w");
if (whereInputIs == NULL){
perror("can't open file source/doesn't exist");
}
puts("Found the file");
readIt = getInputFancy(whereInputIs, gotIt);
write = writeOutput(whereOutputIs, gotIt);
if (!readIt)
{
perror("could not read that file");
}
puts("!!!read the file!!!");
if (fclose ( whereInputIs) != 0) {
perror("trouble trying to close");
}
puts("!!!closed the file!!!");
return 0;
}
(If I could comment this I would)
Try putting parentheses around your de referencing * and variable..
(ch = (*inThLine))
I am on stm32f103c8t6 with STDP-Lib, using stm32's usb library for virtual com port and wanna to talk with the µC via termios-Pc-program. The termios program can read the data the chip is sending via USB, but when I wanna answer, the chip is not reacting on the data I send. What am I doing wrong when sending?
The termios-program:
#include <stdio.h>
#include <unistd.h>
#include <termios.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <sys/stat.h>
typedef union {
int num;
char part[2];
} _16to8;
static void sendData(int tty, unsigned char c) {
write(tty, &c, 1);
}
static unsigned char readData(int tty) {
unsigned char c;
while(read(tty, &c, 1) <= 0);
return c;
}
static unsigned char* readALotOfData(int tty, int len) {
unsigned char* c = NULL;
c = calloc(len, sizeof(unsigned char));
for(int i = 0; i < len; i++) {
c[i] = readData(tty);
}
return c;
}
static void sendCmd(int tty, char* c, size_t len) {
unsigned char* a = NULL;
int i = 0;
a = calloc(len, sizeof(unsigned char));
memcpy(a, c, len);
for(; i < len; i++) {
sendData(tty, a[i]);
}
free(a);
a = NULL;
}
int main(int argc, char** argv) {
struct termios tio;
int tty_fd;
FILE* fd;
struct stat st;
unsigned char c;
unsigned char* buf = NULL;
buf = calloc(4096, sizeof(unsigned char));
memset(&tio, 0, sizeof(tio));
tio.c_cflag = CS8;
tty_fd = open(argv[1], O_RDWR | O_NONBLOCK);
if(tty_fd == -1) {
printf("failed to open port\n");
return 1;
}
char mode;
if(!strcmp(argv[2], "flash")) {
mode = 1;
fd = fopen(argv[3], "r");
if(fd == NULL) {
printf("failed to open file\n");
return 1;
}
} else if(!strcmp(argv[2], "erase")) {
mode = 0;
} else {
printf("unknown operation mode\n");
return 1;
}
cfsetospeed(&tio, B115200);
cfsetispeed(&tio, B115200);
tcsetattr(tty_fd, TCSANOW, &tio);
unsigned char* id = readALotOfData(tty_fd, 20);
printf("%s\n", id);
if(strstr((const char*)id, "1234AABBCC1234")) {
sendCmd(tty_fd, "4321CCBBAA4321", 14);
printf("id verified\n");
} else {
printf("Could not identify device\n");
return 1;
}
if(mode) {
printf("going to flash the device\n");
sendCmd(tty_fd, "\xF1\xA5", 2);
stat(argv[3], &st);
int siz = st.st_size;
char sizR[2] = "\0";
sizR[1] = (unsigned char)(siz & 0xFF);
sizR[0] = (unsigned char)(siz >> 8);
_16to8 num = {0};
num.part[0] = sizR[0];
num.part[1] = sizR[1];
sendCmd(tty_fd, (char*)&num.num, 2);
char buffer[2] = {0};
int i = 0;
while(fread(&buffer, 1, 4, fd)) {
// sendCmd(tty_fd, buffer, 4);
// printf("%s\n", readALotOfData(tty_fd, 5));
}
} else {
printf("going to erase the device's memory\n");
sendCmd(tty_fd, (char*)0xE2A5, 2);
}
close(tty_fd);
return 0;
}
µCProgram:
#include "stm32f10x_conf.h"
#include "main.h"
void eraseFlashPage(uint8_t page) {
uint32_t addr = FLASH_ADDR + 0x400 * page;
FLASH_Unlock();
FLASH_ClearFlag(FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR | FLASH_FLAG_EOP);
FLASH_ErasePage(addr);
FLASH_Lock();
}
void writeFlashAddr(uint8_t page, uint16_t offset, uint32_t data) {
uint32_t addr = FLASH_ADDR + 0x400 * page + offset;
FLASH_Unlock();
FLASH_ClearFlag(FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR | FLASH_FLAG_EOP);
FLASH_ProgramWord(addr, (uint32_t)data);
FLASH_Lock();
}
uint32_t readFlashAddr(uint8_t page) {
uint32_t addr = FLASH_ADDR + 0x400 * page;
return *(uint32_t*)addr;
}
void TIM2_IRQHandler() {
static int count = 0;
if(TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) {
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
if(mode) {
if(count == 2) {
count = 0;
GPIO_ToggleBits(GPIOA, GPIO_Pin_15);
}
count++;
} else {
GPIO_ToggleBits(GPIOA, GPIO_Pin_15);
}
}
}
int main() {
Set_System();
Set_USBClock();
USB_Interrupts_Config();
USB_Init();
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
GPIO_InitTypeDef gpioStruct;
gpioStruct.GPIO_Pin = GPIO_Pin_15;
gpioStruct.GPIO_Mode = GPIO_Mode_Out_PP;
gpioStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &gpioStruct);
GPIO_WriteBit(GPIOA, GPIO_Pin_15, Bit_RESET);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); // 200Hz -> 8Hz
TIM_TimeBaseInitTypeDef timStruct;
timStruct.TIM_Prescaler = 60000;
timStruct.TIM_CounterMode = TIM_CounterMode_Up;
timStruct.TIM_Period = 50; // ISR at 0.125s
timStruct.TIM_ClockDivision = TIM_CKD_DIV4;
timStruct.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM2, &timStruct);
TIM_Cmd(TIM2, ENABLE);
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
NVIC_InitTypeDef nvicStruct;
nvicStruct.NVIC_IRQChannel = TIM2_IRQn;
nvicStruct.NVIC_IRQChannelPreemptionPriority = 0;
nvicStruct.NVIC_IRQChannelSubPriority = 1;
nvicStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&nvicStruct);
_delay_ms(500);
while(1) {
mode = 0;
Receive_length = 0;
char bootID[64];
for(volatile uint32_t cnt = 0; cnt < 4800 * 5000 / 4 / 25; cnt++) {
_printf("1234AABBCC1234");
CDC_Receive_DATA();
if(Receive_length >= 14) {
_gets((char*)&bootID, 14);
if(!memcmp(bootID, "4321CCBBAA4321", 14)) {
mode = 1;
break;
}
Receive_length = 0;
}
}
if(mode) {
uint32_t opt = 0;
_printf("operating mode?\n"); //debug
_gets((char*)&opt, 2);
if(opt == 0xF1A5) {
uint32_t len = 0;
uint32_t data = 0;
uint16_t i = 0;
_gets((char*)&len, 2);
_printf("writing %d/%d bytes starting at 0x%x\n", len, (117 - START_PAGE) * 1024, FLASH_ADDR); // debug
if(len < (117 - START_PAGE) * 1024) { // 117 or 64?
_printf("start writing to flash\n"); //debug
for(i = 0; i <= len / 1024; i++) {
eraseFlashPage(i);
_printf("erasing page %d\n", i); //debug
}
for(i = 0; i < len; i += 4) {
uint8_t page = i / 1024;
_printf("i:%d page:%d offset:%d\n", i, page, i - page * 1024); // debug
_gets((char*)&data, 4);
writeFlashAddr(page, i - page * 1024, data);
_printf("Page %d and 0x%x\n", page, FLASH_ADDR + 0x400 * page + i - page * 1024); // debug
}
_printf("done\n"); //debug
uint32_t sp = *(uint32_t*) FLASH_ADDR;
if((sp & 0x2FFF0000) == 0x20000000) {
TIM_Cmd(TIM2, DISABLE);
GPIO_WriteBit(GPIOA, GPIO_Pin_15, Bit_RESET);
NVIC->ICER[0] = 0xFFFFFFFF;
NVIC->ICER[1] = 0xFFFFFFFF;
NVIC->ICPR[0] = 0xFFFFFFFF;
NVIC->ICPR[1] = 0xFFFFFFFF;
PowerOff();
pFunction jmpUser;
uint32_t jmpAddr = *(__IO uint32_t*)(FLASH_ADDR + 4);
jmpUser = (pFunction)jmpAddr;
__set_MSP(*(__IO uint32_t*)FLASH_ADDR);
jmpUser();
}
} else {
_printf("not enought flash space available\n"); //debug
}
} else if(opt == 0xE2A5) {
for(int i = 0; i < (117 - START_PAGE); i++) {
eraseFlashPage(i);
_printf("erasing page %d\n", i); //debug
}
}
} else {
uint32_t sp = *(uint32_t*) FLASH_ADDR;
if((sp & 0x2FFF0000) == 0x20000000) {
TIM_Cmd(TIM2, DISABLE);
GPIO_WriteBit(GPIOA, GPIO_Pin_15, Bit_RESET);
NVIC->ICER[0] = 0xFFFFFFFF;
NVIC->ICER[1] = 0xFFFFFFFF;
NVIC->ICPR[0] = 0xFFFFFFFF;
NVIC->ICPR[1] = 0xFFFFFFFF;
PowerOff();
pFunction jmpUser;
uint32_t jmpAddr = *(__IO uint32_t*)(FLASH_ADDR + 4);
jmpUser = (pFunction)jmpAddr;
__set_MSP(*(__IO uint32_t*)FLASH_ADDR);
jmpUser();
}
}
}
}
I want to send the identification string and then enter the operations.... A friend of me got a working program with serialport-lib usage, but I wanna use termios...
Anyone an idea why the controller is not reacting on the sent data?