/*========================= IMPLEMENTATION           =========================*/
void int_evt_startup(void* evt)
{
    rvn_loc_cmd_std_t cmd;
    uint32_t blcc;
    
    switch (avrraven.status.state) {
    case STATE_STARTUP:
        /* Restart ATmega1284 application program. If in bootloader mode, start 
         * Application program. If command disappears (during ATmega1284 startup etc.)
         * this application will react on the application startup event sent by
         * ATmega1284.
         */
        cmd.id = RVN_LOC_CMD_ENTER_BOOT;
        sipc_send_frame(sizeof(rvn_loc_cmd_std_t), (uint8_t *)&cmd);
        
        // Put init symbols
        lcd_symbol_set(LCD_SYMBOL_RAVEN);
        lcd_symbol_clr(LCD_SYMBOL_RX);
        lcd_symbol_clr(LCD_SYMBOL_TX);
        lcd_symbol_antenna_signal(LCD_SYMBOL_ANTENNA_DIS);
                
        avrraven.status.ntwk_address = NTWK_ADDRESS_INVALID;
        
        // 
        led_status_set(LED_OFF);
        
        // 
        lcd_puts_P("WAIT FOR M1284 BOOT LOADER");
        
        // If m1284 factory default fw should be loaded:
        BLCC_READ(blcc);
        if (blcc == BLCC_LOAD_FACTORY_DEFAULT) {
            avrraven.status.state = STATE_M1284P_ENTER_BOOT_WAIT_BOOT_EVENT; 
        } else {
            avrraven.status.state = STATE_M1284P_RESTART_WAIT_BOOT_EVENT;
        }
        
        break;
    default:
        // Startupevent in any other state is ignored
        break;
    }
}
Exemple #2
0
/*========================= IMPLEMENTATION           =========================*/
void loc_rsp_ok(void* rsp)
{
    rvn_loc_cmd_get_param_t cmd_get_param;
    rvn_loc_cmd_std_t cmd;
    uint32_t blcc;
    FMENU_item_flash_t* current_menu_entry = FMENU_GetCurrentItem(&MENU_menuHandle);
    
    
    SIPC_ACK_PACKET();
        
    switch (avrraven.status.state) {
    /*======================== FW write               ========================*/
    case STATE_FW_WRITE_INIT:
        lcd_puts_P("RECEIVING FW IMAGE");
        avrraven.status.state = STATE_FW_WRITE;
        break;
    case STATE_FW_WRITE_INIT_WAIT_RX_ENABLE_RESPONSE:
        avrraven.status.state = STATE_FW_WRITE;
        break;
    case STATE_FW_WRITE_COMPLETE_WAIT_RX_ENABLE_RESPONSE:
        lcd_puts_P("DONE");
        avrraven.status.state = STATE_DISPLAY_MESSAGE;
        break;
    case STATE_OTA_TRANS_WAITING_FOR_RX_ENABLE_RESPONSE:
        avrraven.status.state = STATE_IDLE;
        break;
    case STATE_FW_WRITE_WAIT_RX_ENABLE_RESPONSE:
        avrraven.status.state = STATE_FW_WRITE;
        break;
    case STATE_FW_WRITE_WAIT_TX_DONE:
        avrraven.status.state = STATE_FW_WRITE;
        break;
    case STATE_FW_WRITE_COMPLETE_WAIT_TX_DONE:
        lcd_puts_P("DONE");
        avrraven.status.state = STATE_DISPLAY_MESSAGE;
        break;
    case STATE_FW_WRITE_IMAGE:
        // Set ATmega1284p in boot loader mode
        led_status_set(LED_FAST_BLINK);
        lcd_puts_P("WRITING M1284 IMAGE");
        cmd.id = RVN_LOC_CMD_ENTER_BOOT;
        sipc_send_frame(sizeof(cmd), (uint8_t *)&cmd);
        avrraven.status.state = STATE_M1284P_UPGRADE_INIT_WAIT_RESPOND;
        break;
    case STATE_FW_WRITE_COMPLETE_WAIT_RADIO:
        lcd_symbol_set(LCD_SYMBOL_ZLINK);
        lcd_symbol_set(LCD_SYMBOL_ZIGBEE);
        lcd_symbol_antenna_signal(LCD_SYMBOL_ANTENNA_SIG_3);
        cmd.id = RVN_LOC_CMD_RX_ON;
        sipc_send_frame(sizeof(cmd), (uint8_t *)&cmd);
        avrraven.status.state = STATE_FW_WRITTEN_WAIT_RX_ENABLE_RESPONSE;
        break;
    case STATE_FW_WRITTEN_WAIT_RX_ENABLE_RESPONSE:
        lcd_puts_P("FW WRITTEN SUCCESSFULLY");
        ota_event(RVN_OTA_EVT_FW_WRITE_DONE, 0x0000);
        BLCC_WRITE(BLCC_NORMAL_APP_START);
        avrraven.status.state = STATE_DISPLAY_MESSAGE;
        break;
    case STATE_FW_WRITE: 
        break;
    /*======================== Radio                  ========================*/
    case STATE_RADIO_CONNECTING:
        lcd_symbol_set(LCD_SYMBOL_ZLINK);
        lcd_symbol_set(LCD_SYMBOL_ZIGBEE);
        lcd_symbol_antenna_signal(LCD_SYMBOL_ANTENNA_SIG_3);
        cmd.id = RVN_LOC_CMD_RX_ON;
        sipc_send_frame(sizeof(cmd), (uint8_t *)&cmd);
        avrraven.status.state = STATE_RADIO_WAIT_FOR_RX_ENABLE_RESPONSE;
        break;
    case STATE_RADIO_DISCONNECTING:
        lcd_symbol_clr(LCD_SYMBOL_ZLINK);
        lcd_symbol_clr(LCD_SYMBOL_ZIGBEE);
        lcd_symbol_clr(LCD_SYMBOL_RX);
        lcd_symbol_clr(LCD_SYMBOL_TX);
        lcd_symbol_antenna_signal(LCD_SYMBOL_ANTENNA_DIS);
        lcd_puts_P((PROGMEM_DECLARE(const char)*)FMENU_GetTitle(current_menu_entry));
        lcd_num_clr_all();
        avrraven.status.ntwk_address = NTWK_ADDRESS_INVALID;
        avrraven.status.state = STATE_IDLE;
        break;
    case STATE_RADIO_WAIT_FOR_RX_ENABLE_RESPONSE:
    case STATE_RADIO_WAIT_FOR_RX_REENABLE_RESPONSE:
        
        // Get short address
        cmd_get_param.id = RVN_LOC_CMD_GET_PARAM;
        cmd_get_param.param = NWK_ADDRESS;
        sipc_send_frame(sizeof(rvn_loc_cmd_get_param_t), (uint8_t *)&cmd_get_param);

        avrraven.status.state = STATE_RADIO_GET_ADDRESS_WAIT_RESPONSE;
        break;
    /*======================== ATmega1284p            ========================*/
    case STATE_M1284P_UPGRADE_INIT_WAIT_RESPOND:
        /*Does nothing. Waiting for enter bootloader event*/
        break;
    case STATE_M1284P_UPGRADE_PACKET_WAIT_RESPOND:
        send_m1284p_fw_packet(avrraven.status.m1284p_img_offset, avrraven.status.m1284p_address_offset, m1284p_fw_packet);
        lcd_num_putdec((int)(avrraven.status.m1284p_address_offset/1024), LCD_NUM_PADDING_SPACE);
        if ((avrraven.status.m1284p_address_offset += RVN_FW_PACKET_SIZE) == M1284P_APP_FLASH_SIZE) {
            vrt_mem_free((void *)(m1284p_fw_packet));
            lcd_puts_P("DONE");
            avrraven.status.state = STATE_M1284P_UPGRADE_DONE_WAIT_RESPOND;
        } else {
            /* stay in same avrraven.status.state and wait for response on the FW packet*/
        }
        break;
    case STATE_M1284P_UPGRADE_DONE_WAIT_RESPOND:
        // Start ATmega1284's new FW
        cmd.id = RVN_LOC_CMD_APP_START;
        sipc_send_frame(sizeof(cmd), (uint8_t *)&cmd);
        
        // If m1284 factory default fw loaded, m3290 fw allready upgraded, and 
        BLCC_READ(blcc);
        if (blcc == BLCC_LOAD_FACTORY_DEFAULT) {
            BLCC_WRITE(BLCC_FW_UPGRADE_COMPLETE);
            reboot();
        } else {
            // Start own bootloader without waitig for 1284 to reboot
            BLCC_WRITE(BLCC_FW_UPGRADE_START_REQUEST_FROM_APP);
            reboot();
        }
        break;
    case STATE_M1284P_NEW_FW_WAIT_EVENT:
        /*Does nothing. Waiting for app prog start event*/
        break;
    case STATE_M1284P_RESTART_WAIT_BOOT_EVENT:
    case STATE_M1284P_ENTER_BOOT_WAIT_BOOT_EVENT:
        /*Does nothing. Waiting for boot loader start event*/
        break;
    case STATE_M1284P_RESTART_WAIT_APP_EVENT:
        /*Does nothing. Waiting for app prog start event*/
        break;
    case STATE_M1284P_DISCONNECT_WAIT_RESPOND:
        // Set ATmega1284p in boot loader mode
        led_status_set(LED_FAST_BLINK);
        lcd_puts_P("WRITING 1284P FW");
        cmd.id = RVN_LOC_CMD_ENTER_BOOT;
        sipc_send_frame(sizeof(cmd), (uint8_t *)&cmd);
        avrraven.status.state = STATE_M1284P_UPGRADE_INIT_WAIT_RESPOND;
        break;
    /*======================== Misc                   ========================*/
    case STATE_OTA_TRANSACTION_WAITING_FOR_RESPONSE:
        lcd_symbol_clr(LCD_SYMBOL_RX); // TIMED_FUNCTION
        lcd_symbol_set(LCD_SYMBOL_TX); // TIMED_FUNCTION
        cmd.id = RVN_LOC_CMD_RX_ON;
        sipc_send_frame(sizeof(cmd), (uint8_t *)&cmd);
        avrraven.status.state = STATE_OTA_TRANS_WAITING_FOR_RX_ENABLE_RESPONSE;
        break;
    case STATE_MAIL_SEND_INIT:
        lcd_puts_P("SENDING");
        led_status_set(LED_SOFT_BLINK);
        avrraven.status.state = STATE_MAIL_SENDING;
        break;
    default:
        // OK responses in unknown state is ignored
        break;
    }
}
Exemple #3
0
void loc_rsp_get_param(void* rsp)
{
    rvn_loc_cmd_radio_connect_t cmd;
    uint32_t blcc;
    rvn_loc_rsp_get_param_t* rsp_param = (rvn_loc_rsp_get_param_t*)rsp;
    FMENU_item_flash_t* current_menu_entry = FMENU_GetCurrentItem(&MENU_menuHandle);
    FMENU_item_flash_t* startup_menu_entry;
    menu_action_t menu_action = MENU_ACTION_REFRESH;
    
    switch (avrraven.status.state) {
    case STATE_RADIO_GET_PARAM:
        lcd_num_puthex(*(uint16_t*)&rsp_param->data[0], LCD_NUM_PADDING_ZERO);
        avrraven.status.state = STATE_IDLE;
    
        SIPC_ACK_PACKET();
        break;
    case STATE_RADIO_GET_ADDRESS_WAIT_RESPONSE:
        avrraven.status.ntwk_address = *(uint16_t*)&rsp_param->data[0];
        navigate_menu(current_menu_entry, current_menu_entry, menu_action);
        led_status_set(LED_OFF);
        avrraven.status.state = STATE_IDLE;
    
        SIPC_ACK_PACKET();
        break;
    case STATE_M1284P_RESTART_GET_REV:
        // Store M1284P FW revisions
        avrraven.status.m1284p_app_rev = rsp_param->data[0];
        avrraven.status.m1284p_app_rev |= rsp_param->data[1] << 8;
        avrraven.status.m1284p_bl_rev  = rsp_param->data[2];
        avrraven.status.m1284p_bl_rev  |= rsp_param->data[3] << 8;
    
        SIPC_ACK_PACKET();
        
        // Read bootloader communication channel in EEPROM
        BLCC_READ(blcc);
        if (blcc == BLCC_FW_UPGRADE_COMPLETE) {
            // Enable radio
            cmd.id = RVN_LOC_CMD_RADIO_CONNECT;
            cmd.channel = avrraven.user_config.channel;
            cmd.pan_id = avrraven.user_config.panid;
            sipc_send_frame(sizeof(rvn_loc_cmd_radio_connect_t), (uint8_t *)&cmd);
            lcd_puts_P("JOINING NETWORK");
            led_status_set(LED_SOFT_BLINK);
            avrraven.status.state = STATE_FW_WRITE_COMPLETE_WAIT_RADIO;
        } else {
            // Navigate to startup menu
            startup_menu_entry = FMENU_GoToRootItem(&MENU_menuHandle);
            navigate_menu(startup_menu_entry, startup_menu_entry, menu_action);
            
            // If auto join is enabled, try to join network
            if (avrraven.user_config.join_auto == true) {
                // Enable radio
                cmd.id = RVN_LOC_CMD_RADIO_CONNECT;
                cmd.channel = avrraven.user_config.channel;
                cmd.pan_id = avrraven.user_config.panid;
                sipc_send_frame(sizeof(rvn_loc_cmd_radio_connect_t), (uint8_t *)&cmd);
                lcd_puts_P("JOINING NETWORK");
                led_status_set(LED_SOFT_BLINK);
                lcd_num_clr_all();
                avrraven.status.state = STATE_RADIO_CONNECTING;
            } else {
                avrraven.status.state = STATE_IDLE;
            }
        }
        break;
    default:
        // Param responses in unknown state is ignored. Impossible to know what to do with the data
        break;
    }
}
void main(void) {
#else
int main(void) {
#endif
    
    uint32_t blcc;
    
    // Prevent optimizing of bootloader revision in progmem
    volatile uint16_t tmp2 = ATmega3290p_bl_rev;
    
    // Disable watchdog
    watchdog_disable();
    
    
    // Configuring LCD with Extern clock (TOSC, 32.768kHz)
    //                      32786 Hz          32786 Hz
    //  frame_rate = ------------------ = ------------- = 32 Hz
    //               8 * .prescl * .div     8 * 16 * 8
    //
    lcd_config_t lcd_config = LCD_DEFAULT_CONFIG;
    
    // Initialization
    if (true != avr_init()) {               // Generic MCU initialization
        error_handler();
    } else if (df_init() != 0) {            // Data flash initialization
        error_handler();
    } else if (lcd_init(lcd_config) != 0) { // Display
        error_handler();
    } else if (led_init() != 0) {           // Led
        error_handler();
    }
    
   
    /* start timer 2*/
    ASSR |= (1<<AS2);    // Asynchronous operation
    TCCR2A &= ~((1<<CS22)|(1<<CS21)|(1<<CS20));
    TCCR2A |= (1<<CS20);
    
    
    // Check shorting of "Factory default pins"
    uint8_t prr = PRR;
	PRR &= ~(1 << PRADC);
	DIDR1 &= ~((1 << AIN1D)|(1 << AIN0D));
	PRR = prr;
    
    BOOT_DDR |= (1 << BOOT_TX);  // Tx output
    BOOT_PORT &= ~(1 << BOOT_TX);  // Tx low
    
    BOOT_DDR &= ~(1 << BOOT_RX); // Rx input
    BOOT_PORT |= (1 << BOOT_RX); // Rx pullup on
    
    if ((BOOT_PIN & (1 << BOOT_RX)) != (1 << BOOT_RX)) { // Rx pin low?
        /* Check that RX goes high when TX is pulled high. */
        BOOT_PORT |= (1 << BOOT_TX);                            // Set Tx high
        
        nop();
        nop();
        nop();
        nop();
        
        if ((BOOT_PIN & (1 << BOOT_RX)) == (1 << BOOT_RX)) {    // Rx high?
            intvecs_to_boot(); // move interrutp vectors to boot section, and start boot loader
            sei();
            
            // Check supply voltage
            if (supply_voltage_read() < 2600) {
                lcd_puts("LOW BAT");
                error_handler();
            }
            
            BLCC_WRITE(BLCC_NORMAL_APP_START); // write communication channel in case abnormal exit of boot loader (power off etc.)
            
            lcd_symbol_set(LCD_SYMBOL_RAVEN);
            lcd_puts("WRITING");
            led_status_set(LED_FAST_BLINK);
            do_fw_upgrade(M3290P_FLASH_FD_IMG_ADR);

            // Signal ATmega3290p application program that FW upgrade is complete
            // This makes the application program continue upgrade ATmega1284p after booting
            BLCC_WRITE(BLCC_LOAD_FACTORY_DEFAULT);
            
            app_start();    // start application program
        }
    }
    
    // Read bootloader communication channel in EEPROM and take proper action
    BLCC_READ(blcc);
    if (blcc == BLCC_FW_UPGRADE_START_REQUEST_FROM_APP) {
        intvecs_to_boot(); // move interrutp vectors to boot section, and start boot loader
        sei();
        
        // Check supply voltage
        if (supply_voltage_read() < 2600) {
            lcd_puts("LOW BAT");
            error_handler();
        }
        
        BLCC_WRITE(BLCC_NORMAL_APP_START); // write communication channel in case abnormal exit of boot loader (power off etc.)
        
        lcd_symbol_set(LCD_SYMBOL_RAVEN);
        lcd_puts("WRITING");
        led_status_set(LED_FAST_BLINK);
        do_fw_upgrade(M3290P_FLASH_USR_IMG_ADR);
        
        // Signal ATmega3290p application program that FW upgrade is complete
        BLCC_WRITE(BLCC_FW_UPGRADE_COMPLETE);
        reboot();
    } else if (blcc == BLCC_FW_UPGRADE_COMPLETE) {
        BLCC_WRITE(BLCC_FW_UPGRADE_COMPLETE);
        sei();
        app_start();    // start application program
    } else if (blcc == BLCC_RESTART_REQUEST_FROM_APP) {
        /* Start application program*/
        BLCC_WRITE(BLCC_NORMAL_APP_START);
        sei();
        app_start();
    } else {
        /*else, start application program*/
        BLCC_WRITE(BLCC_NORMAL_APP_START);
        sei();
        app_start();
    }
}