int networkJoin(char *ssid) { int retval=0; if (!hasWifiModule) return retval; strcpy(networkSSID, ssid); console.debug("joining: %s\r\n",networkSSID); Watchdog_Reset(); radio.discard(); radio.printf("\r\nATE0\r\nAT+WA=%s\r\n",ssid); while (!radio.gotLine()); // and some timeout. while (!(retval=isErrorOrOK(radio.line()))){ //console.puts(radio.line()); while (!radio.gotLine()) { // timeout? ; } } Watchdog_Reset(); radio.printf("\r\nAT+ndhcp=1\r\n"); delay(1000); // this should be an idle. while (!radio.gotLine()); // and some timeout. while (!(isErrorOrOK(radio.line()))){ console.debug("%s",radio.line()); while (!radio.gotLine()) { ; } } //console.debug("join %s (%d)\r\n",networkSSID,retval=networkStatus()); return(networkStatus()); }
void readSettings() { int n,cc; char ch, buff[24]; char buff2[80]; unsigned int ndx=0; int read=0; if (!settingsFile.open(&root, settingsFileName, O_READ)) { console.printf("DBG: Creating New Settings File\r\n"); console.flush(); writeSettings(); return; } console.printf("DBG: Opened Settings File: %s\r\n",settingsFileName); settingsFile.seekSet(0); while ((read=settingsFile.read(buff, sizeof(buff))) > 0) { //console.printf("DBG: READ %d\r\n",read); console.flush(); for (cc=0; cc < read ; cc++) { ch=buff[cc]; //console.putChar(ch); console.flush(); buff2[ndx]=ch; if (ndx<MAX_INPUT_LINE) {ndx++;} if (ch=='\n'){//console.putChar('\r'); if(ndx) { ndx--; // eat the newline. } buff2[ndx]='\0'; //console.puts(buff2); if ((ndx>4) && buff2[3]=='!') {//fix this when the files are better buff2[3]='\0'; n=lookupIndex(buff2); switch (n) { case _NPW_: networkSetPassword(buff2+4); break; case _NJN_: Watchdog_Reset(); networkJoin(buff2 +4); break; case _PKY_: strncpy(pachubeKey, buff2+4, MAX_PATCHUBE_KEY_LENGHT-1); break; case _PFD_: strncpy(pachubeFeed, buff2+4, MAX_PATCHUBE_FEED_LENGHT-1); break; default: break; } } ndx=0; } } } console.printf("DBG: Finished with Settings File: %s\r\n",settingsFileName); settingsFile.close(); }
void SD_Write_Block(PTR_LBA_APP_STRUCT lba_data_ptr) { uint_32 u32Counter; /*Body*/ gu8SD_Argument.lword = lba_data_ptr->offset; if(SD_SendCommand(SD_CMD24|0x40,SD_OK)) { return; /* Command IDLE fail */ }/*EndIf*/ SPI_Send_byte(0xFE); for(u32Counter=0;u32Counter<lba_data_ptr->size;u32Counter++) { SPI_Send_byte(*(lba_data_ptr->buff_ptr + u32Counter)); }/*EndFor*/ SPI_Send_byte(0xFF); /* checksum Bytes not needed */ SPI_Send_byte(0xFF); if((SPI_Receive_byte() & 0x0F) != 0x05) { return; /* Command fail */ }/*EndIf*/ while(SPI_Receive_byte()==0x00) { Watchdog_Reset(); /* Dummy SPI cycle */ }/*EndWhile*/ return; }/*EndBody*/
void loop() { static int disconnected; console.printf("HELLO?\r\n"); if (millis() - lastCheck > 3000) { digitalWrite(RED_LED,LED_OFF); if ((! hasWifiModule) || networkStatus()) { digitalWrite(RED_LED,LED_OFF); disconnected=0; } else { digitalWrite(RED_LED,LED_ON); if (++disconnected > 10) { char tempssid[40]; strcpy(tempssid,networkSSID); digitalWrite(RED_LED,networkJoin(tempssid)?LED_OFF:LED_ON); } } digitalWrite(GRN_LED,SerialUSB.isConnected()?HIGH:LOW); lastCheck=millis(); } while (console.gotLine()) { digitalWrite(GRN_LED,LOW); handleConsoleInput(); digitalWrite(GRN_LED,HIGH); } clearStowedValues(); Watchdog_Reset(); }
void setup() { //spi.begin(SPI_281_250KHZ, MSBFIRST, 0); pinMode(GRN_LED,OUTPUT); pinMode(ORN_LED,OUTPUT); pinMode(RED_LED,OUTPUT); digitalWrite(GRN_LED,HIGH); digitalWrite(ORN_LED,LOW); digitalWrite(RED_LED,LOW); //iwdg_init(IWDG_PRE_256, WATCHDOG_TIMEOUT); Watchdog_Reset(); delay(3000); console.printf("HELLO?\r\n"); setupRadioModule(); digitalWrite(GRN_LED,LOW); digitalWrite(RED_LED,HIGH); console.printf("LSV:" BOM_VERSION "\r\n"); console.printf("NST: %s\r\n",networkStatus()?"CONNECTED":"NOT CONNECTED"); digitalWrite(ORN_LED,HIGH); digitalWrite(RED_LED,networkStatus()?HIGH:LOW); }
/********************************************************* * Name: SPI_Send_byte * Desc: Send one byte * Parameter: The byte to be sent * Return: None **********************************************************/ void SPI_Send_byte(uint_8 u8Data) { /*Body*/ /* Check the status flag */ if(SPI1_SR & SPI_SR_EOQF_MASK) { /* Clear the EOQF by writting a 1 to it */ SPI1_SR |= SPI_SR_EOQF_MASK; }/*Endif*/ /* Write the DSPI_PUSHR register */ SPI1_PUSHR = ( SPI_PUSHR_CTAS(0) | SPI_PUSHR_EOQ_MASK | SPI_PUSHR_CTCNT_MASK | SPI_PUSHR_PCS(1) | SPI_PUSHR_TXDATA(u8Data)); /* Write the clock and transfer attributes: master clock and frame size (8 bits) */ SPI1_CTAR0 = ( SPI_CTAR_SLAVE_FMSZ(7) | gSPI_BeforeTransfDelay | gSPI_AfterTransfDelay | gSPI_InterTransfDelay | gSPI_BaudRate); /* Start the transfer */ SPI1_MCR &= ~SPI_MCR_HALT_MASK; /* Wait until the transfer has been finished */ while(!(SPI1_SR & SPI_SR_EOQF_MASK)) { Watchdog_Reset(); }/*EndWhile*/ /* Clear the EOQF by writting a 1 to it */ SPI1_SR |= SPI_SR_EOQF_MASK; }/*EndBody*/
void loop() { static int disconnected; if (millis() - lastCheck > 3000) { if (networkStatus()) { digitalWrite(RED_LED,LED_OFF); disconnected=0; } else { digitalWrite(RED_LED,LED_ON); if (++disconnected > 10) { char tempssid[40]; strcpy(tempssid,networkSSID); digitalWrite(RED_LED,networkJoin(tempssid)?LED_OFF:LED_ON); } } digitalWrite(GRN_LED,SerialUSB.isConnected()?HIGH:LOW); lastCheck=millis(); } while (device.gotLine()) { handleDeviceInput(); } while (console.gotLine()) { digitalWrite(GRN_LED,LOW); handleConsoleInput(); digitalWrite(GRN_LED,HIGH); } Watchdog_Reset(); }
/****************************************************************************** * @name main * * @brief This routine is the starting point of the application * * @param None * * @return None * ***************************************************************************** * This function initializes the system, enables the interrupts and calls the * application *****************************************************************************/ void main(void) { Init_Sys(); /* initial the system */ #if MAX_TIMER_OBJECTS (void)TimerQInitialize(0); #endif (void)TestApp_Init(); /* Initialize the USB Test Application */ #if MAX_TIMER_OBJECTS StartKeyPressSimulationTimer(); #endif while(TRUE) { Watchdog_Reset(); /* Call the application task */ TestApp_Task(); } }
/*------------------------------------------------------------setupRadioModule() * *----------------------------------------------------------------------------*/ void setupRadioModule(void) { long int mark=millis(); radio.printf("\r\n"); radio.discard(); //radio.printf("ATE0\r\nAT&K0\r\nAT&R0\r\nAT+WD\r\nAT+NCLOSEALL\r\n"); radio.printf("ATE0\r\nATH\r\n"); while (!radio.gotLine()); while ((millis()-mark<1000)&&(!(hasWifiModule=isErrorOrOK(radio.line())))){ console.printf("DBG: %s\r\n",radio.line()); while (!radio.gotLine()) { ; } } radio.discard(); networkSetPassword(networkPassword); Watchdog_Reset(); networkJoin(networkSSID); }
uint_8 SD_Init(void) { SPI_Init(); // SPI Initialization SD_CLKDelay(10); // Send 80 clocks gu8SD_Argument.lword = 0; SD_CLKDelay(8); /* IDLE Command */ if(SD_SendCommand(SD_CMD0|0x40,SD_IDLE)) { return(1); // Command IDLE fail } (void)SPI_Receive_byte(); // Dummy SPI cycle /* Initialize SD Command */ while(SD_SendCommand(SD_CMD1|0x40,SD_OK)) { Watchdog_Reset(); } (void)SPI_Receive_byte(); // Dummy SPI cycle /* Block Length */ gu8SD_Argument.lword = SD_BLOCK_SIZE; if(SD_SendCommand(SD_CMD16|0x40,SD_OK)) { return(1); // Command IDLE fail } SPI_High_rate(); SPI_Send_byte(0x00); SPI_Send_byte(0x00); //(void)SPI_Receive_byte(); // Dummy SPI cycle return(0); }
/********************************************************* * Name: SPI_Receive_byte * Desc: The byte received by SPI * Parameter: None * Return: Received byte **********************************************************/ uint_8 SPI_Receive_byte(void) { uint_16 u8Data; /*Body*/ /* Check the status flag */ if(SPI1_SR & SPI_SR_EOQF_MASK) { /* Clear the EOQF by writting a 1 to it */ SPI1_SR |= SPI_SR_EOQF_MASK; }/*EndIf*/ /* Write the DSPI_PUSHR register */ SPI1_PUSHR = ( SPI_PUSHR_CTAS(0) | SPI_PUSHR_EOQ_MASK | SPI_PUSHR_CTCNT_MASK | SPI_PUSHR_PCS(1) | SPI_PUSHR_TXDATA(0xFF)); /* Write the clock and transfer attributes: master clock and frame size (8 bits) */ SPI1_CTAR0 = ( SPI_CTAR_FMSZ(7) | gSPI_BeforeTransfDelay | gSPI_AfterTransfDelay | gSPI_InterTransfDelay | gSPI_BaudRate); /* Start the transfer */ SPI1_MCR &= ~SPI_MCR_HALT_MASK; /* Wait until the transfer has been finished */ while(!(SPI1_SR & SPI_SR_EOQF_MASK)) { Watchdog_Reset(); }/*EndWhile*/ /* Clear the EOQF by writting a 1 to it */ SPI1_SR |= SPI_SR_EOQF_MASK; /* Read the byte form the DSPI_POPR register */ u8Data = (uint_16)SPI_RXFR0_RXDATA(SPI1_POPR); return((uint_8)u8Data); }/*EndBody*/
uint_8 SD_Init(void) { /*Body*/ SPI_Init(); /* SPI Initialization */ SD_CLKDelay(10); /* Send 80 clocks */ gu8SD_Argument.lword = 0; SD_CLKDelay(8); /* IDLE Command */ if(SD_SendCommand(SD_CMD0|0x40,SD_IDLE)) { return(1); /* Command IDLE fail */ }/*EndIf*/ (void)SPI_Receive_byte(); /* Dummy SPI cycle */ /* Initialize SD Command */ while(SD_SendCommand(SD_CMD1|0x40,SD_OK)) { Watchdog_Reset(); }/*EndWhile*/ (void)SPI_Receive_byte(); /* Dummy SPI cycle */ /* Block Length */ gu8SD_Argument.lword = SD_BLOCK_SIZE; if(SD_SendCommand(SD_CMD16|0x40,SD_OK)) { return(1); /* Command IDLE fail */ }/*EndIf*/ SPI_High_rate(); SPI_Send_byte(0x00); SPI_Send_byte(0x00); return(0); }/*EndBody*/
/****************************************************************************** * @name main * * @brief This routine is the starting point of the application * * @param None * * @return None * ***************************************************************************** * This function initializes the system, enables the interrupts and calls the * application *****************************************************************************/ void main(void) { /* Bootloader application */ GPIO_Bootloader_Init(); Switch_mode(); /* switch between the application and the bootloader mode */ Init_Sys(); /* initial the system */ #if MAX_TIMER_OBJECTS (void)TimerQInitialize(0); #endif (void)TestApp_Init(); /* Initialize the USB Test Application */ while(TRUE) { Watchdog_Reset(); /* Call the application task */ TestApp_Task(); } }
/** * @brief Attempt to get the name of a RN42 module (this is usually used for datalogger device name assignment) * @param Pointer to serial 'number' string, uint8_t variable set to non zero to enable automatic configuration of RN42 modules (typically for new ones) * @reval Returns zero for success, nonzero for failure (1==no name, 2==failed to get module into command mode) */ uint8_t RN42_get_name(uint8_t SerialNumber[8], uint8_t allowconfig) { if(!RN42_get_command()) { //If we were able to get Command mode uint8_t datavar; while(anything_in_buff((&Usart1_rx_buff))) { //Empty CMD from buffer Get_From_Buffer(&datavar,&Usart1_rx_buff);//Take from buffer } Usart_Send_Str((char*)"GN\r\n"); //Get Name command (note that this is busy wait based) Watchdog_Reset(); { uint8_t counter=0; uint32_t millis=Millis; //Store this for reference while(Millis<(millis+150)) { //Times out after 150ms if(anything_in_buff((&Usart1_rx_buff))) {//Get serial number and place in buffer Get_From_Buffer(&(SerialNumber[counter]),&Usart1_rx_buff);//Take from buffer if((SerialNumber[counter++]=='\n') || (counter>=7)) { //Break out if we get '\r' or reach end of the string break; } } } if(counter>2) { SerialNumber[counter-2]=0; //Remove the return datavar=0; //Success } else { //Something wrong - no name strcpy(SerialNumber,"NNM"); //Store an error name datavar=1; //One means no name has been assigned } } Usart_Send_Str((char*)"---\r"); //Return to Data mode return datavar; } else { strcpy(SerialNumber,"ERR"); //If RN42 module failure, name goes to "ERR" if(allowconfig) //Usually if time.txt file either doesnt exist or is empty, try to configure the RN-42 (!(FATFS_info.fsize)) RN42_conf(); //Try to configure the RN-42 return 2; //2 means the RN42 command mode failed } }
int main(void) { uint8_t system_state=0, i2c_resets=0, si446x_resets=0;//used to track button press functionality and any errors uint8_t sensors=0; uint32_t repetition_counter=0; //Used to detect any I2C lockup uint8_t L3GD20_Data_Buffer_old[8]; //Used to test for noise in the gyro data (indicating that it is working) uint8_t UplinkFlags=0,CutFlags=0; uint16_t UplinkBytes=0; //Counters and flags for telemetry uint32_t last_telemetry=0,cutofftime=0,indtest=0,badgyro=0,permission_time=0,countdown_time=0,last_cuttest=0; uint16_t sentence_counter=0; uint8_t silab; //Cutdown config stuff here, atm uses hardcoded polygon defined in polygon.h static const int32_t Geofence[UK_GEOFENCE_POINTS*2]=UK_GEOFENCE; RTC_t RTC_time; _REENT_INIT_PTR(&my_reent); _impure_ptr = &my_reent; SystemInit(); //Sets up the clk setup_gpio(); //Initialised pins, and detects boot source DBGMCU_Config(DBGMCU_IWDG_STOP, ENABLE); //Watchdog stopped during JTAG halt RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);/* Enable PWR and BKP clocks */ PWR_BackupAccessCmd(ENABLE);/* Allow access to BKP Domain */ uint16_t shutdown_lock=BKP_ReadBackupRegister(BKP_DR3); //Holds the shutdown lock setting uint16_t reset_counter=BKP_ReadBackupRegister(BKP_DR2); //The number of consecutive failed reboot cycles PWR_BackupAccessCmd(DISABLE); if(RCC->CSR&RCC_CSR_IWDGRSTF && shutdown_lock!=SHUTDOWNLOCK_MAGIC) {//Watchdog reset, turn off RCC->CSR|=RCC_CSR_RMVF; //Reset the reset flags shutdown(); } if(USB_SOURCE==bootsource) { RCC->CFGR &= ~(uint32_t)RCC_CFGR_PPRE1_DIV16; RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV4;//Swap the ABP1 bus to run at 12mhz rather than 4 if we booted from USB, makes USB fast enough } SysTick_Configuration(); //Start up system timer at 100Hz for uSD card functionality Watchdog_Config(WATCHDOG_TIMEOUT); //Set the watchdog Watchdog_Reset(); //Reset watchdog as soon as possible incase it is still running at power on rtc_init(); //Real time clock initialise - (keeps time unchanged if set) Usarts_Init(); ISR_Config(); rprintfInit(__usart_send_char); //Printf over the bluetooth if(USB_SOURCE==bootsource) { Set_System(); //This actually just inits the storage layer Set_USBClock(); USB_Interrupts_Config(); USB_Init(); uint32_t nojack=0x000FFFFF; //Countdown timer - a few hundered ms of 0v on jack detect forces a shutdown while (bDeviceState != CONFIGURED) { //Wait for USB config - timeout causes shutdown if((Millis>10000 && bDeviceState == UNCONNECTED)|| !nojack) //No USB cable - shutdown (Charger pin will be set to open drain, cant be disabled without usb) shutdown(); if(GET_VBUS_STATE) //Jack detect resets the countdown nojack=0x0FFFFF; nojack--; Watchdog_Reset(); //Reset watchdog here, if we are stalled here the Millis timeout should catch us } PWR_BackupAccessCmd(ENABLE); /* Allow access to BKP Domain */ BKP_WriteBackupRegister(BKP_DR3,0x0000);//Wipe the shutdown lock setting PWR_BackupAccessCmd(DISABLE); while(1) { if(!(Millis%1000) && bDeviceState == SUSPENDED) { Delay(100); if(!GET_VBUS_STATE) shutdown(); } Watchdog_Reset(); __WFI(); //Sleep mode } } if(!GET_PWR_STATE && !(CoreDebug->DHCSR&0x00000001) && shutdown_lock!=SHUTDOWNLOCK_MAGIC) {//Check here to make sure the power button is still pressed, if not, sleep if no debug and not in always on flight mode shutdown(); //This means a glitch on the supply line, or a power glitch results in sleep } // check to see if battery has enough charge to start ADC_Configuration(); //We leave this a bit later to allow stabilisation { uint32_t t=Millis; while(Millis<(t+100)){__WFI();} //Sensor+inst amplifier takes about 100ms to stabilise after power on } if(Battery_Voltage<BATTERY_STARTUP_LIMIT) { //We will have to turn off if(reset_counter<10) shutdown(); } Watchdog_Reset(); //Card Init can take a second or two // system has passed battery level check and so file can be opened {//Context uint8_t silabs_header[5]={}; uint8_t* silabs_header_=NULL; //Pointer to the array (if all goes ok) if((f_err_code = f_mount(0, &FATFS_Obj)))Usart_Send_Str((char*)"FatFs mount error\r\n");//This should only error if internal error else { //FATFS initialised ok, try init the card, this also sets up the SPI1 if(!(f_err_code=f_open(&FATFS_logfile,(const TCHAR*)"time.txt",FA_OPEN_EXISTING|FA_READ|FA_WRITE))){//Try to open time file get system time if(!f_stat((const TCHAR *)"time.txt",&FATFS_info)) {//Get file info if(FATFS_info.fsize<5) { //Empty file RTC_time.year=(FATFS_info.fdate>>9)+1980;//populate the time struct (FAT start==1980, RTC.year==0) RTC_time.month=(FATFS_info.fdate>>5)&0x000F; RTC_time.mday=FATFS_info.fdate&0x001F; RTC_time.hour=(FATFS_info.ftime>>11)&0x001F; RTC_time.min=(FATFS_info.ftime>>5)&0x003F; RTC_time.sec=(FATFS_info.ftime<<1)&0x003E; rtc_settime(&RTC_time); rprintfInit(__fat_print_char);//printf to the open file printf("RTC set to %d/%d/%d %d:%d:%d\n",RTC_time.mday,RTC_time.month,RTC_time.year,\ RTC_time.hour,RTC_time.min,RTC_time.sec); } } f_close(&FATFS_logfile); //Close the time.txt file } // load settings if file exists Watchdog_Reset(); //Card Init can take a second or two if(!f_open(&FATFS_logfile,(const TCHAR *)"settings.dat",FA_OPEN_EXISTING | FA_READ)) { UINT br; int8_t rtc_correction; f_read(&FATFS_logfile, (void*)(&rtc_correction),sizeof(rtc_correction),&br); //Use the setting to apply correction to the RTC if(br && (rtc_correction<30) && (rtc_correction>-92) && rtc_correction ) { PWR_BackupAccessCmd(ENABLE);/* Allow access to BKP Domain */ uint16_t tweaked_prescale = (0x0001<<15)-2;/* Try to run the RTC slightly too fast so it can be corrected either way */ RTC_WaitForSynchro(); /* Wait for RTC registers synchronization */ if( RTC->PRLL != tweaked_prescale ) {/*Note that there is a 0.5ppm offset here (correction 0==0.5ppm slow)*/ RTC_SetPrescaler(tweaked_prescale); /* RTC period = RTCCLK/RTC_PR = (32.768 KHz)/(32767-2+1) */ RTC_WaitForLastTask(); } BKP_SetRTCCalibrationValue((uint8_t) ((int16_t)31-(21*(int16_t)rtc_correction)/(int16_t)20) ); BKP_RTCOutputConfig(BKP_RTCOutputSource_None);/* Ensure any output is disabled here */ /* Lock access to BKP Domain */ PWR_BackupAccessCmd(DISABLE); } else if(br && ((uint8_t)rtc_correction==0x91) ) {/* 0x91 magic flag sets the RTC clock output on */ PWR_BackupAccessCmd(ENABLE);/* Allow access to BKP Domain */ BKP_RTCOutputConfig(BKP_RTCOutputSource_CalibClock);/* Output a 512Hz reference clock on the TAMPER pin*/ PWR_BackupAccessCmd(DISABLE); } if(br) { f_read(&FATFS_logfile, (void*)(&shutdown_lock),sizeof(shutdown_lock),&br);/*This needs to be set with the same magic flag value*/ if(br==2) { PWR_BackupAccessCmd(ENABLE);/* Allow access to BKP Domain */ BKP_WriteBackupRegister(BKP_DR3,shutdown_lock);//Wipe the shutdown lock setting PWR_BackupAccessCmd(DISABLE); } } if(br==2) { //Read was successful, next try to read 5 bytes of packet header f_read(&FATFS_logfile, (void*)(silabs_header),5,&br); if(br!=5) silabs_header_=silabs_header; } f_close(&FATFS_logfile); //Close the settings.dat file } #ifndef SINGLE_LOGFILE rtc_gettime(&RTC_time); //Get the RTC time and put a timestamp on the start of the file rprintfInit(__str_print_char); //Print to the string printf("%02d-%02d-%02dT%02d-%02d-%02d-%s.csv",RTC_time.year,RTC_time.month,RTC_time.mday,RTC_time.hour,RTC_time.min,RTC_time.sec,"Log");//Timestamp name rprintfInit(__usart_send_char); //Printf over the bluetooth #endif Watchdog_Reset(); //Card Init can take a second or two if((f_err_code=f_open(&FATFS_logfile,(TCHAR*)LOGFILE_NAME,FA_CREATE_ALWAYS | FA_WRITE))) {//Present Delay(10000); if((f_err_code=f_open(&FATFS_logfile,(TCHAR*)LOGFILE_NAME,FA_CREATE_ALWAYS | FA_WRITE))) {//Try again printf("FatFs drive error %d\r\n",f_err_code); if(f_err_code==FR_DISK_ERR || f_err_code==FR_NOT_READY) Usart_Send_Str((char*)"No uSD card inserted?\r\n"); } } else { Watchdog_Reset(); //Card Init can take a second or two print_string[strlen(print_string)-4]=0x00;//Wipe the .csv off the string strcat(print_string,"_gyro.wav"); if((f_err_code=f_open(&FATFS_wavfile_gyro,(TCHAR*)LOGFILE_NAME,FA_CREATE_ALWAYS | FA_WRITE))) {//Present printf("FatFs drive error %d\r\n",f_err_code); if(f_err_code==FR_DISK_ERR || f_err_code==FR_NOT_READY) Usart_Send_Str((char*)"No uSD card inserted?\r\n"); } else { //We have a mounted card f_err_code=f_lseek(&FATFS_logfile, PRE_SIZE);// Pre-allocate clusters if (f_err_code || f_tell(&FATFS_logfile) != PRE_SIZE)// Check if the file size has been increased correctly Usart_Send_Str((char*)"Pre-Allocation error\r\n"); else { if((f_err_code=f_lseek(&FATFS_logfile, 0)))//Seek back to start of file to start writing Usart_Send_Str((char*)"Seek error\r\n"); else rprintfInit(__str_print_char);//Printf to the logfile } if(f_err_code) f_close(&FATFS_logfile);//Close the already opened file on error else file_opened=1; //So we know to close the file properly on shutdown if(file_opened==1) { Watchdog_Reset(); //Card Init can take a second or two if (f_err_code || f_tell(&FATFS_wavfile_gyro) != PRE_SIZE)// Check if the file size has been increased correctly Usart_Send_Str((char*)"Pre-Allocation error\r\n"); else { if((f_err_code=f_lseek(&FATFS_logfile, 0)))//Seek back to start of file to start writing Usart_Send_Str((char*)"Seek error\r\n"); else rprintfInit(__str_print_char);//Printf to the logfile } if(f_err_code) f_close(&FATFS_wavfile_gyro);//Close the already opened file on error else file_opened|=2; //So we know to close the file properly on shutdown } } } } f_err_code|=write_wave_header(&FATFS_wavfile_gyro, 4, 100, 16);//4 channels, last channel is for the current rpm Watchdog_Reset(); //Card Init can take a second or two //Setup and test the silabs radio silab=si446x_setup(silabs_header_); if(silab!=0x44) { //Should return the device code print_string[0]=0x00; printf("Silabs: %02x\n",silab); f_puts("Silabs detect error, got:",&FATFS_logfile); f_puts(print_string,&FATFS_logfile); shutdown_filesystem(ERR, file_opened);//So we log that something went wrong in the logfile shutdown(); } }//Context
int main(void) { uint32_t data_counter=0; //used as data timestamp uint8_t deadly_flashes=0,system_state=0,repetition_counter=0; int16_t sensor_data, sensor_raw_data[3]={}; //used for handling data passed back from sensors int16_t sfe_sensor_ref_buff[2][3],sfe_sensor_ref_buff_old[2][3];//used to detect and fix I2C bus lockup RTC_t RTC_time; wave_stuffer Gyro_wav_stuffer={0,0},Accel_wav_stuffer={0,0};//Used to controlling wav file bit packing SystemInit(); //Sets up the clk setup_gpio(); //Initialised pins, and detects boot source DBGMCU_Config(DBGMCU_IWDG_STOP, ENABLE); //Watchdog stopped during JTAG halt if(RCC->CSR&RCC_CSR_IWDGRSTF) { //Watchdog reset, turn off RCC->CSR|=RCC_CSR_RMVF; //Reset the reset flags shutdown(); } SysTick_Configuration(); //Start up system timer at 100Hz for uSD card functionality Watchdog_Config(WATCHDOG_TIMEOUT); //Set the watchdog Watchdog_Reset(); //Reset watchdog as soon as possible incase it is still running at power on rtc_init(); //Real time clock initialise - (keeps time unchanged if set) Usarts_Init(); ISR_Config(); rprintfInit(__usart_send_char); //Printf over the bluetooth if(USB_SOURCE==bootsource) { Set_System(); //This actually just inits the storage layer Set_USBClock(); USB_Interrupts_Config(); USB_Init(); uint32_t nojack=0x000FFFFF; //Countdown timer - a few hundered ms of 0v on jack detect forces a shutdown while (bDeviceState != CONFIGURED) { //Wait for USB config - timeout causes shutdown if(Millis>10000 || !nojack) //No USB cable - shutdown (Charger pin will be set to open drain, cant be disabled without usb) shutdown(); if(GET_CHRG_STATE) //Jack detect resets the countdown nojack=0x0FFFFF; nojack--; Watchdog_Reset(); //Reset watchdog here, if we are stalled here the Millis timeout should catch us } USB_Configured_LED(); EXTI_ONOFF_EN(); //Enable the off interrupt - allow some time for debouncing while(1) { //If running off USB (mounted as mass storage), stay in this loop - dont turn on anything if(Millis%1000>500) //1Hz on/off flashing switch_leds_on(); //Flash the LED(s) else switch_leds_off(); Watchdog_Reset(); __WFI(); //Sleep until something arrives } } else { if(!GET_PWR_STATE) //Check here to make sure the power button is still pressed, if not, sleep shutdown(); //This means a glitch on the supply line, or a power glitch results in sleep EXTI_ONOFF_EN(); //Enable the off interrupt - allow some time for debouncing ADC_Configuration(); //At present this is purely here to detect low battery do { battery_voltage=Battery_Voltage;//Have to flush adc for some reason Delay(25000); } while(fabs(Battery_Voltage-battery_voltage)>0.01 || !battery_voltage); I2C_Config(); //Setup the I2C bus Sensors=detect_sensors(0); //Search for connected sensors if(battery_voltage<BATTERY_STARTUP_LIMIT) deadly_flashes=1; if(!(Sensors&(1<<FOREHEAD_ACCEL))) //Check for any missing sensors deadly_flashes=2; if(!(Sensors&(1<<(FOREHEAD_GYRO-1)))) deadly_flashes=3; if(!(Sensors&(1<<(SFE_1_ACCEL-1)))) deadly_flashes=4; if(!(Sensors&(1<<(SFE_1_MAGNO-1)))) deadly_flashes=5; if(!(Sensors&(1<<(SFE_1_GYRO-1)))) deadly_flashes=6; if(!(Sensors&(1<<(SFE_2_ACCEL-3)))) deadly_flashes=7; if(!(Sensors&(1<<(SFE_2_MAGNO-3)))) deadly_flashes=8; if(!(Sensors&(1<<(SFE_2_GYRO-3)))) deadly_flashes=9; if((f_err_code = f_mount(0, &FATFS_Obj)))Usart_Send_Str((char*)"FatFs mount error\r\n");//This should only error if internal error else if(!deadly_flashes){ //FATFS and the I2C initialised ok, try init the card, this also sets up the SPI1 if(!f_open(&FATFS_logfile,"time.txt",FA_OPEN_EXISTING | FA_READ | FA_WRITE)) {//Try and open a time file to get the system time if(!f_stat((const TCHAR *)"time.txt",&FATFS_info)) {//Get file info if(!FATFS_info.fsize) {//Empty file RTC_time.year=(FATFS_info.fdate>>9)+1980;//populate the time struct (FAT start==1980, RTC.year==0) RTC_time.month=(FATFS_info.fdate>>5)&0x000F; RTC_time.mday=FATFS_info.fdate&0x001F; RTC_time.hour=(FATFS_info.ftime>>11)&0x001F; RTC_time.min=(FATFS_info.ftime>>5)&0x003F; RTC_time.sec=(FATFS_info.ftime<<1)&0x003E; rtc_settime(&RTC_time); rprintfInit(__fat_print_char);//printf to the open file printf("RTC set to %d/%d/%d %d:%d:%d\n",RTC_time.mday,RTC_time.month,RTC_time.year,\ RTC_time.hour,RTC_time.min,RTC_time.sec); } } f_close(&FATFS_logfile);//Close the time.txt file } rtc_gettime(&RTC_time); //Get the RTC time and put a timestamp on the start of the file rprintfInit(__str_print_char); //Print to the string //timestamp name printf("%d-%02d-%02dT%02d-%02d-%02d",RTC_time.year,RTC_time.month,RTC_time.mday,RTC_time.hour,RTC_time.min,RTC_time.sec); rprintfInit(__usart_send_char); //Printf over the bluetooth f_err_code = f_mkdir(print_string); //Try to make a directory where the logfiles will live if(f_err_code) { printf("FatFs drive error %d\r\n",f_err_code); if(f_err_code==FR_DISK_ERR || f_err_code==FR_NOT_READY) Usart_Send_Str((char*)"No uSD card inserted?\r\n"); repetition_counter=1; } else f_err_code=f_chdir(print_string);//enter our new directory if(f_err_code) { if(!repetition_counter) printf("FatFs drive error entering direcotry %d\r\n",f_err_code); repetition_counter=1; } else { strcat(print_string,".csv"); f_err_code=f_open(&FATFS_logfile,print_string,FA_CREATE_ALWAYS | FA_WRITE);//Try to open the main 100sps csv logfile } if(f_err_code) { if(!repetition_counter) printf("FatFs drive error creating logfile %d\r\n",f_err_code); repetition_counter=1; } else { print_string[strlen(print_string)-4]=0x00; //Wipe the .csv off the string strcat(print_string,"_accel.wav"); f_err_code=f_open(&FATFS_wavfile_accel,print_string,FA_CREATE_ALWAYS | FA_WRITE);//Try to open the accel wav logfile } if(f_err_code) { if(!repetition_counter) printf("FatFs drive error creating accel wav file %d\r\n",f_err_code); repetition_counter=1; } else { print_string[strlen(print_string)-9]=0x00; //Wipe the accel.wav off the string strcat(print_string,"gyro.wav"); f_err_code=f_open(&FATFS_wavfile_gyro,print_string,FA_CREATE_ALWAYS | FA_WRITE);//Try to open the gyro wav logfile } if(f_err_code) { if(!repetition_counter) printf("FatFs drive error creating gyro wav file %d\r\n",f_err_code); } else { //We have a mounted card print_string[0]=0x00; //Wipe the string f_err_code=f_lseek(&FATFS_logfile, PRE_SIZE);// Pre-allocate clusters if (f_err_code || f_tell(&FATFS_logfile) != PRE_SIZE)// Check if the file size has been increased correctly Usart_Send_Str((char*)"Pre-Allocation error\r\n"); else { if((f_err_code=f_lseek(&FATFS_logfile, 0)))//Seek back to start of file to start writing Usart_Send_Str((char*)"Seek error\r\n"); else rprintfInit(__str_print_char);//Printf to the logfile } if(f_err_code) f_close(&FATFS_logfile);//Close the already opened file on error else file_opened=0x01;//So we know to close the file properly on shutdown - bit mask for the files if(!f_err_code) { f_err_code=f_lseek(&FATFS_wavfile_accel, PRE_SIZE);// Pre-allocate clusters if (f_err_code || f_tell(&FATFS_wavfile_accel) != PRE_SIZE)// Check if the file size has been increased correctly Usart_Send_Str((char*)"Pre-Allocation error\r\n"); else { if((f_err_code=f_lseek(&FATFS_wavfile_accel, 0)))//Seek back to start of file to start writing Usart_Send_Str((char*)"Seek error\r\n"); } if(f_err_code) f_close(&FATFS_wavfile_accel);//Close the already opened file on error else file_opened|=0x02;//So we know to close the file properly on shutdown - bit mask for the files } if(!f_err_code) { f_err_code=f_lseek(&FATFS_wavfile_gyro, PRE_SIZE);// Pre-allocate clusters if (f_err_code || f_tell(&FATFS_wavfile_gyro) != PRE_SIZE)// Check if the file size has been increased correctly Usart_Send_Str((char*)"Pre-Allocation error\r\n"); else { if((f_err_code=f_lseek(&FATFS_wavfile_gyro, 0)))//Seek back to start of file to start writing Usart_Send_Str((char*)"Seek error\r\n"); } if(f_err_code) f_close(&FATFS_wavfile_gyro);//Close the already opened file on error else file_opened|=0x04;//So we know to close the file properly on shutdown - bit mask for the files } } } repetition_counter=0; //Reset this here //We die, but flash out a number of flashes first if(f_err_code || deadly_flashes) { //There was an init error for(;deadly_flashes;deadly_flashes--) { RED_LED_ON; Delay(200000); RED_LED_OFF; Delay(200000); Watchdog_Reset(); } RED_LED_ON; Delay(400000); shutdown(); //Abort after a (further )single red flash } }
/** * provide all parameters to init the function and find the first gap. * set all parameters to NULL (for reference parameters) or 0 (for value parameters) to find the subsequent gaps * * @returns pointer to a uint32_t containing the sequence number of a missing log entry * NULL when no gap is found */ const uint32_t* LogEngine_FindGap(gap_search_query_t* arguments, boolbitarray_t* buffer, const uint16_t bufferSize) { if (arguments != NULL) { // if the buffer is too small for the request debug waring should be generated and NULL should be returned (as for no gaps found) uint32_t maximalLength = bufferSize << 3; // each byte in the buffer stores 8 bool values uint32_t requestedLength = arguments->Request.LastSeqNo - arguments->Request.FirstSeqNo + 1; if (requestedLength > maximalLength) { LOGERR("[LogEngine_FindGap] The selected range (%lu) of sequence numbers is too large (max. %lu)!", requestedLength, maximalLength); return NULL; } _LogEngine_FindGap_LastQueriedRemoteSequenceNo = arguments->Request.LastSeqNo; _LogEngine_FindGap_CurrentQueriedRemoteSequenceNo = arguments->Request.FirstSeqNo; if (_LogEngine_FindGap_Buffer != NULL) { // there is something in the buffer, try to reuse it now // 1. check boundaries -> if violated, force a refresh // 2. check targetnodeid if ( arguments->Request.FirstSeqNo < _LogEngine_FindGap_FirstCachedRemoteSequenceNo || arguments->Request.LastSeqNo > _LogEngine_FindGap_LastCachedRemoteSequenceNo || arguments->Request.TargetNodeId != _LogEngine_FindGap_CachedTargetNodeId ) { _LogEngine_FindGap_Buffer = NULL; } } // there is no buffer that could be reused, in such case, the function needs to be initialized if (_LogEngine_FindGap_Buffer == NULL) { _LogEngine_FindGap_LastCachedRemoteSequenceNo = arguments->Request.FirstSeqNo + maximalLength - 1; _LogEngine_FindGap_FirstCachedRemoteSequenceNo = arguments->Request.FirstSeqNo; _LogEngine_FindGap_CachedTargetNodeId = arguments->Request.TargetNodeId; _LogEngine_FindGap_Buffer = buffer; memset(buffer, 0, bufferSize); uint32_t logSize = LogEngine_GetLogSize(); // scan the entire selected area from the local memory and put information about data availability in the buffer // the selected are starts at the localSeqNo provided and ends at the end of the buffer uint32_t currentLocalSeqNo; for(currentLocalSeqNo = arguments->Request.LocalSeqNo; currentLocalSeqNo <= logSize; currentLocalSeqNo++) { // reset the watchdog - this is a long running operation Watchdog_Reset(); // load the entry logentry_t entry; LogEngine_Read(¤tLocalSeqNo, &entry); // skip invalid entries and process only entries that are relevant for the query if ( entry.Preamble != LOG_ENTRY_PREAMBLE || entry.HostNodeId != _LogEngine_FindGap_CachedTargetNodeId || entry.HostSequenceNo < _LogEngine_FindGap_FirstCachedRemoteSequenceNo || entry.HostSequenceNo > _LogEngine_FindGap_LastCachedRemoteSequenceNo ) continue; // a valid entry was found (such that matches the query and is in the selected data range // now, information about it's presence should be stored in the buffer // prepare the index of this entry uint32_t index = entry.HostSequenceNo - arguments->Request.FirstSeqNo; BoolBitArray_Set(buffer, &index); } } // init code end } else { // this is a subsequent call to find the next gap. the gap found during the previous call was reported so the counter needs to be incremented _LogEngine_FindGap_CurrentQueriedRemoteSequenceNo++; } // now, the memory was scanned, and the buffer should be used to investigate whether certain log entries are available // _LogEngine_FindGap_CurrentRemoteSequenceNo is not initialized here on purpose. // it is stored and reused accross sequential calls to this function. for (; _LogEngine_FindGap_CurrentQueriedRemoteSequenceNo <= _LogEngine_FindGap_LastQueriedRemoteSequenceNo; _LogEngine_FindGap_CurrentQueriedRemoteSequenceNo++) { uint32_t index = _LogEngine_FindGap_CurrentQueriedRemoteSequenceNo - _LogEngine_FindGap_FirstCachedRemoteSequenceNo; if (BoolBitArray_Get(_LogEngine_FindGap_Buffer, &index)) continue; // the entry with the requested sequence number was marked ad available in the buffer return &_LogEngine_FindGap_CurrentQueriedRemoteSequenceNo; } // if this line was reached, no (more) gaps were found return NULL; }
int main(void) { uint32_t ppg; //PPG channel uint32_t data_counter=0; //used as data timestamp uint8_t system_state=0; //used to track button press functionality float sensor_data; //used for handling data passed back from sensors RTC_t RTC_time; _REENT_INIT_PTR(&my_reent); _impure_ptr = &my_reent; SystemInit(); //Sets up the clk setup_gpio(); //Initialised pins, and detects boot source DBGMCU_Config(DBGMCU_IWDG_STOP, ENABLE); //Watchdog stopped during JTAG halt if(RCC->CSR&RCC_CSR_IWDGRSTF) { //Watchdog reset, turn off RCC->CSR|=RCC_CSR_RMVF; //Reset the reset flags shutdown(); } SysTick_Configuration(); //Start up system timer at 100Hz for uSD card functionality Watchdog_Config(WATCHDOG_TIMEOUT); //Set the watchdog Watchdog_Reset(); //Reset watchdog as soon as possible incase it is still running at power on rtc_init(); //Real time clock initialise - (keeps time unchanged if set) Usarts_Init(); ISR_Config(); rprintfInit(__usart_send_char); //Printf over the bluetooth if(USB_SOURCE==bootsource) { Set_System(); //This actually just inits the storage layer Set_USBClock(); USB_Interrupts_Config(); USB_Init(); uint32_t nojack=0x000FFFFF; //Countdown timer - a few hundered ms of 0v on jack detect forces a shutdown while (bDeviceState != CONFIGURED) { //Wait for USB config - timeout causes shutdown if(Millis>10000 || !nojack) //No USB cable - shutdown (Charger pin will be set to open drain, cant be disabled without usb) shutdown(); if(GET_VBUS_STATE) //Jack detect resets the countdown nojack=0x0FFFFF; nojack--; Watchdog_Reset(); //Reset watchdog here, if we are stalled here the Millis timeout should catch us } USB_Configured_LED(); EXTI_ONOFF_EN(); //Enable the off interrupt - allow some time for debouncing while(1) { //If running off USB (mounted as mass storage), stay in this loop - dont turn on anything if(Millis%1000>500) //1Hz on/off flashing switch_leds_on(); //Flash the LED(s) else switch_leds_off(); Watchdog_Reset(); } } if(!GET_PWR_STATE) //Check here to make sure the power button is still pressed, if not, sleep shutdown(); //This means a glitch on the supply line, or a power glitch results in sleep for(uint8_t n=0;n<PPG_CHANNELS;n++) init_buffer(&(Buff[n]),PPG_BUFFER_SIZE);//Enough for ~0.25S of data setup_pwm(); //Enable the PWM outputs on all three channels Delay(100000); //Sensor+inst amplifier takes about 100ms to stabilise after power on ADC_Configuration(); //We leave this a bit later to allow stabilisation calibrate_sensor(); //Calibrate the offset on the diff pressure sensor EXTI_ONOFF_EN(); //Enable the off interrupt - allow some time for debouncing I2C_Config(); //Setup the I2C bus uint8_t sensors_=detect_sensors(); //Search for connected sensors sensor_data=GET_BATTERY_VOLTAGE; //Have to flush adc for some reason Delay(10000); if(!(sensors_&~(1<<PRESSURE_HOSE))||GET_BATTERY_VOLTAGE<BATTERY_STARTUP_LIMIT) {//We will have to turn off Watchdog_Reset(); //LED flashing takes a while if(abs(Reported_Pressure)>PRESSURE_MARGIN) Set_Motor(-1); //If the is air backpressure, dump to rapidly drop to zero pressure before turnoff if(file_opened) f_close(&FATFS_logfile); //be sure to terminate file neatly red_flash(); Delay(400000); red_flash(); //Two flashes means battery abort -----------------ABORT 2 if(sensors_&~(1<<PRESSURE_HOSE)) shutdown(); Delay(400000); red_flash(); //Three flashes means no sensors abort ------------ABORT 3 shutdown(); } if((f_err_code = f_mount(0, &FATFS_Obj)))Usart_Send_Str((char*)"FatFs mount error\r\n");//This should only error if internal error else { //FATFS initialised ok, try init the card, this also sets up the SPI1 if(!f_open(&FATFS_logfile,"time.txt",FA_OPEN_EXISTING | FA_READ | FA_WRITE)) {//Try and open a time file to get the system time if(!f_stat((const TCHAR *)"time.txt",&FATFS_info)) {//Get file info if(!FATFS_info.fsize) { //Empty file RTC_time.year=(FATFS_info.fdate>>9)+1980;//populate the time struct (FAT start==1980, RTC.year==0) RTC_time.month=(FATFS_info.fdate>>5)&0x000F; RTC_time.mday=FATFS_info.fdate&0x001F; RTC_time.hour=(FATFS_info.ftime>>11)&0x001F; RTC_time.min=(FATFS_info.ftime>>5)&0x003F; RTC_time.sec=(FATFS_info.ftime<<1)&0x003E; rtc_settime(&RTC_time); rprintfInit(__fat_print_char);//printf to the open file printf("RTC set to %d/%d/%d %d:%d:%d\n",RTC_time.mday,RTC_time.month,RTC_time.year,\ RTC_time.hour,RTC_time.min,RTC_time.sec); } } f_close(&FATFS_logfile); //Close the time.txt file } #ifndef SINGLE_LOGFILE rtc_gettime(&RTC_time); //Get the RTC time and put a timestamp on the start of the file rprintfInit(__str_print_char); //Print to the string printf("%d-%d-%dT%d-%d-%d.txt",RTC_time.year,RTC_time.month,RTC_time.mday,RTC_time.hour,RTC_time.min,RTC_time.sec);//Timestamp name rprintfInit(__usart_send_char); //Printf over the bluetooth #endif if((f_err_code=f_open(&FATFS_logfile,LOGFILE_NAME,FA_CREATE_ALWAYS | FA_WRITE))) {//Present printf("FatFs drive error %d\r\n",f_err_code); if(f_err_code==FR_DISK_ERR || f_err_code==FR_NOT_READY) Usart_Send_Str((char*)"No uSD card inserted?\r\n"); } else { //We have a mounted card f_err_code=f_lseek(&FATFS_logfile, PRE_SIZE);// Pre-allocate clusters if (f_err_code || f_tell(&FATFS_logfile) != PRE_SIZE)// Check if the file size has been increased correctly Usart_Send_Str((char*)"Pre-Allocation error\r\n"); else { if((f_err_code=f_lseek(&FATFS_logfile, 0)))//Seek back to start of file to start writing Usart_Send_Str((char*)"Seek error\r\n"); else rprintfInit(__str_print_char);//Printf to the logfile } if(f_err_code) f_close(&FATFS_logfile);//Close the already opened file on error else file_opened=1; //So we know to close the file properly on shutdown } }
uint_8 SD_Init(void) { #ifdef MCU_MKL25Z4 SPI_Init(); /* SPI Initialization */ SD_CLKDelay(10); /* Send 80 clocks */ SPI_clr_SS() ; gu8SD_Argument.lword = 0; SPI_set_SS(); SD_CLKDelay(8); /* IDLE Command */ SPI_set_SS(); if(SD_SendCommand(SD_CMD0|0x40,SD_IDLE)) { SPI_clr_SS(); return(FALSE); /* Command IDLE fail */ } SPI_clr_SS(); (void)SPI_Receive_byte(); /* Dummy SPI cycle */ /* Initialize SD Command */ SPI_set_SS(); while(SD_SendCommand(SD_CMD1|0x40,SD_OK)) { Watchdog_Reset(); } SPI_clr_SS() ; (void)SPI_Receive_byte(); /* Dummy SPI cycle */ /* Block Length */ gu8SD_Argument.lword = BYTESWAP32(SD_BLOCK_SIZE); SPI_set_SS(); if(SD_SendCommand(SD_CMD16|0x40,SD_OK)) { SPI_clr_SS() ; return(FALSE); /* Command IDLE fail */ } SPI_clr_SS() ; SPI_High_rate(); SPI_Send_byte(0x00); SPI_Send_byte(0x00); return(TRUE); #else /*Body*/ SPI_Init(); /* SPI Initialization*/ SD_CLKDelay(10); /* Send 80 clocks*/ gu8SD_Argument.lword = 0; SD_CLKDelay(8); /* IDLE Command */ if(SD_SendCommand(SD_CMD0|0x40,SD_IDLE)) { return(FALSE); /* Command IDLE fail*/ }/*Endif*/ (void)SPI_Receive_byte(); /* Dummy SPI cycle*/ /* Initialize SD Command */ while(SD_SendCommand(SD_CMD1|0x40,SD_OK)) { Watchdog_Reset(); }/*EndWhile*/ (void)SPI_Receive_byte(); /*Dummy SPI cycle */ /* Block Length */ gu8SD_Argument.lword = BYTESWAP32(SD_BLOCK_SIZE); if(SD_SendCommand(SD_CMD16|0x40,SD_OK)) { return(FALSE); /* Command IDLE fail */ }/*Endif*/ SPI_High_rate(); SPI_Send_byte(0x00); SPI_Send_byte(0x00); return(TRUE); #endif }/*End Body*/
void SD_Write_Block(PTR_LBA_APP_STRUCT lba_data_ptr) { #ifdef MCU_MKL25Z4 uint_32 u32Counter; SPI_set_SS(); gu8SD_Argument.lword = BYTESWAP32(lba_data_ptr->offset); if(SD_SendCommand(SD_CMD24|0x40,SD_OK)) { SPI_clr_SS() ; return; /* Command IDLE fail */ } SPI_Send_byte(0xFE); for(u32Counter=0;u32Counter<lba_data_ptr->size;u32Counter++) { SPI_Send_byte(*(lba_data_ptr->buff_ptr + u32Counter)); } SPI_Send_byte(0xFF); /* checksum Bytes not needed */ SPI_Send_byte(0xFF); if((SPI_Receive_byte() & 0x0F) != 0x05) { SPI_clr_SS() ; return; /* Command fail */ } while(SPI_Receive_byte()==0x00) { Watchdog_Reset(); /* Dummy SPI cycle */ } SPI_clr_SS() ; return; #else /* Body */ uint_32 u32Counter, time_out; gu8SD_Argument.lword = BYTESWAP32(lba_data_ptr->offset); if(SD_SendCommand(SD_CMD24|0x40,SD_OK)) { return; /* Command IDLE fail */ } /* EndIf */ SPI_Send_byte(0xFE); for(u32Counter=0;u32Counter<lba_data_ptr->size;u32Counter++) { SPI_Send_byte(*(lba_data_ptr->buff_ptr + u32Counter)); } /* EndFor */ SPI_Send_byte(0xFF); /* checksum Bytes not needed */ SPI_Send_byte(0xFF); for (time_out=0;time_out<1000;time_out++) { if((SPI_Receive_byte() & 0x1F) < 16) { break; } /* EndIf */ }/* EndFor */ if (time_out>=1000) return; while(SPI_Receive_byte()==0x00) { Watchdog_Reset(); } /* EndWhile */ return; #endif }
void setup() { int logNo; char configLineBuffer[LINE_BUFFER_MAX]; spi.begin(SPI_281_250KHZ, MSBFIRST, 0); pinMode(GRN_LED,OUTPUT); pinMode(ORN_LED,OUTPUT); pinMode(RED_LED,OUTPUT); digitalWrite(GRN_LED,HIGH); digitalWrite(ORN_LED,LOW); digitalWrite(RED_LED,LOW); iwdg_init(IWDG_PRE_256, WATCHDOG_TIMEOUT); Watchdog_Reset(); if (!card.init(&spi)) { //if (!card.init()) { console.printf("FTL: card.init failed"); } delay(100); // initialize a FAT volume if (!volume.init(&card)) { console.printf("FTL: volume.init failed"); } // open the root directory if (!root.openRoot(&volume)) ;//SerialUSB.println("FTL: openRoot failed"); for (logNo=0; (!logOpened) && logNo<512; logNo++) { Watchdog_Reset(); //int snprintf(char *str, size_t size, const char *format, ...); snprintf(logFileName,15,"LOG%03d.TXT",logNo); if (file.open(&root, logFileName, O_READ)) { //SerialUSB.print("DBG: Exists :"); SerialUSB.println(logFileName); file.close(); } else if (file.open(&root, logFileName, O_CREAT|O_READ|O_WRITE)) { //SerialUSB.print("DBG: New File:"); SerialUSB.println(logFileName); logOpened=true; file.sync(); file.close(); file.open(&root,logFileName,O_WRITE|O_READ); while (file.read(configLineBuffer,LINE_BUFFER_MAX)) { } file.sync(); } } //if (!logOpened) SerialUSB.println("FTL: openRoot failed"); digitalWrite(GRN_LED,LOW); digitalWrite(RED_LED,HIGH); readSettings(); console.printf("LSV:" BOM_VERSION "\r\n"); console.printf("NST: %s\r\n",networkStatus()?"CONNECTED":"NOT CONNECTED"); digitalWrite(ORN_LED,HIGH); digitalWrite(RED_LED,networkStatus()?HIGH:LOW); }