UD-GS1 デバグ用 3D Acc 動かない
Fork of UDNS1_mbed-dev by
Revision 173:1198e6c31b4a, committed 2018-09-24
- Comitter:
- hakusan270
- Date:
- Mon Sep 24 15:11:03 2018 +0000
- Parent:
- 172:3aa6f1366c5d
- Commit message:
- ??????
Changed in this revision
--- a/main.cpp Sat Sep 22 13:35:44 2018 +0000 +++ b/main.cpp Mon Sep 24 15:11:03 2018 +0000 @@ -1,6 +1,8 @@ #include "mbed.h" #include <string.h> - +#include <time.h> +#include "rtc_api.h" +#include "watchdog.h" #define ONE_G_ACCELERATION 9.8 //重力加速度 #define EXP_BIAS 12 @@ -25,13 +27,17 @@ AnalogIn batlev(PA_2); InterruptIn event(PA_7); +Watchdog wd; + char buffer[100]; uint8_t rxbuffer[128]; uint8_t cmdrxbuffer[80]; +uint8_t rxCmdStatus[128]; int rxindex=0; +int oldrxindex; int cmdrxindex=0; uint8_t rcvf; - +uint8_t dbgmsgf=1; uint8_t errorf; void intTimer( void ); @@ -40,6 +46,7 @@ unsigned short UDGS1_encodeFloat(float v); int int_sqrt(unsigned int x); int initLIS3DH(); +int readTemp(short *tmp); void rx_Irq(void) { @@ -47,16 +54,20 @@ uint8_t c; while(pclpwa.readable() ) { c = rxbuffer[rxindex] = pclpwa.getc(); - if (rxindex>120) { + if (rxindex>127) { rxbuffer[rxindex+1]=0; - pc.write((const uint8_t *)rxbuffer,rxindex,NULL); + if (dbgmsgf) pc.write((const uint8_t *)rxbuffer,rxindex,NULL); + memcpy((char*)rxCmdStatus,(char*)rxbuffer , rxindex+1 ); + oldrxindex = rxindex+1; rxindex=0; rcvf=1; rxbuffer[rxindex+1]=0; - } else rxindex++; + } else if (/*c==0x0d ||*/ c==0x0a) { rxbuffer[rxindex+1]=0; - pc.write((const uint8_t *)rxbuffer,rxindex+1,NULL); + if (dbgmsgf) pc.write((const uint8_t *)rxbuffer,rxindex+1,NULL); + strcpy((char*)rxCmdStatus,(char*)rxbuffer ); + oldrxindex = rxindex+1; rxindex=0; rcvf=1; if (strstr((char*)rxbuffer,"Invalid")) errorf=1; @@ -70,30 +81,34 @@ int SendLPWAcmd(char *cmd) { - int timeout=10; + int timeout=30; + int i=0; rcvf=0; errorf=0; wait_ms(1); while(rxindex && timeout--)wait_ms(10); - - - + if(timeout==0)pc.printf("timeout 1\n\r"); memset(rxbuffer,0,sizeof(rxbuffer)); rxindex=0; + wait_ms(10); pclpwa.printf(cmd); pclpwa.printf("\r\n"); - timeout=1000; + timeout=500; while (rcvf==0 && timeout--) wait_ms(10); + if(timeout==0)pc.printf("timeout 2\n\r"); if (errorf) { + timeout=500; //retry wait_ms(10); rcvf=0; errorf=0; + wait_ms(10); pclpwa.printf(cmd); pclpwa.printf("\r\n"); while (rcvf==0 && timeout--) wait_ms(10); + if(timeout==0)pc.printf("timeout 3\n\r"); } wait_ms(10); return errorf; @@ -125,35 +140,337 @@ pc.printf("@@@@@@@@ INTout1 @@@\n\r"); } +float convertLaloFomMin(float lalo) +{ + int integ; + float min; + integ = (int)lalo; + min = lalo - (float)integ; + min = min / 0.60 ; + return((float)integ + min); +} +/* 緯度 24 - 46 */ +long convertLaInt(float la) +{ + return( (int)((convertLaloFomMin(la) - 24.0f ) / 0.00001049042 ) ); +} + +/* 経度 122 - 146*/ + +long convertLoInt(float lo) +{ + return( (int)((convertLaloFomMin(lo) - 122.0f ) / 0.000011444095 ) ); +} + +/* 緯度 24 - 46 */ +float convertLaFloat(int la) +{ + return( 24.0f + 0.00001049042 * (float)la ); +} + +/* 経度 122 - 146*/ + +float convertLoFloat(int lo) +{ + return( 122.0f + 0.000011444095 * (float)lo ); +} + + +int getNextTimeSet() +{ + int mode=0; + char *p; + dbgmsgf=0; + memset((char*)rxCmdStatus,0,sizeof(rxCmdStatus)); + SendLPWAcmd("< TIME DREM GET"); +// pc.printf((char*)rxCmdStatus); + p = strstr((char*)rxCmdStatus,"TIME DREM GET"); + if (p) { +// pc.printf(p+13); + sscanf(p + 14,"%d",&mode); + } + dbgmsgf=1; + return(mode); +} + +int getNextTimeSend() +{ + int mode=0; + char *p; + dbgmsgf=0; + memset((char*)rxCmdStatus,0,sizeof(rxCmdStatus)); + SendLPWAcmd("< TIME TREM GET"); +// pc.printf((char*)rxCmdStatus); + p = strstr((char*)rxCmdStatus,"TIME TREM GET"); + if (p) { +// pc.printf(p+13); + sscanf(p + 14,"%d",&mode); + } + dbgmsgf=1; + return(mode); +} + +int setPayload(char *payload) { + char buf[60]= {"< TX PLD SET "}; + char dat[8]; + int i; + int ret; + for(i=0;i<16;i++){ + sprintf(dat,"%02x",payload[i] & 0xff); + strcat(buf,dat); + } + // pc.printf(buf); + ret = SendLPWAcmd(buf); + if (ret==0) { + if (strstr((char*)rxbuffer,"> TX PLD SET")==NULL) ret= -1; + } + return(ret); +} + +int getGNSSmode() +{ + int mode=0; + char *p; + dbgmsgf=0; + memset((char*)rxCmdStatus,0,sizeof(rxCmdStatus)); + SendLPWAcmd("< GNSS STT GET"); +// pc.printf((char*)rxCmdStatus); + p = strstr((char*)rxCmdStatus,"GNSS STT GET"); + if (p) { +// pc.printf(p+13); + sscanf(p + 13,"%x",&mode); + } + dbgmsgf=1; + return(mode); +} + +int getGPStime(time_t *gpst) +{ + int timeout=10; + dbgmsgf=0; + int ret=0; + char *p; + memset((char*)rxCmdStatus,0,sizeof(rxCmdStatus)); + SendLPWAcmd("< TIME CTIME GET"); + while(timeout--) { + wait_ms(500); + p = strstr((char*)rxCmdStatus,"TIME CTIME"); + if (p) break; + } + wait_ms(1); + p = strstr((char*)rxCmdStatus,"0x"); + if (p) { + sscanf(p,"%x",(int*)gpst); + ret=1; + } + dbgmsgf=1; + return(ret); +} + + +int getTimeFromGPS(char *buf, int rtcset){ + time_t gpstime; + time_t tim; + int ret; + struct tm *now; + if ( getGPStime(&gpstime) ) { + int gpsw, gpstw; + gpsw = gpstime >> 20; + gpstw = gpstime & 0xfffff; + tim = (gpsw * 7 * 24 * 60 * 60) + gpstw; + tim += (10*365*24*60*60 + 24*60*60*7 + 9*60*60);//Tokyo time + now = localtime(&tim); + if (rtcset) rtc_write(tim); + + ret = strftime(buf, 23,"%Y %m/%d %T",now); + return(ret); + } + return -1; +} + + + +int getGPSposGGA(float *pLo,float *pLa, float *pHDOP, long *pElev) +{ + int timeout=10; + int i,j; + dbgmsgf=0; + int ret=0; + int sum=0; + memset((char*)rxCmdStatus,0,sizeof(rxCmdStatus)); + SendLPWAcmd("< GNSS HOST_FW_SENT SET_EVT 0x0001"); + while(timeout--) { + wait_ms(500); + if (strstr((char*)rxCmdStatus,"$GPGGA") ) break; + } + wait_ms(1); + if (timeout) { + for(i=0,j=0;i<128;i++) { + if (rxCmdStatus[i]== ',' ) { + j++; + if (j==2 && rxCmdStatus[i+2]!=',') sscanf((char*)rxCmdStatus+i+1, "%f",pLo ); + else if (j==4 && rxCmdStatus[i+2]!=',') sscanf((char*)rxCmdStatus+i+1, "%f",pLa ); + else if (j==8 && rxCmdStatus[i+2]!=',') sscanf((char*)rxCmdStatus+i+1, "%f",pHDOP ); + else if (j==9 && rxCmdStatus[i+2]!=',') sscanf((char*)rxCmdStatus+i+1, "%d",pElev ); + ret=1; + } else if (rxCmdStatus[i]== '*' ) { + sscanf((char*)rxCmdStatus+i+1, "%x",&sum ); + int x; + uint8_t s = 0; + for(x=3;rxCmdStatus[x]!='*';x++) s ^= rxCmdStatus[x]; + s &= 0xff; + // pc.printf("%s %02x, %02x %d\r\n",rxCmdStatus,sum,s & 0xff,sum); + if (s != sum){ + ret = -1;// check sum err + pc.printf("sum-err %s %02x, %02x \r\n",rxCmdStatus,sum,s & 0xff); + } + } + } + + SendLPWAcmd("< GNSS HOST_FW_SENT SET_EVT 0x0000"); + } + dbgmsgf=1; + return(ret); +} + + +int getGPSGSA(int *pmode,float *pPDOP) +{ + int timeout=10; + int i,j; + dbgmsgf=0; + int ret=0; + int sum=0; + memset((char*)rxCmdStatus,0,sizeof(rxCmdStatus)); + SendLPWAcmd("< GNSS HOST_FW_SENT SET_EVT 0x0004"); + while(timeout--) { + wait_ms(500); + if (strstr((char*)rxCmdStatus,"GSA") ) break; + } + wait_ms(1); + if (timeout) { + for(i=0,j=0;i<128;i++) { + if (rxCmdStatus[i]== ',' ) { + j++; + if (j==2 && rxCmdStatus[i+2]!=',') sscanf((char*)rxCmdStatus+i+1, "%d",pmode ); + else if (j==16 && rxCmdStatus[i+2]!=',') sscanf((char*)rxCmdStatus+i+1, "%f",pPDOP ); + ret=1; + } else if (rxCmdStatus[i]== '*' ) { + sscanf((char*)rxCmdStatus+i+1, "%x",&sum ); + int x; + uint8_t s = 0; + for(x=3;rxCmdStatus[x]!='*';x++) s ^= rxCmdStatus[x]; + s &= 0xff; + // pc.printf("%s %02x, %02x %d\r\n",rxCmdStatus,sum,s & 0xff,sum); + if (s != sum){ + ret = -1;// check sum err + pc.printf("sum-err %s %02x, %02x \r\n",rxCmdStatus,sum,s & 0xff); + } + } + } + + SendLPWAcmd("< GNSS HOST_FW_SENT SET_EVT 0x0000"); + } + dbgmsgf=1; + return(ret); +} + + + +int getGPSRMC(char *ptime,char *pdate,float *pLo,float *pLa) +{ + int timeout=10; + int i,j; + dbgmsgf=0; + int ret=0; + int sum=0; + memset((char*)rxCmdStatus,0,sizeof(rxCmdStatus)); + SendLPWAcmd("< GNSS HOST_FW_SENT SET_EVT 0x0020"); + while(timeout--) { + wait_ms(500); + if (strstr((char*)rxCmdStatus,"RMC") ) break; + } + wait_ms(1); + if (timeout) { + for(i=0,j=0;i<128;i++) { + if (rxCmdStatus[i]== ',' ) { + j++; + if (j==1) memcpy(ptime,(char*)rxCmdStatus+i+1,9 ); + else if (j==9) memcpy(pdate,(char*)rxCmdStatus+i+1,6 ); + else if (j==3 && rxCmdStatus[i+2]!=',') sscanf((char*)rxCmdStatus+i+1, "%f",pLo ); + else if (j==5 && rxCmdStatus[i+2]!=',') sscanf((char*)rxCmdStatus+i+1, "%f",pLa ); + ret=1; + } else if (rxCmdStatus[i]== '*' ) { + sscanf((char*)rxCmdStatus+i+1, "%x",&sum ); + int x; + uint8_t s = 0; + for(x=3;rxCmdStatus[x]!='*';x++) s ^= rxCmdStatus[x]; + s &= 0xff; + // pc.printf("%s %02x, %02x %d\r\n",rxCmdStatus,sum,s & 0xff,sum); + if (s != sum){ + ret = -1;// check sum err + pc.printf("sum-err %s %02x, %02x \r\n",rxCmdStatus,sum,s & 0xff); + } + } + } + + SendLPWAcmd("< GNSS HOST_FW_SENT SET_EVT 0x0000"); + } + dbgmsgf=1; + return(ret); +} + + + int main() { int i=0; short x,y,z; - - + char c; + int ret; + int rtcenb=0; + rtc_init(); + printf("\r\n**** Hello UD-GS1 by mbed ******\r\n"); + + long llo = convertLoInt(136.599999f); + float flo = convertLoFloat(llo); + long lla = convertLaInt(36.599999f); + float fla = convertLaFloat(lla); + pc.printf("lo=%f %08x la=%f %08x\r\n", flo,llo,fla,lla); + llo = convertLoInt(146.0f); + flo = convertLoFloat(llo); + lla = convertLaInt(46.0f); + fla = convertLaFloat(lla); + pc.printf("lo=%f %08x la=%f %08x\r\n", flo,llo,fla,lla); + + + if (wd.WatchdogCausedReset()) + pc.printf("Watchdog caused reset.\r\n"); + wd.Configure(30); + wd.Service(); // enabl.mode(PullNone); // wkup.mode(PullNone); // v20v.mode(PullNone); // ext7.mode(PullNone); -event.rise (&intpin1); -event.enable_irq(); + dbgmsgf=1; enabl = 0; - wkup = 1; // Normal mode - v20v = 1; //2V off - -// pc.attach(cmd_rx_Irq,Serial::RxIrq); + wkup = 1; // Normal mode + v20v = 1; //2V off + wait_ms(100); + enabl = 1; // enable + v20v = 0; //2V ON + while(pclpwa.readable()) c = pclpwa.getc(); pclpwa.attach(rx_Irq,Serial::RxIrq); - pclpwa.set_flow_control(Serial::RTSCTS,PB_1,PB_13); - printf("\r\n**** Hello UD-GS1 by mbed ******\r\n"); - wait_ms(100); + pclpwa.set_flow_control(Serial::RTSCTS,PB_1,PB_13); + wait_ms(500); // 4sec + printf("\r\n**** LPWA ON ******\r\n"); + + event.rise (&intpin1); + event.enable_irq(); pc.printf("Adc=%d INT1=%d INT2=%d ",(int)(batlev.read()*100.0f) , intout1.read(),intout2.read()); initLIS3DH(); read3axes(&x,&y,&z); - printf("3D acc x=%d y=%d z=%d\r\n",x,y,z); - v20v = 0; //2V on - wait_ms(100); - enabl = 1; // enable - wait_ms(4000); // 100 ms + printf("3D acc x=%d y=%d z=%d Temp=%d\r\n",x,y,z,readTemp(NULL)); // interrput.attach(&intTimer, 0.001); #if 0 SendLPWAcmd("< SYS MODE SET 05"); @@ -167,22 +484,85 @@ SendLPWAcmd("< SYS EEPROM GET 0x0414"); while(1); #endif - SendLPWAcmd("< SYS MODE SET 00"); + dbgmsgf=0; + ret = SendLPWAcmd("< SYS MODE SET 00"); + if (ret==0) pc.write((const uint8_t *)rxbuffer,oldrxindex+1,NULL); // SendLPWAcmd("< SYS MODE SET_EVT ON"); - SendLPWAcmd("< SYS VER GET"); - wait_ms(100); - SendLPWAcmd("< GNSS VER GET"); - wait_ms(100); + ret = SendLPWAcmd("< SYS VER GET"); + if (ret==0) pc.write((const uint8_t *)rxbuffer,oldrxindex+1,NULL); +// wait_ms(100); + ret = SendLPWAcmd("< GNSS VER GET"); + if (ret==0) pc.write((const uint8_t *)rxbuffer,oldrxindex+1,NULL); +// wait_ms(100); + ret = SendLPWAcmd("< SYS MODE SET 00"); + if (ret==0) pc.write((const uint8_t *)rxbuffer,oldrxindex+1,NULL); // SendLPWAcmd("< SYS TO_WAIT_FETCHING SET ON"); - SendLPWAcmd("< SYS TO_FETCHING SET ON"); - SendLPWAcmd("< TX PLD SET 0123456789ABCDEF0123456789ABCDEF"); + ret = SendLPWAcmd("< SYS TO_FETCHING SET ON"); + if (ret==0) pc.write((const uint8_t *)rxbuffer,oldrxindex+1,NULL); + ret = SendLPWAcmd("< TX PLD SET 0123456789ABCDEF0123456789ABCDEF"); + if (ret==0) pc.write((const uint8_t *)rxbuffer,oldrxindex+1,NULL); // SendLPWAcmd("< GNSS HOST_FW_SENT SET_EVT 0x0001"); - SendLPWAcmd("< TX PREV_STT SET_EVT ON"); - SendLPWAcmd("< GNSS STT GET"); + ret = SendLPWAcmd("< TX PREV_STT SET_EVT ON"); + if (ret==0) pc.write((const uint8_t *)rxbuffer,oldrxindex+1,NULL); + ret = SendLPWAcmd("< GNSS STT GET"); + if (ret==0) pc.write((const uint8_t *)rxbuffer,oldrxindex+1,NULL); + char pay[16]={0x00, 0x01, 0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x10,0x20,0x30,0x40,0x50,0x60,0x70}; + setPayload(pay); + if (ret==0) pc.write((const uint8_t *)rxbuffer,oldrxindex+1,NULL); + else pc.printf("Set payload error\r\n"); + + dbgmsgf=1; + + wd.Configure(20.0f); + while (1) { + int mode; + float lo=0.0f,la=0.0f,HDOP; + long elev; + wd.Service(); + + // printf(" cnt=%d stat= ",i++); - SendLPWAcmd("< GNSS STT GET"); - pc.printf("Adc=%d INT1=%d INT2=%d ",(int)(batlev.read()*100.0f) , intout1.read(),intout2.read()); + //SendLPWAcmd("< GNSS STT GET"); + mode = getGNSSmode(); + if (mode & 2 && rtcenb==0 ) { + char st[32]; + if (getTimeFromGPS(st,1)>0) { + pc.printf("%s ",st ); + + rtcenb=1; + } + } + pc.printf("Adc=%d INT1=%d INT2=%d mode=%02x next time=%d\r\n",(int)(batlev.read()*100.0f) , intout1.read(),intout2.read(), mode ,getNextTimeSet()); + if (mode & 4) { + char stime[10]={0}; + char sdate[8]={0}; + if (getGPSposGGA( &lo , &la, &HDOP,&elev) >= 0) { + pc.printf("Lo=N %f La=E %f HDOP=%f evevation=%d\r\n", lo/100.0f,la/100.0f,HDOP,elev); + } + + if ( getGPSGSA(&mode,&HDOP) >= 0) + pc.printf("GSA 2D/3D mode=%d PDOP=%f\r\n", mode,HDOP); + + if (getGPSRMC(stime,sdate,&lo , &la) >=0) + pc.printf("RMC Lo=N %f La=E %f time %s date=%s\r\n", lo/100.0f,la/100.0f,stime,sdate); + + } + if (mode &0x80) + pc.printf("next time=%d send=%d ",getNextTimeSet(), getNextTimeSend()); +if (rtcenb) +{ + time_t tim = rtc_read(); + struct tm *now; + char buf[24]={0}; + now = localtime(&tim); + strftime(buf, 23,"%Y %m/%d %T",now); + pc.printf("RTC time=%s\n\r",buf); +} + pc.printf("Temp =%d ",readTemp(NULL)); + + + wait_ms(4000); // pc.write((const uint8_t *)"ACBD\r\n",6,NULL); // pc.puts("ASDFGREWA\r\n"); @@ -215,7 +595,7 @@ Read multi regsters from SPI *************************************************/ unsigned char spireadRegs(unsigned char ad,unsigned char *p,int bytes){ -#if 1 +#if 0 while(bytes--) { *p = spireadReg( ad ); p++; @@ -249,6 +629,45 @@ } +/**************************************** + half float 16bit浮動小数点からfloatに変換 + SEEEEE TT TTTT TTTT --> SEEEEEEEE E TTT TTTT TTTT TTTT TTTT + signed ext + float 指数部 bias 127 + half 指数部 bias 15 +*****************************************/ +float UDGS1_16decodeFloat(unsigned short v){ + volatile float r; + int sign = 1; + if (v & 0x8000) { sign = -1; v&= 0x7fff;} + + if(v==0) return(0.0f); + if((v & 0x7c00) == 0 ) + *(unsigned long *)&r = ((v & 0x3ff) << (23-10)); + else + *(unsigned long *)&r = ((v & 0x3ff) << (23-10)) | (((v>>10) + (127-15)) << 23) ; + return(r * sign); +} + +/**************************************** + float から half 16bit浮動小数点に変換 + SEEEEE TT TTTT TTTT <-- SEEEEEEEE E TTT TTTT TTTT TTTT TTTT + float 指数部 bias 127 + half 指数部 bias 15 +*****************************************/ +unsigned short UDGS1_16encodeFloat(float v){ + unsigned short sign = 0; + if (v < 0.0f) sign = 0x8000; + + register unsigned long tf; + register unsigned short exp; + if(v <= 0.000000059f)return(0); + if(v > 131008.0f)return(0x7fff); + tf = *(unsigned long *)&v; + exp = ((tf >> 23) & 0xff ) - (127-15); + return( ((tf >> 13) & 0x3ff) | (exp << 10) | sign ); +} + /**************************************** tyny 13bit浮動小数点からfloatに変換 @@ -322,8 +741,7 @@ { int timeout=5; unsigned char regs[6]; -// STSPI.frequency(1000); - + while((spireadReg(0x07)&7)==0 && timeout--){wait_us(5);}; spireadRegs(0x28,regs,6);// 12bit signed 1G = 413 9.8m/s**2 // STSPI.frequency(); //1MHz @@ -333,4 +751,18 @@ return(0); } +/************************************************* + read temparature from LIS3DH +*************************************************/ +int readTemp(short *tmp) +{ + int t; + t = spireadReg(0x0d); + t |= spireadReg(0x0e) << 8; + t >>= 4; +// pc.printf("tmp %d %04x\r\n", t, t); + if (tmp) *tmp = t; + return(t); +} + \ No newline at end of file
--- a/targets/TARGET_STM/TARGET_STM32L0/device.h Sat Sep 22 13:35:44 2018 +0000 +++ b/targets/TARGET_STM/TARGET_STM32L0/device.h Mon Sep 24 15:11:03 2018 +0000 @@ -36,5 +36,5 @@ #define DEVICE_ID_LENGTH 24 #include "objects.h" - +#define RTC_LSI 1 #endif
--- a/targets/TARGET_STM/rtc_api.c Sat Sep 22 13:35:44 2018 +0000 +++ b/targets/TARGET_STM/rtc_api.c Mon Sep 24 15:11:03 2018 +0000 @@ -34,7 +34,7 @@ #include "mbed_error.h" static RTC_HandleTypeDef RtcHandle; - +//#define DEVICE_RTC_LSI 1 #if RTC_LSI #define RTC_CLOCK LSI_VALUE #else
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/watchdog.cpp Mon Sep 24 15:11:03 2018 +0000 @@ -0,0 +1,131 @@ +/// @file Watchdog.cpp provides the interface to the Watchdog module +/// +/// This provides basic Watchdog service for the mbed. You can configure +/// various timeout intervals that meet your system needs. Additionally, +/// it is possible to identify if the Watchdog was the cause of any +/// system restart. +/// +/// Adapted from Simon's Watchdog code from http://mbed.org/forum/mbed/topic/508/ +/// +/// @note Copyright © 2011 by Smartware Computing, all rights reserved. +/// This software may be used to derive new software, as long as +/// this copyright statement remains in the source file. +/// @author David Smart +/// +/// @note Copyright © 2015 by NBRemond, all rights reserved. +/// This software may be used to derive new software, as long as +/// this copyright statement remains in the source file. +/// +/// Added support for STM32 Nucleo platforms +/// +/// @author Bernaérd Remond +/// + +//#define LPC +#define ST_NUCLEO + + +#include "mbed.h" +#include "watchdog.h" + + +/// Watchdog gets instantiated at the module level +Watchdog::Watchdog() { +#ifdef LPC + wdreset = (LPC_WDT->WDMOD >> 2) & 1; // capture the cause of the previous reset +#endif +#ifdef ST_NUCLEO + // capture the cause of the previous reset + /* Check if the system has resumed from IWDG reset */ +/* + if (__HAL_RCC_GET_FLAG(RCC_FLAG_IWDGRST)) { + wdreset = true; + } + else { + wdreset = false; + } +*/ + wdreset = false; +#endif + +} + +/// Load timeout value in watchdog timer and enable +void Watchdog::Configure(float timeout) { +#ifdef LPC + LPC_WDT->WDCLKSEL = 0x1; // Set CLK src to PCLK + uint32_t clk = SystemCoreClock / 16; // WD has a fixed /4 prescaler, PCLK default is /4 + LPC_WDT->WDTC = (uint32_t)(timeout * (float)clk); + LPC_WDT->WDMOD = 0x3; // Enabled and Reset +#endif +#ifdef ST_NUCLEO + // see http://embedded-lab.com/blog/?p=9662 + #define LsiFreq (45000) + + uint16_t PrescalerCode; + uint16_t Prescaler; + uint16_t ReloadValue; + float Calculated_timeout; + + if ((timeout * (LsiFreq/4)) < 0x7FF) { + PrescalerCode = IWDG_PRESCALER_4; + Prescaler = 4; + } + else if ((timeout * (LsiFreq/8)) < 0xFF0) { + PrescalerCode = IWDG_PRESCALER_8; + Prescaler = 8; + } + else if ((timeout * (LsiFreq/16)) < 0xFF0) { + PrescalerCode = IWDG_PRESCALER_16; + Prescaler = 16; + } + else if ((timeout * (LsiFreq/32)) < 0xFF0) { + PrescalerCode = IWDG_PRESCALER_32; + Prescaler = 32; + } + else if ((timeout * (LsiFreq/64)) < 0xFF0) { + PrescalerCode = IWDG_PRESCALER_64; + Prescaler = 64; + } + else if ((timeout * (LsiFreq/128)) < 0xFF0) { + PrescalerCode = IWDG_PRESCALER_128; + Prescaler = 128; + } + else { + PrescalerCode = IWDG_PRESCALER_256; + Prescaler = 256; + } + + // specifies the IWDG Reload value. This parameter must be a number between 0 and 0x0FFF. + ReloadValue = (uint32_t)(timeout * (LsiFreq/Prescaler)); + + Calculated_timeout = ((float)(Prescaler * ReloadValue)) / LsiFreq; + printf("WATCHDOG set with prescaler:%d reload value: 0x%X - timeout:%f\n",Prescaler, ReloadValue, Calculated_timeout); + + IWDG->KR = 0x5555; //Disable write protection of IWDG registers + IWDG->PR = PrescalerCode; //Set PR value + IWDG->RLR = ReloadValue; //Set RLR value + IWDG->KR = 0xAAAA; //Reload IWDG + IWDG->KR = 0xCCCC; //Start IWDG - See more at: http://embedded-lab.com/blog/?p=9662#sthash.6VNxVSn0.dpuf +#endif + + Service(); +} + +/// "Service", "kick" or "feed" the dog - reset the watchdog timer +/// by writing this required bit pattern +void Watchdog::Service() { +#ifdef LPC + LPC_WDT->WDFEED = 0xAA; + LPC_WDT->WDFEED = 0x55; +#endif +#ifdef ST_NUCLEO + IWDG->KR = 0xAAAA; //Reload IWDG - See more at: http://embedded-lab.com/blog/?p=9662#sthash.6VNxVSn0.dpuf +#endif +} + +/// get the flag to indicate if the watchdog causes the reset +bool Watchdog::WatchdogCausedReset() { + return wdreset; +} + \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/watchdog.h Mon Sep 24 15:11:03 2018 +0000 @@ -0,0 +1,101 @@ +/// @file Watchdog.h provides the interface to the Watchdog module +/// +/// This provides basic Watchdog service for the mbed. You can configure +/// various timeout intervals that meet your system needs. Additionally, +/// it is possible to identify if the Watchdog was the cause of any +/// system restart, permitting the application code to take appropriate +/// behavior. +/// +/// Adapted from Simon's Watchdog code from http://mbed.org/forum/mbed/topic/508/ +/// +/// @note Copyright © 2011 by Smartware Computing, all rights reserved. +/// This software may be used to derive new software, as long as +/// this copyright statement remains in the source file. +/// @author David Smart +/// +/// History +/// \li v1.00 - 20110616: initial release with some documentation improvements +/// +#ifndef WATCHDOG_H +#define WATCHDOG_H +#include "mbed.h" + +/// The Watchdog class provides the interface to the Watchdog feature +/// +/// Embedded programs, by their nature, are usually unattended. If things +/// go wrong, it is usually important that the system attempts to recover. +/// Aside from robust software, a hardware watchdog can monitor the +/// system and initiate a system reset when appropriate. +/// +/// This Watchdog is patterned after one found elsewhere on the mbed site, +/// however this one also provides a method for the application software +/// to determine the cause of the reset - watchdog or otherwise. +/// +/// example: +/// @code +/// Watchdog wd; +/// +/// ... +/// main() { +/// if (wd.WatchdogCausedReset()) +/// pc.printf("Watchdog caused reset.\r\n"); +/// +/// wd.Configure(3.0); // sets the timeout interval +/// for (;;) { +/// wd.Service(); // kick the dog before the timeout +/// // do other work +/// } +/// } +/// @endcode +/// +class Watchdog { +public: + /// Create a Watchdog object + /// + /// example: + /// @code + /// Watchdog wd; // placed before main + /// @endcode + Watchdog(); + + /// Configure the timeout for the Watchdog + /// + /// This configures the Watchdog service and starts it. It must + /// be serviced before the timeout, or the system will be restarted. + /// + /// example: + /// @code + /// ... + /// wd.Configure(1.4); // configure for a 1.4 second timeout + /// ... + /// @endcode + /// + /// @param[in] timeout in seconds, as a floating point number + /// @returns none + /// + void Configure(float timeout); + + /// Service the Watchdog so it does not cause a system reset + /// + /// example: + /// @code + /// wd.Service(); + /// @endcode + /// @returns none + void Service(); + + /// WatchdogCausedReset identifies if the cause of the system + /// reset was the Watchdog + /// + /// example: + /// @code + /// if (wd.WatchdogCausedReset())) { + /// @endcode + /// + /// @returns true if the Watchdog was the cause of the reset + bool WatchdogCausedReset(); +private: + bool wdreset; +}; + +#endif // WATCHDOG_H \ No newline at end of file