/* Send function. * Write to send_buf[1] - send_buf[31] before calling this function. * command will be placed in send_buf[0].*/ void send(command_t command) { uint8_t i; // Set operation mode to transmit. CE_LOW(); hal_nrf_set_operation_mode(HAL_NRF_PTX); // Copy command to send buffer. send_buf[0] = command; hal_nrf_write_tx_payload(send_buf, PAYLOAD_SIZE); // Activate sender CE_PULSE(); send_success = false; // Wait for radio to transmit while (RFF != 1) ; RFF = 0; nrf_irq(); // Clear send buffer. for (i = 0; i < PAYLOAD_SIZE; i++) { send_buf[i] = 0x00; } // Reset operation mode to receive. hal_nrf_set_operation_mode(HAL_NRF_PRX); CE_HIGH(); }
/* Send function. * Write to send_buf[1] - send_buf[31] before calling this function. * command will be placed in send_buf[0].*/ static void send(command_t command, uint8_t size) //size includes cmd { send_success = false; packet_received = false; // Copy command to send buffer. send_buf[0] = command; rf_write_payload(send_buf, size); // Activate sender CE_H; // Wait for radio to transmit irq_wait_flag(rf_irq_flag) ; nrf_irq(); CE_L; }
/* 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(); }