add command reset, fix some troubles

This commit is contained in:
Edward Emelianov 2023-09-12 23:13:50 +03:00
parent e959c7dfe2
commit 94f87db5c5
9 changed files with 64 additions and 34 deletions

View File

@ -113,6 +113,8 @@ void can_messages_proc(){
SEND("DUMMY"); SEND("DUMMY");
bufputchar('0' + (data[1]==CMD_DUMMY0 ? 0 : 1)); bufputchar('0' + (data[1]==CMD_DUMMY0 ? 0 : 1));
newline(); newline();
b[0] = CMD_PING;
can_send_data(b, 1); // return to slave: pong
break; break;
case CMD_PING: // pong case CMD_PING: // pong
can_send_data(b, 1); can_send_data(b, 1);
@ -174,6 +176,9 @@ void can_messages_proc(){
*((uint32_t*)&b[2]) = Tms; *((uint32_t*)&b[2]) = Tms;
can_send_data(b, 6); can_send_data(b, 6);
break; break;
case CMD_RESET_MCU:
NVIC_SystemReset();
break;
} }
}else if(data[0] == DATA_MARK){ // process received data }else if(data[0] == DATA_MARK){ // process received data
char Ns = '0' + data[1]; char Ns = '0' + data[1];

View File

@ -50,6 +50,7 @@ typedef enum{
CMD_REINIT_SENSORS, // (re)init sensors CMD_REINIT_SENSORS, // (re)init sensors
CMD_GETBUILDNO, // request for firmware build number CMD_GETBUILDNO, // request for firmware build number
CMD_SYSTIME, // get system time CMD_SYSTIME, // get system time
CMD_RESET_MCU, // reset MCU
// dummy commands for test purposes // dummy commands for test purposes
CMD_DUMMY0 = 0xDA, CMD_DUMMY0 = 0xDA,
CMD_DUMMY1 = 0xAD CMD_DUMMY1 = 0xAD

View File

@ -35,7 +35,7 @@
#define TSYS01_START_CONV (0x48) #define TSYS01_START_CONV (0x48)
#define TSYS01_PROM_ADDR0 (0xA0) #define TSYS01_PROM_ADDR0 (0xA0)
// conversion time (with reserve) // conversion time (with reserve)
#define CONV_TIME (15) #define CONV_TIME (25)
uint8_t read_i2c(uint8_t addr, uint32_t *data, uint8_t nbytes); uint8_t read_i2c(uint8_t addr, uint32_t *data, uint8_t nbytes);
uint8_t write_i2c(uint8_t addr, uint8_t data); uint8_t write_i2c(uint8_t addr, uint8_t data);

View File

@ -44,6 +44,7 @@ void sys_tick_handler(void){
++Tms; ++Tms;
} }
#if 0
static void iwdg_setup(){ static void iwdg_setup(){
/* Enable the peripheral clock RTC */ /* Enable the peripheral clock RTC */
/* (1) Enable the LSI (40kHz) */ /* (1) Enable the LSI (40kHz) */
@ -64,6 +65,7 @@ static void iwdg_setup(){
while(IWDG->SR); /* (5) */ while(IWDG->SR); /* (5) */
IWDG->KR = IWDG_REFRESH; /* (6) */ IWDG->KR = IWDG_REFRESH; /* (6) */
} }
#endif
int main(void){ int main(void){
uint32_t lastT = 0, lastS = 0, lastB = 0; uint32_t lastT = 0, lastS = 0, lastB = 0;
@ -81,7 +83,7 @@ int main(void){
RCC->CSR |= RCC_CSR_RMVF; // remove reset flags RCC->CSR |= RCC_CSR_RMVF; // remove reset flags
USB_setup(); USB_setup();
sensors_init(); sensors_init();
iwdg_setup(); //iwdg_setup();
while (1){ while (1){
IWDG->KR = IWDG_REFRESH; // refresh watchdog IWDG->KR = IWDG_REFRESH; // refresh watchdog
@ -130,7 +132,7 @@ int main(void){
#endif #endif
cmd_parser(txt, 0); cmd_parser(txt, 0);
} }
if(lastB - Tms > 99){ // run `sendbuf` each 100ms if(lastB - Tms > 249){ // run `sendbuf` each 250ms
sendbuf(); sendbuf();
lastB = Tms; lastB = Tms;
} }

View File

@ -58,7 +58,7 @@ void sendbuf(){
if(blen == 0) return; if(blen == 0) return;
*bptr = 0; *bptr = 0;
if(USBcmd) USB_send(buff); if(USBcmd) USB_send(buff);
else while(LINE_BUSY == usart_send(buff, blen)){IWDG->KR = IWDG_REFRESH;} else for(int i = 0; (i < 9999) && (LINE_BUSY == usart_send(buff, blen)); ++i){IWDG->KR = IWDG_REFRESH;}
bptr = buff; bptr = buff;
blen = 0; blen = 0;
} }
@ -69,7 +69,7 @@ void addtobuf(const char *txt){
if(l > UARTBUFSZ){ if(l > UARTBUFSZ){
sendbuf(); // send prevoius data in buffer sendbuf(); // send prevoius data in buffer
if(USBcmd) USB_send(txt); if(USBcmd) USB_send(txt);
else while(LINE_BUSY == usart_send_blocking(txt, l)){IWDG->KR = IWDG_REFRESH;} else for(int i = 0; (i < 9999) && (LINE_BUSY == usart_send_blocking(txt, l)); ++i){IWDG->KR = IWDG_REFRESH;}
}else{ }else{
if(blen+l > UARTBUFSZ){ if(blen+l > UARTBUFSZ){
sendbuf(); sendbuf();
@ -222,6 +222,10 @@ void cmd_parser(char *txt, uint8_t isUSB){
} }
} }
switch(_1st){ switch(_1st){
case '#':
if(ID == BCAST_ID) NVIC_SystemReset();
CANsend(ID, CMD_RESET_MCU, _1st);
break;
case '@': case '@':
debugmode = !debugmode; debugmode = !debugmode;
SEND("DEBUG mode "); SEND("DEBUG mode ");
@ -336,7 +340,7 @@ void cmd_parser(char *txt, uint8_t isUSB){
CANsend(ID, CMD_START_MEASUREMENT, _1st); CANsend(ID, CMD_START_MEASUREMENT, _1st);
break; break;
case 't': case 't':
if(!sensors_scan_mode) sensors_start(); sensors_start();
break; break;
case 'u': case 'u':
SEND("Unique ID CAN mode\n"); SEND("Unique ID CAN mode\n");
@ -380,8 +384,9 @@ void cmd_parser(char *txt, uint8_t isUSB){
SEND("https://github.com/eddyem/tsys01/tree/master/STM32/TSYS_controller build#" BUILD_NUMBER " @ " BUILD_DATE "\n"); SEND("https://github.com/eddyem/tsys01/tree/master/STM32/TSYS_controller build#" BUILD_NUMBER " @ " BUILD_DATE "\n");
SEND( SEND(
"ALL little letters - without CAN messaging\n" "ALL little letters - without CAN messaging\n"
"# - reset MCU (self or with given ID like '1#')\n"
"0..7 - send command to given controller (0 - this) instead of broadcast\n" "0..7 - send command to given controller (0 - this) instead of broadcast\n"
"@ - set/reset debug mode\n" "@ - set/clear debug mode\n"
"a - get raw ADC values\n" "a - get raw ADC values\n"
"B - send broadcast CAN dummy message\n" "B - send broadcast CAN dummy message\n"
"b - get/set CAN bus baudrate\n" "b - get/set CAN bus baudrate\n"

View File

@ -116,11 +116,13 @@ void sensors_off(){
static int sensors_on(){ static int sensors_on(){
mesg("Turn on sensors"); mesg("Turn on sensors");
curr_mul_addr = 0; curr_mul_addr = 0;
sensors_scan_mode = 0;
MUL_OFF(); MUL_OFF();
if(SENSORS_OVERCURNT()){ if(SENSORS_OVERCURNT()){
mesg("OVERCURRENT!"); mesg("OVERCURRENT!");
SENSORS_OFF(); SENSORS_OFF();
Sstate = (++overcurnt_ctr > 32) ? SENS_OVERCURNT_OFF : SENS_OVERCURNT; Sstate = (++overcurnt_ctr > 32) ? SENS_OVERCURNT_OFF : SENS_OVERCURNT;
if(Sstate == SENS_OVERCURNT_OFF) mesg("sensors_on() ---> OFF by overcurrent");
return FALSE; return FALSE;
}else{ }else{
mesg("Powered on"); mesg("Powered on");
@ -143,7 +145,7 @@ void sensors_init(){
* do nothing if measurement processing * do nothing if measurement processing
*/ */
void sensors_start(){ void sensors_start(){
if(sensors_scan_mode) return; //if(sensors_scan_mode) return;
switch(Sstate){ switch(Sstate){
case SENS_SLEEPING: case SENS_SLEEPING:
Sstate = SENS_START_MSRMNT; Sstate = SENS_START_MSRMNT;
@ -263,11 +265,13 @@ static uint8_t gettempproc(){
if(BAD_TEMPERATURE != (Temperatures[curr_mul_addr][i] = calc_t(t, i))){ if(BAD_TEMPERATURE != (Temperatures[curr_mul_addr][i] = calc_t(t, i))){
err = 0; err = 0;
++Ntemp_measured; ++Ntemp_measured;
} mesg(" got one T");
}else mesg(" bad T");
} }
} }
if(err){ if(err){
write_i2c(Taddr[i], TSYS01_RESET); write_i2c(Taddr[i], TSYS01_RESET);
mesg(" i2c err");
} }
} }
return TRUE; return TRUE;
@ -357,9 +361,11 @@ void showtemperature(){
void sensors_process(){ void sensors_process(){
static int8_t NsentOverCAN = -1; // number of T (N*10+p) sent over CAN bus; -1 - nothing to send static int8_t NsentOverCAN = -1; // number of T (N*10+p) sent over CAN bus; -1 - nothing to send
if(SENSORS_OVERCURNT()){ if(SENSORS_OVERCURNT()){
mesg("sensors_process(): overcurrent!");
MUL_OFF(); MUL_OFF();
SENSORS_OFF(); SENSORS_OFF();
Sstate = (++overcurnt_ctr > 32) ? SENS_OVERCURNT_OFF : SENS_OVERCURNT; Sstate = (++overcurnt_ctr > 32) ? SENS_OVERCURNT_OFF : SENS_OVERCURNT;
if(Sstate == SENS_OVERCURNT_OFF) mesg("sensors_process(): ---> OFF by overcurrent");
return; return;
} }
switch(Sstate){ switch(Sstate){
@ -368,18 +374,19 @@ void sensors_process(){
i2c_setup(CURRENT_SPEED); i2c_setup(CURRENT_SPEED);
Sstate = SENS_RESETING; Sstate = SENS_RESETING;
lastSensT = Tms; lastSensT = Tms;
NsentOverCAN = -1; //NsentOverCAN = -1;
break; break;
case SENS_RESETING: // reset & discovery procedure case SENS_RESETING: // reset & discovery procedure
if(NsentOverCAN == -1){ /*if(NsentOverCAN == -1){
mesg("SENS_RESETING"); mesg("SENS_RESETING");
NsentOverCAN = 0; NsentOverCAN = 0;
} }*/
if(Tms - lastSensT > POWERUP_TIME){ if(Tms - lastSensT > POWERUP_TIME){
if(sensors_scan(resetproc)){ if(sensors_scan(resetproc)){
count_sensors(); // get total amount of sensors count_sensors(); // get total amount of sensors
if(Nsens_present){ if(Nsens_present){
Sstate = SENS_GET_COEFFS; Sstate = SENS_GET_COEFFS;
mesg("SENS_RESETING -> SENS_GET_COEFFS");
}else{ // no sensors found }else{ // no sensors found
mesg("No sensors found -> off"); mesg("No sensors found -> off");
sensors_off(); sensors_off();
@ -388,39 +395,39 @@ void sensors_process(){
} }
break; break;
case SENS_GET_COEFFS: // get coefficients case SENS_GET_COEFFS: // get coefficients
mesg("SENS_GET_COEFFS");
if(sensors_scan(getcoefsproc)){ if(sensors_scan(getcoefsproc)){
Sstate = SENS_SLEEPING; // sleep after got coefficients Sstate = SENS_SLEEPING; // sleep after got coefficients
mesg("SENS_GET_COEFFS -> SENS_SLEEPING");
} }
break; break;
case SENS_START_MSRMNT: // send all sensors command to start measurements case SENS_START_MSRMNT: // send all sensors command to start measurements
mesg("SENS_START_MSRMNT");
if(sensors_scan(msrtempproc)){ if(sensors_scan(msrtempproc)){
lastSensT = Tms; lastSensT = Tms;
Sstate = SENS_WAITING; Sstate = SENS_WAITING;
Ntemp_measured = 0; // reset value of good measurements Ntemp_measured = 0; // reset value of good measurements
mesg("SENS_START_MSRMNT -> SENS_WAITING");
} }
break; break;
case SENS_WAITING: // wait for end of conversion case SENS_WAITING: // wait for end of conversion
mesg("SENS_WAITING");
if(Tms - lastSensT > CONV_TIME){ if(Tms - lastSensT > CONV_TIME){
NsentOverCAN = -1; //NsentOverCAN = -1;
mesg("SENS_WAITING -> SENS_GATHERING");
Sstate = SENS_GATHERING; Sstate = SENS_GATHERING;
} }
break; break;
case SENS_GATHERING: // scan all sensors, get thermal data & calculate temperature case SENS_GATHERING: // scan all sensors, get thermal data & calculate temperature
if(NsentOverCAN < 0){ /*if(NsentOverCAN < 0){
mesg("SENS_SLEEPING"); mesg("SENS_GATHERING");
NsentOverCAN = 0; NsentOverCAN = 0;
} }*/
if(sensors_scan(gettempproc)){ if(sensors_scan(gettempproc)){
lastSensT = Tms; lastSensT = Tms;
NsentOverCAN = 0; NsentOverCAN = 0;
Sstate = SENS_SENDING_DATA; Sstate = SENS_SENDING_DATA;
mesg("SENS_GATHERING -> SENS_SENDING_DATA");
} }
break; break;
case SENS_SENDING_DATA: case SENS_SENDING_DATA:
mesg("SENS_SENDING_DATA");
if(Nsens_present == 0){ if(Nsens_present == 0){
mesg("No sensors found -> off"); mesg("No sensors found -> off");
sensors_off(); sensors_off();
@ -430,6 +437,7 @@ void sensors_process(){
NsentOverCAN = send_temperatures(NsentOverCAN); // call sending T process NsentOverCAN = send_temperatures(NsentOverCAN); // call sending T process
if(NsentOverCAN < 0){ // all data sent -> sleep if(NsentOverCAN < 0){ // all data sent -> sleep
Sstate = SENS_SLEEPING; Sstate = SENS_SLEEPING;
mesg("SENS_SENDING_DATA -> SENS_SLEEPING");
/* /*
if(Nsens_present != Ntemp_measured){ // restart sensors only after measurements sent if(Nsens_present != Ntemp_measured){ // restart sensors only after measurements sent
mesg("restart"); mesg("restart");
@ -439,13 +447,14 @@ void sensors_process(){
} }
break; break;
case SENS_SLEEPING: // wait for `SLEEP_TIME` till next measurements in scan mode case SENS_SLEEPING: // wait for `SLEEP_TIME` till next measurements in scan mode
if(NsentOverCAN < 0){ /*if(NsentOverCAN < 0){
mesg("SENS_SLEEPING"); mesg("SENS_SLEEPING");
NsentOverCAN = 0; NsentOverCAN = 0;
} }*/
if(sensors_scan_mode){ // sleep until next measurement start if(sensors_scan_mode){ // sleep until next measurement start
if(Tms - lastSensT > SLEEP_TIME){ if(Tms - lastSensT > SLEEP_TIME){
Sstate = SENS_START_MSRMNT; Sstate = SENS_START_MSRMNT;
mesg("SENS_SLEEPING -> SENS_START_MSRMNT");
} }
} }
break; break;

View File

@ -29,6 +29,7 @@
#include "usb.h" #include "usb.h"
#endif #endif
#define WAITFOR (72000000)
extern volatile uint32_t Tms; extern volatile uint32_t Tms;
static int datalen[2] = {0,0}; // received data line length (including '\n') static int datalen[2] = {0,0}; // received data line length (including '\n')
@ -62,14 +63,14 @@ TXstatus usart_send(const char *str, int len){
if(!txrdy) return LINE_BUSY; if(!txrdy) return LINE_BUSY;
if(len > UARTBUFSZ) return STR_TOO_LONG; if(len > UARTBUFSZ) return STR_TOO_LONG;
txrdy = 0; txrdy = 0;
IWDG->KR = IWDG_REFRESH;
#ifdef EBUG #ifdef EBUG
USB_send("\n\n\nUSART send:\n"); USB_send("\n\n\nUSART send:\n");
USB_send(str); USB_send(str);
USB_send("\n\n"); USB_send("\n\n");
#endif #endif
memcpy(tbuf, str, len); memcpy(tbuf, str, len);
while(!(USARTX->ISR & USART_ISR_TXE)); // no refresh of WD to prevent weird things for(int i = 0; (i < WAITFOR) && !(USARTX->ISR & USART_ISR_TXE); ++i){IWDG->KR = IWDG_REFRESH;}
if(!(USARTX->ISR & USART_ISR_TXE)) return LINE_BUSY;
#if USARTNUM == 2 #if USARTNUM == 2
DMA1_Channel4->CCR &= ~DMA_CCR_EN; DMA1_Channel4->CCR &= ~DMA_CCR_EN;
DMA1_Channel4->CNDTR = len; DMA1_Channel4->CNDTR = len;
@ -80,25 +81,32 @@ TXstatus usart_send(const char *str, int len){
DMA1_Channel2->CCR |= DMA_CCR_EN; DMA1_Channel2->CCR |= DMA_CCR_EN;
#else #else
#error "Not implemented" #error "Not implemented"
#endif
#ifdef EBUG
USB_send(" -> start transmission\n");
#endif #endif
return ALL_OK; return ALL_OK;
} }
TXstatus usart_send_blocking(const char *str, int len){ TXstatus usart_send_blocking(const char *str, int len){
if(!txrdy) return LINE_BUSY; if(!txrdy) return LINE_BUSY;
int i;
bufovr = 0; bufovr = 0;
IWDG->KR = IWDG_REFRESH; IWDG->KR = IWDG_REFRESH;
while(!(USARTX->ISR & USART_ISR_TXE)); // no refresh of WD to prevent weird things for(int i = 0; (i < WAITFOR) && !(USARTX->ISR & USART_ISR_TXE); ++i){IWDG->KR = IWDG_REFRESH;}
if(!(USARTX->ISR & USART_ISR_TXE)) return LINE_BUSY;
#ifdef EBUG #ifdef EBUG
USB_send("\n\n\nUSART send blocking:\n"); USB_send("\n\n\nUSART send blocking:\n");
USB_send(str); USB_send(str);
USB_send("\n\n"); USB_send("\n");
#endif #endif
for(i = 0; i < len; ++i){ for(int l = 0; l < len; ++l){
USARTX -> TDR = *str++; USARTX -> TDR = *str++;
while(!(USARTX->ISR & USART_ISR_TXE)){IWDG->KR = IWDG_REFRESH;}; for(int i = 0; (i < WAITFOR) && !(USARTX->ISR & USART_ISR_TXE); ++i){IWDG->KR = IWDG_REFRESH;}
if(!(USARTX->ISR & USART_ISR_TXE)) return LINE_BUSY;
} }
#ifdef EBUG
USB_send(" -> done\n");
#endif
return ALL_OK; return ALL_OK;
} }
/* /*
@ -135,7 +143,7 @@ void usart_setup(){
USART2->BRR = 480000 / 1152; USART2->BRR = 480000 / 1152;
USART2->CR3 = USART_CR3_DMAT; // enable DMA Tx USART2->CR3 = USART_CR3_DMAT; // enable DMA Tx
USART2->CR1 = USART_CR1_TE | USART_CR1_RE | USART_CR1_UE; // 1start,8data,nstop; enable Rx,Tx,USART USART2->CR1 = USART_CR1_TE | USART_CR1_RE | USART_CR1_UE; // 1start,8data,nstop; enable Rx,Tx,USART
while(!(USART2->ISR & USART_ISR_TC)); // polling idle frame Transmission for(int i = 0; (i < WAITFOR) && !(USART2->ISR & USART_ISR_TC); ++i){IWDG->KR = IWDG_REFRESH;} // polling idle frame Transmission
USART2->ICR |= USART_ICR_TCCF; // clear TC flag USART2->ICR |= USART_ICR_TCCF; // clear TC flag
USART2->CR1 |= USART_CR1_RXNEIE; USART2->CR1 |= USART_CR1_RXNEIE;
NVIC_EnableIRQ(USART2_IRQn); NVIC_EnableIRQ(USART2_IRQn);
@ -159,7 +167,7 @@ void usart_setup(){
USART1->BRR = 480000 / 1152; USART1->BRR = 480000 / 1152;
USART1->CR3 = USART_CR3_DMAT; // enable DMA Tx USART1->CR3 = USART_CR3_DMAT; // enable DMA Tx
USART1->CR1 = USART_CR1_TE | USART_CR1_RE | USART_CR1_UE; // 1start,8data,nstop; enable Rx,Tx,USART USART1->CR1 = USART_CR1_TE | USART_CR1_RE | USART_CR1_UE; // 1start,8data,nstop; enable Rx,Tx,USART
while(!(USART1->ISR & USART_ISR_TC)); // polling idle frame Transmission for(int i = 0; (i < WAITFOR) && !(USART1->ISR & USART_ISR_TC); ++i){IWDG->KR = IWDG_REFRESH;} // polling idle frame Transmission
USART1->ICR |= USART_ICR_TCCF; // clear TC flag USART1->ICR |= USART_ICR_TCCF; // clear TC flag
USART1->CR1 |= USART_CR1_RXNEIE; USART1->CR1 |= USART_CR1_RXNEIE;
NVIC_EnableIRQ(USART1_IRQn); NVIC_EnableIRQ(USART1_IRQn);

View File

@ -1,3 +1,3 @@
#define BUILD_NUMBER "66" #define BUILD_NUMBER "80"
#define BUILD_DATE "2023-09-11" #define BUILD_DATE "2023-09-12"
#define BUILDNO 66 #define BUILDNO 80