/** * @brief Bootloader Main function */ int main() { uint8_t GO_dfu = false; /* Brings up System using CMSIS functions, enables the LEDs. */ PIOS_SYS_Init(); /* Enable Prefetch Buffer */ FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); /* Flash 2 wait state */ FLASH_SetLatency(FLASH_Latency_2); RCC_AHBPeriphClockCmd(RCC_AHBPeriph_CRC, ENABLE); /* Delay system */ PIOS_DELAY_Init(); for (uint32_t t = 0; t < 10000000; ++t) { if (NSS_HOLD_STATE == 1) GO_dfu = TRUE; else { GO_dfu = FALSE; break; } } //while(TRUE) // { // PIOS_LED_Toggle(LED1); // PIOS_DELAY_WaitmS(1000); // } //GO_dfu = TRUE; PIOS_IAP_Init(); GO_dfu = GO_dfu | PIOS_IAP_CheckRequest();// OR with app boot request if (GO_dfu == FALSE) { jump_to_app(); } if (PIOS_IAP_CheckRequest()) { PIOS_DELAY_WaitmS(1000); PIOS_IAP_ClearRequest(); } PIOS_Board_Init(); boot_status = idle; Fw_crc = PIOS_BL_HELPER_CRC_Memory_Calc(); PIOS_LED_On(LED1); while (1) { process_spi_request(); } return 0; }
/** * Execute the application binary * * \param addr Application start address. * \return If success, no return; * 1 - address alignment error; * 2 - address not executable. */ static uint8_t _app_exec(void *addr) { uint32_t i; /* Check parameters */ if ((uint32_t)addr & 0x7F) { return 1; } if ((uint32_t)addr > CM_SRAM_END) { return 2; } __disable_irq(); /* Disable SysTick */ SysTick->CTRL = 0; /* Disable IRQs & clear pending IRQs */ for (i = 0; i < 8; i++) { NVIC->ICER[i] = 0xFFFFFFFF; NVIC->ICPR[i] = 0xFFFFFFFF; } /* Switch clock to slow RC */ osc_enable(OSC_SLCK_32K_RC); osc_wait_ready(OSC_SLCK_32K_RC); pmc_switch_mck_to_sclk(SYSCLK_PRES_1); /* Switch clock to fast RC */ osc_enable(OSC_MAINCK_12M_RC); osc_wait_ready(OSC_MAINCK_12M_RC); pmc_switch_mck_to_mainck(SYSCLK_PRES_1); /* Modify vector table location */ __DSB(); __ISB(); SCB->VTOR = ((uint32_t)addr & SCB_VTOR_TBLOFF_Msk); __DSB(); __ISB(); __enable_irq(); /* Jump to application */ jump_to_app(addr); /* Never be here */ return 0; }
int main() { PIOS_SYS_Init(); if (BSL_HOLD_STATE == 0) USB_connected = TRUE; PIOS_IAP_Init(); if (PIOS_IAP_CheckRequest() == TRUE) { PIOS_Board_Init(); PIOS_DELAY_WaitmS(1000); User_DFU_request = TRUE; PIOS_IAP_ClearRequest(); } GO_dfu = (USB_connected == TRUE) || (User_DFU_request == TRUE); if (GO_dfu == TRUE) { PIOS_Board_Init(); if (User_DFU_request == TRUE) DeviceState = DFUidle; else DeviceState = BLidle; STOPWATCH_Init(100, LED_PWM_TIMER); } else JumpToApp = TRUE; STOPWATCH_Reset(LED_PWM_TIMER); while (TRUE) { if (JumpToApp == TRUE) jump_to_app(); switch (DeviceState) { case Last_operation_Success: case uploadingStarting: case DFUidle: period1 = 50; sweep_steps1 = 100; PIOS_LED_Off(BLUE); period2 = 0; break; case uploading: period1 = 50; sweep_steps1 = 100; period2 = 25; sweep_steps2 = 50; break; case downloading: period1 = 25; sweep_steps1 = 50; PIOS_LED_Off(BLUE); period2 = 0; break; case BLidle: period1 = 0; PIOS_LED_On(BLUE); period2 = 0; break; default://error period1 = 50; sweep_steps1 = 100; period2 = 50; sweep_steps2 = 100; } if (period1 != 0) { if (LedPWM(period1, sweep_steps1, STOPWATCH_ValueGet(LED_PWM_TIMER))) PIOS_LED_On(BLUE); else PIOS_LED_Off(BLUE); } else PIOS_LED_On(BLUE); if (period2 != 0) { if (LedPWM(period2, sweep_steps2, STOPWATCH_ValueGet(LED_PWM_TIMER))) PIOS_LED_On(BLUE); else PIOS_LED_Off(BLUE); } else PIOS_LED_Off(BLUE); if (STOPWATCH_ValueGet(LED_PWM_TIMER) > 100 * 50 * 100) STOPWATCH_Reset(LED_PWM_TIMER); if ((STOPWATCH_ValueGet(LED_PWM_TIMER) > 60000) && (DeviceState == BLidle)) JumpToApp = TRUE; processRX(); DataDownload(start); } }
int main() { PIOS_SYS_Init(); PIOS_Board_Init(); PIOS_IAP_Init(); USB_connected = PIOS_USB_CheckAvailable(0); if (PIOS_IAP_CheckRequest() == true) { PIOS_DELAY_WaitmS(1000); User_DFU_request = true; PIOS_IAP_ClearRequest(); } GO_dfu = (USB_connected == true) || (User_DFU_request == true); if (GO_dfu == true) { PIOS_Board_Init(); if (User_DFU_request == true) DeviceState = DFUidle; else DeviceState = BLidle; } else JumpToApp = true; uint32_t stopwatch = 0; uint32_t prev_ticks = PIOS_DELAY_GetuS(); while (true) { /* Update the stopwatch */ uint32_t elapsed_ticks = PIOS_DELAY_GetuSSince(prev_ticks); prev_ticks += elapsed_ticks; stopwatch += elapsed_ticks; if (JumpToApp == true) jump_to_app(); switch (DeviceState) { case Last_operation_Success: case uploadingStarting: case DFUidle: period1 = 5000; sweep_steps1 = 100; PIOS_LED_Off(PIOS_LED_HEARTBEAT); period2 = 0; break; case uploading: period1 = 5000; sweep_steps1 = 100; period2 = 2500; sweep_steps2 = 50; break; case downloading: period1 = 2500; sweep_steps1 = 50; PIOS_LED_Off(PIOS_LED_HEARTBEAT); period2 = 0; break; case BLidle: period1 = 0; PIOS_LED_On(PIOS_LED_HEARTBEAT); period2 = 0; break; default://error period1 = 5000; sweep_steps1 = 100; period2 = 5000; sweep_steps2 = 100; } if (period1 != 0) { if (LedPWM(period1, sweep_steps1, stopwatch)) PIOS_LED_On(PIOS_LED_HEARTBEAT); else PIOS_LED_Off(PIOS_LED_HEARTBEAT); } else PIOS_LED_On(PIOS_LED_HEARTBEAT); if (period2 != 0) { if (LedPWM(period2, sweep_steps2, stopwatch)) PIOS_LED_On(PIOS_LED_HEARTBEAT); else PIOS_LED_Off(PIOS_LED_HEARTBEAT); } else PIOS_LED_Off(PIOS_LED_HEARTBEAT); if (stopwatch > 50 * 1000 * 1000) stopwatch = 0; if ((stopwatch > 6 * 1000 * 1000) && (DeviceState == BLidle)) JumpToApp = true; processRX(); DataDownload(start); } }
int main(void) { bool try_boot = true; /* try booting before we drop to the bootloader */ unsigned timeout = BOOTLOADER_DELAY; /* if nonzero, drop out of the bootloader after this time */ /* Enable the FPU before we hit any FP instructions */ SCB_CPACR |= ((3UL << 10*2) | (3UL << 11*2)); /* set CP10 Full Access and set CP11 Full Access */ #if defined(BOARD_VRBRAINV40) || defined(BOARD_VRBRAINV45) if(!board_test_force_pin() && !(board_get_rtc_signature() == BOOT_RTC_SIGNATURE)) { jump_to_app(); } #endif /* do board-specific initialisation */ board_init(); /* * Check the force-bootloader register; if we find the signature there, don't * try booting. */ if (board_get_rtc_signature() == BOOT_RTC_SIGNATURE) { /* * Don't even try to boot before dropping to the bootloader. */ try_boot = false; /* * Don't drop out of the bootloader until something has been uploaded. */ timeout = 0; #if defined(BOARD_VRBRAINV40) || defined(BOARD_VRBRAINV45) // force an erase of the first sector because version 4.x // of the board is not able to reset USB after first boot. // This will force the bootloader to stay until a program has been flashed. flash_unlock(); flash_func_erase_sector(0); flash_lock(); #endif /* * Clear the signature so that if someone resets us while we're * in the bootloader we'll try to boot next time. */ board_set_rtc_signature(0); } #ifdef INTERFACE_USB /* * Check for USB connection - if present, don't try to boot, but set a timeout after * which we will fall out of the bootloader. * * If the force-bootloader pins are tied, we will stay here until they are removed and * we then time out. */ #if defined(BOARD_VRBRAINV40) || defined(BOARD_VRBRAINV45) if (gpio_get(BOARD_PRESENCE_PORT, BOARD_PRESENCE_PIN) != 0 && board_test_force_pin()) { /* don't try booting before we set up the bootloader */ try_boot = false; } #else if (gpio_get(BOARD_PRESENCE_PORT, BOARD_PRESENCE_PIN) != 0) { /* don't try booting before we set up the bootloader */ try_boot = false; } #endif #endif /* Try to boot the app if we think we should just go straight there */ if (try_boot) { /* set the boot-to-bootloader flag so that if boot fails on reset we will stop here */ #ifdef BOARD_BOOT_FAIL_DETECT board_set_rtc_signature(BOOT_RTC_SIGNATURE); #endif /* try to boot immediately */ jump_to_app(); /* booting failed, stay in the bootloader forever */ timeout = 0; } /* configure the clock for bootloader activity */ rcc_clock_setup_hse_3v3(&clock_setup); /* start the interface */ cinit(BOARD_INTERFACE_CONFIG); #if 0 // MCO1/02 gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO8); gpio_set_output_options(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_100MHZ, GPIO8); gpio_set_af(GPIOA, GPIO_AF0, GPIO8); gpio_mode_setup(GPIOC, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO9); gpio_set_af(GPIOC, GPIO_AF0, GPIO9); #endif while (1) { /* run the bootloader, come back after an app is uploaded or we time out */ bootloader(timeout); /* if the force-bootloader pins are strapped, just loop back */ if (board_test_force_pin()) continue; /* set the boot-to-bootloader flag so that if boot fails on reset we will stop here */ #ifdef BOARD_BOOT_FAIL_DETECT board_set_rtc_signature(BOOT_RTC_SIGNATURE); #endif /* look to see if we can boot the app */ jump_to_app(); /* launching the app failed - stay in the bootloader forever */ timeout = 0; } }
int main(void) { unsigned tempi; char val; uint8_t sw1,sw2; #ifdef START_POWERSAVE char OK = 1; #endif cli(); MCUCR = (1<<IVCE); MCUCR = (1<<IVSEL); //move interruptvectors to the Boot sector USART_Init(UART_BAUD_SELECT(BAUDRATE,XTAL),UARTSINGLE); // single speed // USART_Init(UART_BAUD_SELECT(BAUDRATE/2,XTAL),UARTDOUBLE); // double speed d7segment_init(); #if defined(START_POWERSAVE) /* This is an adoption of the Butterfly Bootloader startup-sequence. It may look a little strange but separating the login-loop from the main parser-loop gives a lot a possibilities (timeout, sleep-modes etc.). */ for(;OK;) { if((BLPIN1 & (1<<BLPNUM1)) || (BLPIN2 & (1<<BLPNUM2))) // Either one of two switch press still go app mode { // jump to main app if pin is not grounded BLPORT1 &= ~(1<<BLPNUM1); // set to default MCUCR = (1<<IVCE); MCUCR = (0<<IVSEL); // move interruptvectors to the Application sector jump_to_app(); // Jump to application sector } else { val = recchar(); if( val == 0x1B ) /* ESC */ { // AVRPROG connection while (val != 'S') // Wait for signon { val = recchar(); } send_boot(); // Report signon OK = 0; } else sendchar('?'); } // Power-Save code here } #elif defined(START_SIMPLE) sw1 = _7SEGMENT_SW1_IN_PORT & _7SEGMENT_SW1; sw2 = _7SEGMENT_SW2_IN_PORT & _7SEGMENT_SW2; if ((sw1) ) //&& (!sw2)) // SW1, SW2 Press // if((BLPIN1 & (1<<BLPNUM1)) || (BLPIN2 & (1<<BLPNUM2))) { // jump to main app if pin is grounded // BLPORT1 &= ~(1<<BLPNUM1); // set to default ?? // BLPORT2 &= ~(1<<BLPNUM2); // set to default ?? MCUCR = (1<<IVCE); MCUCR = (0<<IVSEL); //move interruptvectors to the Application sector d7segment_display(_7SEGMENT_C_P,1); jump_to_app(); // Jump to application sector } #elif defined(START_BOOTICE) #warning "BOOTICE mode - no startup-condition" #else #error "Select START_ condition for bootloader in main.c" #endif for(;;) { d7segment_display(_7SEGMENT_C_B,1); val=recchar(); if(val=='a') //Autoincrement? { sendchar('Y'); //Autoincrement is quicker } else if(val=='A') //write address { address=recchar(); //read address 8 MSB address=(address<<8)|recchar(); address=address<<1; // !! convert from word address to byte address sendchar('\r'); } else if(val=='b') { // Buffer load support sendchar('Y'); // Report buffer load supported sendchar((UART_RX_BUFFER_SIZE >> 8) & 0xFF); // Report buffer size in bytes sendchar(UART_RX_BUFFER_SIZE & 0xFF); } else if(val=='B') // Start buffer load
int main() { /* NOTE: Do NOT modify the following start-up sequence */ /* Any new initialization functions should be added in OpenPilotInit() */ /* Brings up System using CMSIS functions, enables the LEDs. */ PIOS_SYS_Init(); if (BSL_HOLD_STATE == 0) USB_connected = TRUE; PIOS_IAP_Init(); if (PIOS_IAP_CheckRequest() == TRUE) { PIOS_Board_Init(); PIOS_DELAY_WaitmS(1000); User_DFU_request = TRUE; PIOS_IAP_ClearRequest(); } GO_dfu = (USB_connected == TRUE) || (User_DFU_request == TRUE); if (GO_dfu == TRUE) { if (USB_connected) ProgPort = Usb; else ProgPort = Serial; PIOS_Board_Init(); if(User_DFU_request == TRUE) DeviceState = DFUidle; else DeviceState = BLidle; STOPWATCH_Init(100,LED_PWM_TIMER); if (ProgPort == Serial) { fifoBuf_init(&ssp_buffer,rx_buffer,UART_BUFFER_SIZE); STOPWATCH_Init(100,SSP_TIMER);//nao devia ser 1000? STOPWATCH_Reset(SSP_TIMER); ssp_Init(&ssp_port, &SSP_PortConfig); } PIOS_OPAHRS_ForceSlaveSelected(true); } else JumpToApp = TRUE; STOPWATCH_Reset(LED_PWM_TIMER); while (TRUE) { if (ProgPort == Serial) { ssp_ReceiveProcess(&ssp_port); status=ssp_SendProcess(&ssp_port); while((status!=SSP_TX_IDLE) && (status!=SSP_TX_ACKED)){ ssp_ReceiveProcess(&ssp_port); status=ssp_SendProcess(&ssp_port); } } if (JumpToApp == TRUE) jump_to_app(); //pwm_period = 50; // *100 uS -> 5 mS //pwm_sweep_steps =100; // * 5 mS -> 500 mS switch (DeviceState) { case Last_operation_Success: case uploadingStarting: case DFUidle: period1 = 50; sweep_steps1 = 100; PIOS_LED_Off(RED); period2 = 0; break; case uploading: period1 = 50; sweep_steps1 = 100; period2 = 25; sweep_steps2 = 50; break; case downloading: period1 = 25; sweep_steps1 = 50; PIOS_LED_Off(RED); period2 = 0; break; case BLidle: period1 = 0; PIOS_LED_On(BLUE); period2 = 0; break; default://error period1 = 50; sweep_steps1 = 100; period2 = 50; sweep_steps2 = 100; } if (period1 != 0) { if (LedPWM(period1, sweep_steps1, STOPWATCH_ValueGet(LED_PWM_TIMER))) PIOS_LED_On(BLUE); else PIOS_LED_Off(BLUE); } else PIOS_LED_On(BLUE); if (period2 != 0) { if (LedPWM(period2, sweep_steps2, STOPWATCH_ValueGet(LED_PWM_TIMER))) PIOS_LED_On(RED); else PIOS_LED_Off(RED); } else PIOS_LED_Off(RED); if (STOPWATCH_ValueGet(LED_PWM_TIMER) > 100 * 50 * 100) STOPWATCH_Reset(LED_PWM_TIMER); if ((STOPWATCH_ValueGet(LED_PWM_TIMER) > 60000) && (DeviceState == BLidle)) JumpToApp = TRUE; processRX(); DataDownload(start); } }
/*--- MAIN -------------------------------------------------------------------*/ int main(void) { char temp_char; uint16_t loop = 1; uint8_t bootFlag = TRUE; cli(); /* the following code moves the interrupt vector pointer to the bootloader section. The problem is the compiler doesn't understand where to put the IV table. */ GICR = _BV(IVCE); GICR |= _BV(IVSEL); //move interruptvectors to the Boot sector /* The slow baud rate is required because of the intel hex parsing overhead. If I could figure out how to enable interrupts in the BLS (compiler issue) then a higher speed could be used by switching to an interrupt based UART ISR. The code could also be optimized. */ SerCom0Init(BAUD_2400); // NOTE, the baud rates are constants defined in // sercom.h. You need to adjust those constants // to fit your MCU speed // poll USART receive complete flag 64k times to catch the 'i' reliably // test if flash is empty (i.e. flash content is 0xff) if(pgm_read_byte_near(0x0000) != 0xFF) { bootFlag = FALSE; } do { if(bit_is_set( UCSRA, RXC)) if( UDR == 'i') { bootFlag = TRUE; PutString0("Boot V "); PutChar0(VER_HIGH_BYTE); PutChar0(VER_LOW_BYTE); PutString0("\r\n"); } } while(loop++); /* this main loop is the user 'menu'. */ while(bootFlag) { if( Hit0() ) // more necessary for UART code running interrupts { temp_char=GetChar0(); switch(temp_char) { case 'u': // download new program { /* erase the main flash excepting BLS */ buf_address = 0; while ( APP_END > buf_address ) { boot_page_erase(buf_address); // Perform page erase boot_spm_busy_wait(); // Wait until the memory is erased. buf_address += SPM_PAGESIZE; } buf_address = 0; /* load new program */ PutString0("READY"); if(( temp_char = ihex_load())) { PutString0("ERR "); PutInt0(temp_char); } else {( PutString0("OK") ); bootFlag = FALSE ; // Exit to run } } break; case 'x': //Exit upgrade { GICR = _BV(IVCE); GICR &= ~_BV(IVSEL); //move interruptvectors to the Application sector jump_to_app(); // Jump to application sector // wdt_enable(WDTO_15MS); // Enable Watchdog Timer to give reset } break; default: { PutString0("u - Upload or x - Execute\r\n"); } } // end switch } // end if( Hit0() ) } // end while(1) // Start to application GICR = _BV(IVCE); GICR &= ~_BV(IVSEL); //move interruptvectors to the Application sector jump_to_app(); // Jump to application sector return 0; }
int main() { PIOS_SYS_Init(); PIOS_Board_Init(); PIOS_IAP_Init(); // Make sure the brown out reset value for this chip // is 2.7 volts check_bor(); #ifdef PIOS_INCLUDE_USB USB_connected = PIOS_USB_CheckAvailable(0); #endif if (PIOS_IAP_CheckRequest() == true) { PIOS_DELAY_WaitmS(1000); User_DFU_request = true; PIOS_IAP_ClearRequest(); } GO_dfu = (USB_connected == true) || (User_DFU_request == true); if (GO_dfu == true) { if (User_DFU_request == true) { DeviceState = DFUidle; } else { DeviceState = BLidle; } } else { JumpToApp = true; } uint32_t stopwatch = 0; uint32_t prev_ticks = PIOS_DELAY_GetuS(); while (true) { /* Update the stopwatch */ uint32_t elapsed_ticks = PIOS_DELAY_GetuSSince(prev_ticks); prev_ticks += elapsed_ticks; stopwatch += elapsed_ticks; if (JumpToApp == true) { jump_to_app(); } switch (DeviceState) { case Last_operation_Success: case uploadingStarting: case DFUidle: period1 = 5000; sweep_steps1 = 100; PIOS_LED_Off(PIOS_LED_HEARTBEAT); period2 = 0; break; case uploading: period1 = 5000; sweep_steps1 = 100; period2 = 2500; sweep_steps2 = 50; break; case downloading: period1 = 2500; sweep_steps1 = 50; PIOS_LED_Off(PIOS_LED_HEARTBEAT); period2 = 0; break; case BLidle: period1 = 0; PIOS_LED_On(PIOS_LED_HEARTBEAT); period2 = 0; break; default: // error period1 = 5000; sweep_steps1 = 100; period2 = 5000; sweep_steps2 = 100; } if (period1 != 0) { if (LedPWM(period1, sweep_steps1, stopwatch)) { PIOS_LED_On(PIOS_LED_HEARTBEAT); } else { PIOS_LED_Off(PIOS_LED_HEARTBEAT); } } else { PIOS_LED_On(PIOS_LED_HEARTBEAT); } if (period2 != 0) { if (LedPWM(period2, sweep_steps2, stopwatch)) { PIOS_LED_On(PIOS_LED_HEARTBEAT); } else { PIOS_LED_Off(PIOS_LED_HEARTBEAT); } } else { PIOS_LED_Off(PIOS_LED_HEARTBEAT); } if (stopwatch > 50 * 1000 * 1000) { stopwatch = 0; } if ((stopwatch > 6 * 1000 * 1000) && ((DeviceState == BLidle) || (DeviceState == DFUidle && !USB_connected))) { JumpToApp = true; } processRX(); DataDownload(start); } }
int main(void) { unsigned timeout = 0; /* do board-specific initialisation */ board_init(); #if defined(INTERFACE_USART) | defined (INTERFACE_USB) /* XXX sniff for a USART connection to decide whether to wait in the bootloader? */ timeout = BOOTLOADER_DELAY; #endif #ifdef INTERFACE_I2C # error I2C bootloader detection logic not implemented #endif /* if the app left a cookie saying we should wait, then wait */ if (should_wait()) timeout = BOOTLOADER_DELAY; #ifdef BOARD_FORCE_BL_PIN /* if the force-BL pin state matches the state of the pin, wait in the bootloader forever */ if (BOARD_FORCE_BL_VALUE == gpio_get(BOARD_FORCE_BL_PORT, BOARD_FORCE_BL_PIN)) timeout = 0xffffffff; #endif /* look for the magic wait-in-bootloader value in backup register zero */ /* if we aren't expected to wait in the bootloader, try to boot immediately */ if (timeout == 0) { /* try to boot immediately */ jump_to_app(); /* if we returned, there is no app; go to the bootloader and stay there */ timeout = 0; } /* configure the clock for bootloader activity */ #if defined(INTERFACE_USB) rcc_clock_setup_in_hsi_out_48mhz(); #else rcc_clock_setup_in_hsi_out_24mhz(); #endif /* start the interface */ cinit(BOARD_INTERFACE_CONFIG); while (1) { /* run the bootloader, possibly coming back after the timeout */ bootloader(timeout); /* look to see if we can boot the app */ jump_to_app(); /* boot failed; stay in the bootloader forever next time */ timeout = 0; } }
void ATrst(void) { for(uint8_t i=0; i<sizeof(ok); i++) usart0_write(ok[i]); _delay_ms(50); jump_to_app(); }
/*--- MAIN -------------------------------------------------------------------*/ int main(void) { uint8_t temp_char,tmp; uint8_t bootFlag = TRUE; cli(); /* the following code moves the interrupt vector pointer to the bootloader section. The problem is the compiler doesn't understand where to put the IV table. */ GICR = _BV(IVCE); GICR = _BV(IVSEL); //move interruptvectors to the Boot sector ** WRITE 0 TO IVCE use = not | // Initial 7 Segments on E_io // Set direction of two switch to Input DDRB = 0xFF; // Output DDRC = 0x18; // P3, P4 for Control 7 segments Digits // Enable pull up resistor PORTC |= 0x24; /* The slow baud rate is required because of the intel hex parsing overhead. If I could figure out how to enable interrupts in the BLS (compiler issue) then a higher speed could be used by switching to an interrupt based UART ISR. The code could also be optimized. */ uart_init( UART_INTERRUPT,UART_8_N_1,UART_38400); // poll USART receive complete flag 64k times to catch the 'i' reliably // test if flash is empty (i.e. flash content is 0xff) if(pgm_read_byte_near(0x0000) != 0xFF) { bootFlag = FALSE; } // Enter boot mode by press b // while (!(tmp = uart_read())); // if (tmp == 'b') // bootFlag = TRUE; // Check SW for enter boot mode either press both SW at the same time tmp = PINC & (0x24); // PB0, PB3 port if (!tmp) // Press SW tmp = 0 bootFlag = TRUE; uart_write_str (VERSION); // Display b characters E_OUT_PORTA = 0x7C; // b E_OUT_PB1(0); E_OUT_PB2(1); /* this main loop is the user 'menu'. */ while(bootFlag) { if( (tmp = uart_read()) ) { switch(tmp) { case 'u': // download new program { /* erase the main flash excepting BLS */ buf_address = 0; while ( APP_END > buf_address ) { boot_page_erase(buf_address); // Perform page erase boot_spm_busy_wait(); // Wait until the memory is erased. buf_address += SPM_PAGESIZE; } buf_address = 0; /* load new program */ uart_write_str("READY \n"); if(( temp_char = ihex_load())) { uart_write_str("ERR "); uart_write_char(temp_char + '0' ); uart_write_char('\n'); } else { bootFlag = FALSE ; // Exit to run } } break; case 'x': //Exit upgrade { GICR = _BV(IVCE); GICR &= ~(_BV(IVSEL) | _BV(IVCE)); //move interruptvectors to the Application sector Write 0 to IVCE jump_to_app(); // Jump to application sector // wdt_enable(WDTO_15MS); // Enable Watchdog Timer to give reset } break; default: { uart_write_str(" u - Upload or x - Execute \n"); } } // end switch } } // end while(1) // Start to application GICR = _BV(IVCE); GICR &= ~(_BV(IVSEL) | _BV(IVCE)); //move interruptvectors to the Application sector Write 0 to IVCE jump_to_app(); // Jump to application sector return 0; }
int main() { /* NOTE: Do NOT modify the following start-up sequence */ /* Any new initialization functions should be added in OpenPilotInit() */ /* Brings up System using CMSIS functions, enables the LEDs. */ PIOS_SYS_Init(); if (BSL_HOLD_STATE == 0) USB_connected = TRUE; PIOS_IAP_Init(); if (PIOS_IAP_CheckRequest() == TRUE) { PIOS_Board_Init(); PIOS_DELAY_WaitmS(1000); User_DFU_request = TRUE; PIOS_IAP_ClearRequest(); } GO_dfu = (USB_connected == TRUE) || (User_DFU_request == TRUE); if (GO_dfu == TRUE) { PIOS_Board_Init(); if(User_DFU_request == TRUE) DeviceState = DFUidle; else DeviceState = BLidle; STOPWATCH_Init(100,LED_PWM_TIMER); } else JumpToApp = TRUE; STOPWATCH_Reset(LED_PWM_TIMER); while (TRUE) { if (JumpToApp == TRUE) jump_to_app(); //pwm_period = 50; // *100 uS -> 5 mS //pwm_sweep_steps =100; // * 5 mS -> 500 mS switch (DeviceState) { case Last_operation_Success: case uploadingStarting: case DFUidle: period1 = 50; sweep_steps1 = 100; PIOS_LED_Off(BLUE); period2 = 0; break; case uploading: period1 = 50; sweep_steps1 = 100; period2 = 25; sweep_steps2 = 50; break; case downloading: period1 = 25; sweep_steps1 = 50; PIOS_LED_Off(BLUE); period2 = 0; break; case BLidle: period1 = 0; PIOS_LED_On(BLUE); period2 = 0; break; default://error period1 = 50; sweep_steps1 = 100; period2 = 50; sweep_steps2 = 100; } if (period1 != 0) { if (LedPWM(period1, sweep_steps1, STOPWATCH_ValueGet(LED_PWM_TIMER))) PIOS_LED_On(BLUE); else PIOS_LED_Off(BLUE); } else PIOS_LED_On(BLUE); if (period2 != 0) { if (LedPWM(period2, sweep_steps2, STOPWATCH_ValueGet(LED_PWM_TIMER))) PIOS_LED_On(BLUE); else PIOS_LED_Off(BLUE); } else PIOS_LED_Off(BLUE); if (STOPWATCH_ValueGet(LED_PWM_TIMER) > 100 * 50 * 100) STOPWATCH_Reset(LED_PWM_TIMER); if ((STOPWATCH_ValueGet(LED_PWM_TIMER) > 60000) && (DeviceState == BLidle)) JumpToApp = TRUE; processRX(); DataDownload(start); } }
void process_spi_request(void) { const struct pios_board_info * bdinfo = &pios_board_info_blob; bool msg_to_process = FALSE; PIOS_IRQ_Disable(); /* Figure out if we're in an interesting stable state */ switch (lfsm_get_state()) { case LFSM_STATE_USER_BUSY: msg_to_process = TRUE; break; case LFSM_STATE_INACTIVE: /* Queue up a receive buffer */ lfsm_user_set_rx_v0(&user_rx_v0); lfsm_user_done(); break; case LFSM_STATE_STOPPED: /* Get things going */ lfsm_set_link_proto_v0(&link_tx_v0, &link_rx_v0); break; default: /* Not a stable state */ break; } PIOS_IRQ_Enable(); if (!msg_to_process) { /* Nothing to do */ //PIOS_COM_SendFormattedString(PIOS_COM_AUX, "."); return; } if (user_rx_v0.tail.magic != OPAHRS_MSG_MAGIC_TAIL) { return; } switch (user_rx_v0.payload.user.t) { case OPAHRS_MSG_V0_REQ_FWUP_VERIFY: opahrs_msg_v0_init_user_tx(&user_tx_v0, OPAHRS_MSG_V0_RSP_FWUP_STATUS); Fw_crc = PIOS_BL_HELPER_CRC_Memory_Calc(); lfsm_user_set_tx_v0(&user_tx_v0); boot_status = idle; PIOS_LED_Off(LED1); user_tx_v0.payload.user.v.rsp.fwup_status.status = boot_status; break; case OPAHRS_MSG_V0_REQ_RESET: PIOS_DELAY_WaitmS(user_rx_v0.payload.user.v.req.reset.reset_delay_in_ms); PIOS_SYS_Reset(); break; case OPAHRS_MSG_V0_REQ_VERSIONS: //PIOS_LED_On(LED1); opahrs_msg_v0_init_user_tx(&user_tx_v0, OPAHRS_MSG_V0_RSP_VERSIONS); user_tx_v0.payload.user.v.rsp.versions.bl_version = BOOTLOADER_VERSION; user_tx_v0.payload.user.v.rsp.versions.hw_version = (BOARD_TYPE << 8) | BOARD_REVISION; user_tx_v0.payload.user.v.rsp.versions.fw_crc = Fw_crc; lfsm_user_set_tx_v0(&user_tx_v0); break; case OPAHRS_MSG_V0_REQ_MEM_MAP: opahrs_msg_v0_init_user_tx(&user_tx_v0, OPAHRS_MSG_V0_RSP_MEM_MAP); user_tx_v0.payload.user.v.rsp.mem_map.density = bdinfo->hw_type; user_tx_v0.payload.user.v.rsp.mem_map.rw_flags = (BOARD_READABLE | (BOARD_WRITABLE << 1)); user_tx_v0.payload.user.v.rsp.mem_map.size_of_code_memory = bdinfo->fw_size; user_tx_v0.payload.user.v.rsp.mem_map.size_of_description = bdinfo->desc_size; user_tx_v0.payload.user.v.rsp.mem_map.start_of_user_code = bdinfo->fw_base; lfsm_user_set_tx_v0(&user_tx_v0); break; case OPAHRS_MSG_V0_REQ_SERIAL: opahrs_msg_v0_init_user_tx(&user_tx_v0, OPAHRS_MSG_V0_RSP_SERIAL); PIOS_SYS_SerialNumberGet( (char *) &(user_tx_v0.payload.user.v.rsp.serial.serial_bcd)); lfsm_user_set_tx_v0(&user_tx_v0); break; case OPAHRS_MSG_V0_REQ_FWUP_STATUS: opahrs_msg_v0_init_user_tx(&user_tx_v0, OPAHRS_MSG_V0_RSP_FWUP_STATUS); user_tx_v0.payload.user.v.rsp.fwup_status.status = boot_status; lfsm_user_set_tx_v0(&user_tx_v0); break; case OPAHRS_MSG_V0_REQ_FWUP_DATA: PIOS_LED_On(LED1); opahrs_msg_v0_init_user_tx(&user_tx_v0, OPAHRS_MSG_V0_RSP_FWUP_STATUS); if (!(user_rx_v0.payload.user.v.req.fwup_data.adress < bdinfo->fw_base)) { for (uint8_t x = 0; x < user_rx_v0.payload.user.v.req.fwup_data.size; ++x) { if (FLASH_ProgramWord( (user_rx_v0.payload.user.v.req.fwup_data.adress + ((uint32_t)(x * 4))), user_rx_v0.payload.user.v.req.fwup_data.data[x]) != FLASH_COMPLETE) { boot_status = write_error; break; } } } else { boot_status = outside_dev_capabilities; } PIOS_LED_Off(LED1); user_tx_v0.payload.user.v.rsp.fwup_status.status = boot_status; lfsm_user_set_tx_v0(&user_tx_v0); break; case OPAHRS_MSG_V0_REQ_FWDN_DATA: opahrs_msg_v0_init_user_tx(&user_tx_v0, OPAHRS_MSG_V0_RSP_FWDN_DATA); uint32_t adr = user_rx_v0.payload.user.v.req.fwdn_data.adress; for (uint8_t x = 0; x < 4; ++x) { user_tx_v0.payload.user.v.rsp.fw_dn.data[x] = *PIOS_BL_HELPER_FLASH_If_Read(adr + x); } lfsm_user_set_tx_v0(&user_tx_v0); break; case OPAHRS_MSG_V0_REQ_FWUP_START: FLASH_Unlock(); opahrs_msg_v0_init_user_tx(&user_tx_v0, OPAHRS_MSG_V0_RSP_FWUP_STATUS); user_tx_v0.payload.user.v.rsp.fwup_status.status = boot_status; lfsm_user_set_tx_v0(&user_tx_v0); PIOS_LED_On(LED1); if (PIOS_BL_HELPER_FLASH_Start() == TRUE) { boot_status = started; PIOS_LED_Off(LED1); } else { boot_status = start_failed; break; } break; case OPAHRS_MSG_V0_REQ_BOOT: PIOS_DELAY_WaitmS(user_rx_v0.payload.user.v.req.boot.boot_delay_in_ms); FLASH_Lock(); jump_to_app(); break; default: break; } /* Finished processing the received message, requeue it */ lfsm_user_set_rx_v0(&user_rx_v0); lfsm_user_done(); return; }