static void gzp_index_db_add(uint8_t val) { int16_t i; uint8_t temp_val; // Search for unwritten loacation in index DB for(i = 0; i < GZP_INDEX_DB_SIZE; i++) { temp_val = hal_flash_byte_read(GZP_INDEX_DB_ADR + i); // Lower nibble if(i != (GZP_INDEX_DB_SIZE - 1)) { if((temp_val & 0x0f) == 0x0f) { temp_val = (temp_val & 0xf0) | val; break; } // Upper nibble else if((temp_val & 0xf0) == 0xf0) { temp_val = (temp_val & 0x0f) | (val << 4); break; } } else { temp_val = (GZP_PARAMS_DB_MAX_ENTRIES << 4) | val; break; } } // Write index DB hal_flash_byte_write(GZP_INDEX_DB_ADR + i, temp_val); }
void lib_eeprom255_bytes_write(uint8_t adr, uint8_t *src, uint8_t n) { uint8_t xdata i; uint16_t xdata flash_dst_pn, xdata_dst_adr, flash_old_pn, xdata_old_adr; if(*((uint8_t xdata *)(PAGE_0_XDATA + BK_BYTE)) == 0xff) { flash_dst_pn = PAGE_0_FLASH_PN; xdata_dst_adr = PAGE_0_XDATA; flash_old_pn = PAGE_1_FLASH_PN; xdata_old_adr = PAGE_1_XDATA; } else { flash_dst_pn = PAGE_1_FLASH_PN; xdata_dst_adr = PAGE_1_XDATA; flash_old_pn = PAGE_0_FLASH_PN; xdata_old_adr = PAGE_0_XDATA; } for(i = 0; i < n; i++) { if((*((uint8_t xdata *)(xdata_old_adr + adr + i))) != src[i]) { break; } } if(i < n) { hal_flash_page_erase(flash_dst_pn); for(i = 0; i < 255; i++) { if(i >= adr && i < (adr + n)) { hal_flash_byte_write(xdata_dst_adr + i, src[i - adr]); } else { hal_flash_byte_write(xdata_dst_adr + i, *((uint8_t xdata *)(xdata_old_adr + i))); } } hal_flash_byte_write(xdata_dst_adr + BK_BYTE, 0); hal_flash_page_erase(flash_old_pn); } }
void lib_eeprom255_byte_write(uint8_t adr, uint8_t dat) { uint8_t xdata i; uint16_t xdata flash_dst_pn, xdata_dst_adr, flash_old_pn, xdata_old_adr; if(*((uint8_t xdata *)(PAGE_0_XDATA + BK_BYTE)) == 0xff) { flash_dst_pn = PAGE_0_FLASH_PN; xdata_dst_adr = PAGE_0_XDATA; flash_old_pn = PAGE_1_FLASH_PN; xdata_old_adr = PAGE_1_XDATA; } else { flash_dst_pn = PAGE_1_FLASH_PN; xdata_dst_adr = PAGE_1_XDATA; flash_old_pn = PAGE_0_FLASH_PN; xdata_old_adr = PAGE_0_XDATA; } if((*((uint8_t xdata *)(xdata_old_adr + adr))) != dat) { hal_flash_page_erase(flash_dst_pn); PCON &= ~(1 << 4); for(i = 0; i < 255; i++) { if(i == adr) { hal_flash_byte_write(xdata_dst_adr + adr, dat); } else { hal_flash_byte_write(xdata_dst_adr + i, *((uint8_t xdata *)(xdata_old_adr + i))); } } hal_flash_byte_write(xdata_dst_adr + BK_BYTE, 0); hal_flash_page_erase(flash_old_pn); } }
void gzp_host_chip_id_read(uint8_t *dst, uint8_t n) { uint8_t i; if(hal_flash_byte_read(GZP_PARAMS_STORAGE_ADR + GZP_HOST_ID_LENGTH + 1) == 0xff) { hal_flash_byte_write((GZP_PARAMS_STORAGE_ADR + GZP_HOST_ID_LENGTH + 1), 0x00); hal_rng_power_up(true); for(i = 0; i < n; i++) { while(!hal_rng_data_ready()) ; hal_flash_byte_write((GZP_PARAMS_STORAGE_ADR + GZP_HOST_ID_LENGTH + 2 + i), hal_rng_read()); } hal_rng_power_up(false); } for(i = 0; i < n; i++) { *(dst++) = hal_flash_byte_read((GZP_PARAMS_STORAGE_ADR + GZP_HOST_ID_LENGTH + 2 + i)); } }
static bool gzp_set_host_id(const uint8_t* src) { if(hal_flash_byte_read(GZP_PARAMS_STORAGE_ADR) == 0xff) { hal_flash_byte_write(GZP_PARAMS_STORAGE_ADR, 0x00); hal_flash_bytes_write(GZP_PARAMS_STORAGE_ADR + 1, src, GZP_HOST_ID_LENGTH); return true; } else { return false; } }
/* Ma-ma-ma-main function! */ void main() { state_t state = LISTENING; command_t cmd = CMD_NO_CMD; firmware_start firmware; uint16_t channel_timer = 0, bootloader_timer = 0, connection_timer = 0; uint8_t ch_i = 0, firmware_number = 0; bool running; uint16_t bytes_received = 0; uint16_t bytes_total = 0; uint8_t ea_default, rf_default; // Disable RF interrupt rf_default = RF; RF = 0; // Disable global interrupt ea_default = EA; EA = 0; // Set up parameters for RF communication. configureRF(); #ifdef DEBUG_LED_ P0DIR = 0; P0 = 0x55; #endif running = true; // Boot loader loop. // Will terminate after a couple of seconds if firmware has been successfully // installed. while (running) { // Polls the RF-interrupt bit every iteration. if (RFF) { RFF = 0; nrf_irq(); if (packet_received) { packet_received = false; connection_timer = 0; cmd = MSG_CMD; switch (cmd) { // Host initiates contact with the device. case CMD_INIT: // Send ACK to host, go to CONNECTED state if successful. sendInitAck(&state); // Reset timers channel_timer = bootloader_timer = 0; break; // Host starts a firmware update. case CMD_UPDATE_START: if (state == CONNECTED) { // Initiate firmware updates, go to RECEIVING_FIRMWARE state // if successful. startFirmwareUpdate(&state, &bytes_total, &bytes_received, &firmware_number); } #ifdef DEBUG_LED_ P0 = state; #endif break; // Write message containing one hex record. case CMD_WRITE: if (state == RECEIVING_FIRMWARE) { writeHexRecord(&state, &bytes_received); } #ifdef DEBUG_LED_ P0 = 0x40; #endif break; // Firmware update has been completed. case CMD_UPDATE_COMPLETE: CE_LOW(); // Check that every byte is received. if (bytes_received == bytes_total) { // Mark firmware as successfully installed. hal_flash_byte_write(FW_INSTALLED, 0x01); hal_flash_byte_write(FW_NUMBER, firmware_number); state = CONNECTED; send(CMD_ACK); } else { send(CMD_NACK); } if (!send_success) { state = ERROR; } #ifdef DEBUG_LED_ P0 = 0x10; #endif break; // Host request data from flash at specified address. case CMD_READ: readHexRecord(); #ifdef DEBUG_LED_ P0 = 0x20; #endif break; // Host sends ping to check connections with device. case CMD_PING: if (state != LISTENING) { send(CMD_PONG); } #ifdef DEBUG_LED_ P0 = 0x80; #endif break; // Host sends disconnect case CMD_EXIT: state = LISTENING; break; // These commands should no be received. case CMD_NO_CMD: default: state = ERROR; break; } // Clear command cmd = CMD_NO_CMD; } // RF interrupt bit not set } else if (state == LISTENING) { // Will listen to one channel for 'a while' before changing. channel_timer++; if (channel_timer > CHANNEL_TIMEOUT) { channel_timer = 0; // Go to next channel ch_i = (ch_i+1)%3; hal_nrf_set_rf_channel(default_channels[ch_i]); #ifdef DEBUG_LED_ P0 = ch_i; #endif // After changing channels and being in the LISTENING state // for 'a while', boot loader loop will check if there is firmware // installed, and if so end the while(running) loop. bootloader_timer++; if (bootloader_timer > BOOTLOADER_TIMEOUT) { bootloader_timer = 0; running = (hal_flash_byte_read(FW_INSTALLED) == 0x01) ? false : true; } } // While connected must receive something or connection times out. // Connection timer reset when packet received. } else if (state == CONNECTED) { connection_timer++; if (connection_timer > CONNECTION_TIMEOUT) { state = LISTENING; } } } resetRF(); #ifdef DEBUG_LED_ // Default value for P0DIR P0 = 0x00; P0DIR = 0xFF; #endif EA = ea_default; RF = rf_default; // Reads address of firmware's reset vector. temp_data[0] = hal_flash_byte_read(FW_RESET_ADDR_H); temp_data[1] = hal_flash_byte_read(FW_RESET_ADDR_L); firmware = (firmware_start)(((uint16_t)temp_data[0]<<8) | (temp_data[1])); // Jump to firmware. Goodbye! firmware(); }
uint8_t agent_action( uint8_t src, uint8_t dst, uint8_t sta, uint8_t seq, uint8_t *dat, uint8_t dat_len, uint8_t *out_dat, uint8_t* out_dat_len) { if(dst != my_addr && (dst != UART_ADDR || src != UART_ADDR)) return RES_FWD_DST; if(sta & STA_ACK_FLAG) if(sta & STA_UART_FLAG) return RES_FWD_UART; else return RES_NOP; if(dat[0] == CMD_FWD) return RES_FWD_UART; out_dat[0] = dat[0]; switch(dat[0]) { case CMD_NOP: *out_dat_len = dat_len; break; case CMD_SET_PORT: PORT_0 |= dat[1] & dat[2] & PORT_0_MASK; PORT_0 &= dat[1] | ~dat[2] | ~PORT_0_MASK; PORT_1 |= dat[3] & dat[4] & PORT_1_MASK; PORT_1 &= dat[3] | ~dat[4] | ~PORT_1_MASK; case CMD_GET_PORT: out_dat[1] = PORT_0 & dat[2]; out_dat[2] = PORT_0_MASK & dat[2]; out_dat[3] = PORT_1 & dat[4]; out_dat[4] = PORT_1_MASK & dat[4]; *out_dat_len = 5; break; case CMD_SET_DIR: PORT_0_DIR |= dat[1] & dat[2] & PORT_0_MASK; PORT_0_DIR &= dat[1] | ~dat[2] | ~PORT_0_MASK; PORT_1_DIR |= dat[3] & dat[4] & PORT_1_MASK; PORT_1_DIR &= dat[3] | ~dat[4] | ~PORT_1_MASK; case CMD_GET_DIR: out_dat[1] = PORT_0_DIR & dat[2]; out_dat[2] = PORT_0_MASK & dat[2]; out_dat[3] = PORT_1_DIR & dat[4]; out_dat[4] = PORT_1_MASK & dat[4]; *out_dat_len = 5; break; case CMD_SET_ADDR: PCON &= ~PMW; hal_flash_page_erase(NV_PAGE_ADDR); hal_flash_byte_write(NV_ADDR_ADDR, dat[1]); my_addr = hal_flash_byte_read(NV_ADDR_ADDR); agent_set_my_addr(); case CMD_GET_ADDR: out_dat[1] = my_addr; *out_dat_len = 2; break; default: *out_dat_len = 1; break; } return RES_REP_SRC; }