void Waypoints::set_waypoint_with_index(Waypoints::WP wp, uint8_t i) { i = constrain(i, 0, _total); uint32_t mem = _start_byte + (i * _wp_size); eeprom_busy_wait(); eeprom_write_byte((uint8_t *) mem, wp.id); mem++; eeprom_busy_wait(); eeprom_write_byte((uint8_t *) mem, wp.p1); mem++; eeprom_busy_wait(); eeprom_write_dword((uint32_t *) mem, wp.alt); mem += 4; eeprom_busy_wait(); eeprom_write_dword((uint32_t *) mem, wp.lat); mem += 4; eeprom_busy_wait(); eeprom_write_dword((uint32_t *) mem, wp.lng); }
void init_lifetime_stats() { eeprom_write_dword((uint32_t*)(LIFETIME_EEPROM_OFFSET + 0), LIFETIME_MAGIC); eeprom_write_dword((uint32_t*)(LIFETIME_EEPROM_OFFSET + 4), 0); eeprom_write_dword((uint32_t*)(LIFETIME_EEPROM_OFFSET + 8), 0); eeprom_write_dword((uint32_t*)(LIFETIME_EEPROM_OFFSET + 12), 0); eeprom_write_dword((uint32_t*)(LIFETIME_EEPROM_OFFSET + 16), 0); }
static void save_lifetime_stats() { eeprom_write_dword((uint32_t*)(LIFETIME_EEPROM_OFFSET + 0), LIFETIME_MAGIC); eeprom_write_dword((uint32_t*)(LIFETIME_EEPROM_OFFSET + 4), lifetime_minutes); eeprom_write_dword((uint32_t*)(LIFETIME_EEPROM_OFFSET + 8), lifetime_print_minutes); eeprom_write_dword((uint32_t*)(LIFETIME_EEPROM_OFFSET + 12), triptime_minutes); eeprom_write_dword((uint32_t*)(LIFETIME_EEPROM_OFFSET + 16), triptime_print_minutes); }
void heater_save_settings() { #ifndef BANG_BANG heater_t i; for (i = 0; i < NUM_HEATERS; i++) { eeprom_write_dword((uint32_t *) &EE_factors[i].EE_p_factor, heaters_pid[i].p_factor); eeprom_write_dword((uint32_t *) &EE_factors[i].EE_i_factor, heaters_pid[i].i_factor); eeprom_write_dword((uint32_t *) &EE_factors[i].EE_d_factor, heaters_pid[i].d_factor); eeprom_write_word((uint16_t *) &EE_factors[i].EE_i_limit, heaters_pid[i].i_limit); } #endif /* BANG_BANG */ }
void zoSmsRestoreDefaults(void) { eeprom_write_byte((u08*)ZO_EEPROM_ADDRESS_NODE_ID, ZO_DEFAULT_NODE_ID); eeprom_write_word((u16*)ZO_EEPROM_ADDRESS_GAIN_P, ZO_DEFAULT_GAIN_P); eeprom_write_word((u16*)ZO_EEPROM_ADDRESS_GAIN_I, ZO_DEFAULT_GAIN_I); eeprom_write_word((u16*)ZO_EEPROM_ADDRESS_GAIN_D, ZO_DEFAULT_GAIN_D); eeprom_write_word((u16*)ZO_EEPROM_ADDRESS_CURRENT_LIMIT, ZO_DEFAULT_CURRENT_LIMIT); eeprom_write_word((u16*)ZO_EEPROM_ADDRESS_CURRENT_LIMIT_DURATION, ZO_DEFAULT_CURRENT_LIMIT_DURATION); eeprom_write_byte((u08*)ZO_EEPROM_ADDRESS_DIGITAL_IO_CONFIG, ZO_DEFAULT_DIGITAL_IO_CONFIG); eeprom_write_dword((u32*)ZO_EEPROM_ADDRESS_BAUD_UART, ZO_DEFAULT_BAUD_UART); eeprom_write_dword((u32*)ZO_EEPROM_ADDRESS_BAUD_I2C, ZO_DEFAULT_BAUD_I2C); eeprom_write_word((u16*)ZO_EEPROM_ADDRESS_PROFILE_ACCELERATION, ZO_DEFAULT_PROFILE_ACCELERATION); eeprom_write_word((u16*)ZO_EEPROM_ADDRESS_PROFILE_VELOCITY, ZO_DEFAULT_PROFILE_VELOCITY); eeprom_write_byte((u08*)ZO_EEPROM_ADDRESS_LAM, ZO_DEFAULT_LAM); eeprom_write_byte((u08*)ZO_EEPROM_ADDRESS_ERROR_REPORTING_LVL, ZO_DEFAULT_ERROR_REPORTING_LVL); }
bool import_bank(const uint8_t bank, const char* data) { // Abort if the supplied string is too short if (strlen(data) < 8*PROGRAMS_PER_BANK) { return false; } // Abort if the bank index is too big if (bank > 11) { return false; } uint8_t offset = bank * PROGRAMS_PER_BANK; char* hex_dword = " "; // Store programs for (uint8_t i=0; i < PROGRAMS_PER_BANK; ++i) { strncpy(hex_dword, data, 8); eeprom_write_dword(&program_data_storage[offset+i], strtoul(hex_dword, NULL, 16)); data += 8; wdt_reset(); } return true; }
/** * Write a single 32 bits integer */ bool Eeprom::writeLong(int address, uint32_t value) { if (!isWriteOk(address + sizeof(uint32_t))) return false; eeprom_write_dword((unsigned long *) address, value); return true; }
void seed_rand() { uint32_t next_seed = eeprom_read_dword( (uint32_t*)SEED_ADDR ); srandom( next_seed ); eeprom_write_dword( (uint32_t*)SEED_ADDR, random() ); }
// save a fence point void AP_Limit_Geofence::set_fence_point_with_index(Vector2l &point, uint8_t i) { uint32_t mem; if (i >= (unsigned)fence_total()) { // not allowed return; } mem = _eeprom_fence_start + (i * _fence_wp_size); eeprom_write_dword((uint32_t *)mem, point.x); mem += sizeof(uint32_t); eeprom_write_dword((uint32_t *)mem, point.y); _boundary_uptodate = false; }
static void test_overflow_into_4th_byte() { test("test_overflow_into_4th_byte"); uint32_t *memory = (uint32_t *)108; eeprom_write_dword(memory, 0x00FFFFFF); uint32_t result = increment_eeprom_uint32(memory); assert(result == 0x01000000); assert(eeprom_read_dword(memory) == 0x01000000); }
static void test_byte_overflow() { test("test_byte_overflow"); uint32_t *memory = (uint32_t *)104; eeprom_write_dword(memory, 0xFF); uint32_t result = increment_eeprom_uint32(memory); assert(result == 0x100); assert(eeprom_read_dword(memory) == 0x100); }
static void test_simple_increment() { test("test_simple_increment"); uint32_t *memory = (uint32_t *)100; eeprom_write_dword(memory, 1); uint32_t result = increment_eeprom_uint32(memory); assert(result == 2); assert(eeprom_read_dword(memory) == 2); }
void inline eeprom_write_float(float* addr, float f) { union { uint32_t i; float f; } n; n.f = f; eeprom_write_dword((uint32_t*)addr, n.i); }
static void test_rollover_to_zero() { test("test_rollover_to_zero"); uint32_t *memory = (uint32_t *)112; eeprom_write_dword(memory, 0xFFFFFFFF); eeprom_write_byte((uint8_t *)memory + 4, 0xa5); uint32_t result = increment_eeprom_uint32(memory); assert(result == 0x00000000); assert(eeprom_read_dword(memory) == 0x00000000); assert(eeprom_read_byte((uint8_t *)memory + 4) == 0xa5); }
static void do_serialnumber(int direction, unsigned int vWalue) { uint32_t snum; if (direction == ENDPOINT_DIR_OUT) { Endpoint_Read_Control_Stream_LE(&snum, sizeof(snum)); eeprom_write_dword(&serialno, snum); } else if (direction == ENDPOINT_DIR_IN) { snum = eeprom_read_dword(&serialno); Endpoint_Write_Control_Stream_LE(&snum, sizeof(snum)); } }
ALWBase::ALWBase() { /* * XXX: For some reason, this messes things up if it runs in init(). * It must have something to do with the timing: Calling it before * Arduino's core init code is okay, but after is not. Bizarre. * One thread suggested it's the WDT, but I don't think so. */ static uint32_t EEMEM storedRandomSeed; uint32_t randomSeed = eeprom_read_dword(&storedRandomSeed); srandom(randomSeed); eeprom_write_dword(&storedRandomSeed, random()); }
/* setSerialEEPROM() - sets the Waspmote unique serial identifier to EEPROM * * The serial id to be stored is specified as input */ bool WaspUtils::setSerialEEPROM( unsigned long serial ) { // Store to EEPROM eeprom_write_dword( (uint32_t*)EEPROM_SERIALID_START, serial ); // check EEPROM if( serial == getSerialEEPROM() ) { return true; } return false; }
uint32_t get_seed(uint32_t* eeprom_begin, uint32_t* eeprom_end) { uint32_t* ptr; uint32_t seed = eeprom_read_dword(eeprom_begin); for (ptr=eeprom_begin+1; ptr<eeprom_end; ++ptr) if (++seed != eeprom_read_dword(ptr)) break; if (ptr >= eeprom_end) ptr = eeprom_begin; eeprom_write_dword(ptr, seed); if (seed == 0) seed = 0xaaaaaaaa; return seed; }
const char PROGMEM *settingsLineSetNotifyValue(char *buf, uint16_t len, uint8_t index) { if (index > 3) { return TOO_MANY_NOTIFY; } if (currentSetLineIdx >= lineInputSize){ return NO_NOTIFY_OUTPUT; } float value = atof(buf); uint8_t type = pgm_read_byte(&lineInputDescription[currentSetLineIdx].type); LineInputConversion conversion = (LineInputConversion) pgm_read_word(&(lineInputDescription[currentSetLineIdx].convertValue)); if (value > conversion(type == ANALOG ? 1023 : 1) || value < conversion(0)) { return PSTR("notify value overflow"); } eeprom_write_dword((uint32_t *) &lineInputSettings[currentSetLineIdx].notifies[index].value, *((unsigned long *)&value)); return 0; }
void send_dimmer_status(void) { UART_PUTS("Sending Dimmer Status:\r\n"); // set device ID bufx[0] = device_id; // update packet counter packetcounter++; if (packetcounter % PACKET_COUNTER_WRITE_CYCLE == 0) { eeprom_write_dword((uint32_t*)0, packetcounter); } setBuf32(1, packetcounter); // set command ID "Dimmer Status" bufx[5] = 30; // TODO: Move command IDs to global definition file as defines // set current brightness bufx[6] = (uint8_t)(current_brightness * 255 / 100); // set end brightness bufx[7] = end_brightness; // set total animation time setBuf16(8, (uint16_t)(animation_length * ANIMATION_CYCLE_MS / 1000)); // set time until animation finishes setBuf16(10, (uint16_t)((animation_length - animation_position) * ANIMATION_CYCLE_MS / 1000)); // set CRC32 uint32_t crc = crc32(bufx, 12); setBuf32(12, crc); // show info UART_PUTF("CRC32: %lx\r\n", crc); uart_putstr("Unencrypted: "); printbytearray(bufx, 16); rfm12_sendbuf(); UART_PUTS("Send encrypted: "); printbytearray(bufx, 16); UART_PUTS("\r\n"); }
int main() { stdout = &mystdout; // read the eeprom value uint32_t c = eeprom_read_dword((void*)&value); printf("Read from eeprom 0x%08lx -- should be 0xdeadbeef\n", c); // change the eeprom eeprom_write_dword((void*)&value, 0xcafef00d); // re-read it c = eeprom_read_dword((void*)&value); printf("Read from eeprom 0x%08lx -- should be 0xcafef00d\n", c); // this quits the simulator, since interupts are off // this is a "feature" that allows running tests cases and exit sleep_cpu(); }
void send_packet(uint8_t aes_key_nr, uint8_t data_len) { // set device ID (base station has ID 0 by definition) bufx[0] = 0; // update packet counter packetcounter++; if (packetcounter % PACKET_COUNTER_WRITE_CYCLE == 0) { eeprom_write_dword((uint32_t*)0, packetcounter); } setBuf32(1, packetcounter); // set CRC32 uint32_t crc = crc32(bufx, data_len + 6); setBuf32(data_len + 6, crc); // load AES key (0 is first AES key) if (aes_key_nr >= AES_KEY_EEPROM_COUNT) { aes_key_nr = AES_KEY_EEPROM_COUNT - 1; } eeprom_read_block (aes_key, (uint8_t *)(EEPROM_POS_AES_KEY + aes_key_nr * 32), 32); // show info decode_data(data_len + 6); UART_PUTF(" AES key: %u\r\n", aes_key_nr); UART_PUTF(" CRC32: %02lx\r\n", crc); UART_PUTS(" Unencrypted: "); printbytearray(bufx, data_len + 10); // encrypt and send uint8_t aes_byte_count = rfm12_sendbuf(data_len + 10); UART_PUTS("Send encrypted: "); printbytearray(bufx, aes_byte_count); UART_PUTS("\r\n"); }
int answer_record(char* filename1, char* filename2, char use_beep) // Отвечает, записывает сообщение, { if (answer_play(filename1)) return 1; // Отвечаем, предлагаем оставить сообщение if (use_beep) beep(3000, 500); // Биип sprintf(buffer, "/%08lu.wav", record_num); // Формируем имя файла clunet_send(CLUNET_BROADCAST_ADDRESS, CLUNET_PRIORITY_INFO, CLUNET_COMMAND_INTERCOM_MESSAGE, (char*)&record_num, sizeof(record_num)); // Отправляем в сеть сообщение record_num++; eeprom_write_dword((void*)0, record_num); // Запоминаем кол-во записей if (rec_wav(buffer) == 0) // Пишем сообщение { int s = 0; long int totalSize = 0; while (s >= 0 && totalSize < 8000UL*RECORD_MAX_LENGTH) { s = sound_write(); totalSize += s; if (!LINE_POWER || OFFHOOK) // Сняли трубку, или сигнал исчез { sound_stop(); return 1; } } sound_stop(); } if (play_wav_pgm(filename2) == 0) // Если пациент дождался, благодарим { while (sound_read() >= 0) { if (!LINE_POWER || OFFHOOK) // Сняли трубку, или сигнал исчез { sound_stop(); return 1; } } sound_stop(); } return 0; }
void settingsLineOutputSetValue(uint8_t outputIdx, float value) { eeprom_write_dword((uint32_t *) &lineOutputSettings[outputIdx].lastValue, *((unsigned long *)&value)); }
int main ( void ) { uint8_t aes_key_nr; uint8_t loop = 0; uint8_t loop2 = 0; uint8_t data[22]; sbi(LED_DDR, LED_PIN); // delay 1s to avoid further communication with uart or RFM12 when my programmer resets the MC after 500ms... _delay_ms(1000); request_queue_init(); // read packetcounter, increase by cycle and write back packetcounter = eeprom_read_dword((uint32_t*)EEPROM_POS_PACKET_COUNTER) + PACKET_COUNTER_WRITE_CYCLE; eeprom_write_dword((uint32_t*)0, packetcounter); uart_init(true); UART_PUTS ("\r\n"); UART_PUTS ("Open Home Control Base Station V1.0\r\n"); UART_PUTS ("(c) 2012 Uwe Freese, www.open-home-control.com\r\n"); UART_PUTF ("Packet counter: %lu\r\n", packetcounter); UART_PUTS ("Waiting for incoming data. Press h for help.\r\n"); rfm12_init(); sei(); // ENCODE TEST /* uint8_t testlen = 64; eeprom_read_block (aes_key, (uint8_t *)EEPROM_POS_AES_KEY, 32); UART_PUTS("Using AES key "); printbytearray((uint8_t *)aes_key, 32); UART_PUTS("Before encryption: "); printbytearray(bufx, testlen); unsigned long crc = crc32(bufx, testlen); UART_PUTF("CRC32 is %lx (added as last 4 bytes)\r\n", crc); UART_PUTS("1\r\n"); crc = crc32(bufx, testlen - 4); UART_PUTS("2\r\n"); setBuf32(testlen - 4, crc); UART_PUTS("Before encryption (CRC added): "); printbytearray(bufx, testlen); UART_PUTS("1\r\n"); uint8_t aes_byte_count = aes256_encrypt_cbc(bufx, testlen); UART_PUTS("2\r\n"); UART_PUTS("After encryption: "); printbytearray(bufx, aes_byte_count); UART_PUTF("String len = %u\r\n", aes_byte_count); UART_PUTS("1\r\n"); aes256_decrypt_cbc(bufx, aes_byte_count); UART_PUTS("2\r\n"); UART_PUTS("After decryption: "); printbytearray(bufx, testlen); crc = getBuf32(testlen - 4); UART_PUTF("CRC32 is %lx (last 4 bytes from decrypted message)\r\n", crc); printbytearray(bufx, testlen); UART_PUTS("After decryption (CRC removed): "); printbytearray(bufx, testlen); UART_PUTF("String len = %u\r\n", testlen); while(1); */ while (42) { if (rfm12_rx_status() == STATUS_COMPLETE) { uint8_t len = rfm12_rx_len(); if ((len == 0) || (len % 16 != 0)) { UART_PUTF("Received garbage (%u bytes not multiple of 16): ", len); printbytearray(bufx, len); } else // try to decrypt with all keys stored in EEPROM { uint32_t assumed_crc; uint32_t actual_crc; for(aes_key_nr = 0; aes_key_nr < AES_KEY_EEPROM_COUNT ; aes_key_nr++) { //strncpy((char *)bufx, (char *)rfm12_rx_buffer(), len); memcpy(bufx, rfm12_rx_buffer(), len); /*if (aes_key_nr == 0) { UART_PUTS("Before decryption: "); printbytearray(bufx, len); }*/ eeprom_read_block (aes_key, (uint8_t *)(EEPROM_POS_AES_KEY + aes_key_nr * 32), 32); //UART_PUTS("Trying AES key "); //printbytearray((uint8_t *)aes_key, 32); aes256_decrypt_cbc(bufx, len); //UART_PUTS("Decrypted bytes: "); //printbytearray(bufx, len); assumed_crc = getBuf32(len - 4); actual_crc = crc32(bufx, len - 4); //UART_PUTF("Received CRC32 would be %lx\r\n", assumed_crc); //UART_PUTF("Re-calculated CRC32 is %lx\r\n", actual_crc); if (assumed_crc == actual_crc) { //UART_PUTS("CRC correct, AES key found!\r\n"); UART_PUTF("Received (AES key %u): ", aes_key_nr); printbytearray(bufx, len - 4); decode_data(len - 4); break; } } if (assumed_crc != actual_crc) { UART_PUTS("Received garbage (CRC wrong after decryption).\r\n"); } UART_PUTS("\r\n"); } //uart_hexdump((char *)bufcontents, rfm12_rx_len()); //UART_PUTS("\r\n"); // tell the implementation that the buffer can be reused for the next data. rfm12_rx_clear(); } // send data, if waiting in send buffer if (send_data_avail) { uint8_t i; uint8_t data_len_raw = strlen(sendbuf) / 2 - 2; // round data length to 6 + 16 bytes (including padding bytes) uint8_t data_len = (((data_len_raw + 9) / 16) + 1) * 16 - 10; // set aes key nr aes_key_nr = hex_to_uint8((uint8_t *)sendbuf, 0); //UART_PUTF("AES KEY = %u\r\n", aes_key_nr); // set command id uint8_t command_id = hex_to_uint8((uint8_t *)sendbuf, 2); // set data for (i = 0; i < data_len_raw; i++) { data[i] = hex_to_uint8((uint8_t *)sendbuf, 4 + 2 * i); } // set padding bytes for (i = data_len_raw; i < data_len; i++) { data[i] = 0; } // send status packet immediately (command IDs are less than 128) if (command_id < 128) { // set command id bufx[5] = command_id; // set data memcpy(bufx + 6, data, data_len); send_packet(aes_key_nr, data_len); } else // enqueue request (don't send immediately) { if (queue_request(data[0], command_id, aes_key_nr, data + 1)) { UART_PUTS("Adding request to queue.\r\n"); } else { UART_PUTS("Warning! Request queue full. Packet will not be sent.\r\n"); } print_request_queue(); } // clear send text buffer send_data_avail = false; rfm12_tick(); led_blink(200, 0, 1); } // flash LED every second to show the device is alive if (loop == 50) { led_blink(10, 10, 1); loop = 0; if (set_repeat_request(packetcounter + 1)) // if request to repeat was found in queue { UART_PUTS("Repeating request.\r\n"); send_packet(0, 6); print_request_queue(); } // Auto-send something for debugging purposes... if (loop2 == 50) { //strcpy(sendbuf, "008c0001003d"); //send_data_avail = true; loop2 = 0; } else { loop2++; } } else { _delay_ms(20); } rfm12_tick(); loop++; process_rxbuf(); if (uart_timeout > 0) { uart_timeout--; if (uart_timeout == 0) { UART_PUTS("*** UART user timeout. Input was ignored. ***\r\n"); } } } // never called // aes256_done(&aes_ctx); }
inline void epr_set_long(uint pos,long value) { eeprom_write_dword((unsigned long*)(EEPROM_OFFSET+pos),value); }
void ReefAngel_EEPROMClass::write_dword(int address, const uint32_t value) { eeprom_write_dword((uint32_t *) address, (uint32_t) value); }
int main(void) { uint16_t send_status_timeout = 25; uint32_t station_packetcounter; uint32_t pos; uint8_t button_state = 0; uint8_t manual_dim_direction = 0; // delay 1s to avoid further communication with uart or RFM12 when my programmer resets the MC after 500ms... _delay_ms(1000); util_init(); check_eeprom_compatibility(DEVICE_TYPE_DIMMER); osccal_init(); // read packetcounter, increase by cycle and write back packetcounter = eeprom_read_dword((uint32_t*)EEPROM_POS_PACKET_COUNTER) + PACKET_COUNTER_WRITE_CYCLE; eeprom_write_dword((uint32_t*)EEPROM_POS_PACKET_COUNTER, packetcounter); // read device id and write to send buffer device_id = eeprom_read_byte((uint8_t*)EEPROM_POS_DEVICE_ID); use_pwm_translation = 1; //eeprom_read_byte((uint8_t*)EEPROM_POS_USE_PWM_TRANSLATION); // TODO: read (saved) dimmer state from before the eventual powerloss /*for (i = 0; i < SWITCH_COUNT; i++) { uint16_t u16 = eeprom_read_word((uint16_t*)EEPROM_POS_SWITCH_STATE + i * 2); switch_state[i] = (uint8_t)(u16 & 0b1); switch_timeout[i] = u16 >> 1; }*/ // read last received station packetcounter station_packetcounter = eeprom_read_dword((uint32_t*)EEPROM_POS_STATION_PACKET_COUNTER); led_blink(200, 200, 5); #ifdef UART_DEBUG uart_init(false); UART_PUTS ("\r\n"); UART_PUTS ("smarthomatic Dimmer V1.0 (c) 2013 Uwe Freese, www.smarthomatic.org\r\n"); osccal_info(); UART_PUTF ("Device ID: %u\r\n", device_id); UART_PUTF ("Packet counter: %lu\r\n", packetcounter); UART_PUTF ("Use PWM translation table: %u\r\n", use_pwm_translation); UART_PUTF ("Last received station packet counter: %u\r\n\r\n", station_packetcounter); #endif // init AES key eeprom_read_block (aes_key, (uint8_t *)EEPROM_POS_AES_KEY, 32); rfm12_init(); PWM_init(); io_init(); setPWMDutyCycle(0); timer0_init(); // DEMO to measure the voltages of different PWM settings to calculate the pwm_lookup table /*while (42) { uint16_t i; for (i = 0; i <= 1024; i = i + 100) { UART_PUTF ("PWM value OCR1A: %u\r\n", i); OCR1A = i; led_blink(500, 6500, 1); } }*/ // DEMO 0..100..0%, using the pwm_lookup table and the translation table in EEPROM. /*while (42) { float i; for (i = 0; i <= 100; i = i + 0.05) { led_blink(10, 10, 1); setPWMDutyCycle(i); } for (i = 99.95; i > 0; i = i - 0.05) { led_blink(10, 10, 1); setPWMDutyCycle(i); } }*/ // set initial switch state /*for (i = 0; i < SWITCH_COUNT; i++) { switchRelais(i, switch_state[i]); }*/ sei(); // DEMO 30s /*animation_length = 30; animation_length = (uint32_t)((float)animation_length * 1000 / ANIMATION_CYCLE_MS); start_brightness = 0; end_brightness = 255; animation_position = 0;*/ while (42) { if (rfm12_rx_status() == STATUS_COMPLETE) { uint8_t len = rfm12_rx_len(); if ((len == 0) || (len % 16 != 0)) { UART_PUTF("Received garbage (%u bytes not multiple of 16): ", len); printbytearray(bufx, len); } else // try to decrypt with all keys stored in EEPROM { memcpy(bufx, rfm12_rx_buffer(), len); //UART_PUTS("Before decryption: "); //printbytearray(bufx, len); aes256_decrypt_cbc(bufx, len); //UART_PUTS("Decrypted bytes: "); //printbytearray(bufx, len); uint32_t assumed_crc = getBuf32(len - 4); uint32_t actual_crc = crc32(bufx, len - 4); //UART_PUTF("Received CRC32 would be %lx\r\n", assumed_crc); //UART_PUTF("Re-calculated CRC32 is %lx\r\n", actual_crc); if (assumed_crc != actual_crc) { UART_PUTS("Received garbage (CRC wrong after decryption).\r\n"); } else { //UART_PUTS("CRC correct, AES key found!\r\n"); UART_PUTS(" Received: "); printbytearray(bufx, len - 4); // decode command and react uint8_t sender = bufx[0]; UART_PUTF(" Sender: %u\r\n", sender); if (sender != 0) { UART_PUTF("Packet not from base station. Ignoring (Sender ID was: %u).\r\n", sender); } else { uint32_t packcnt = getBuf32(1); UART_PUTF(" Packet Counter: %lu\r\n", packcnt); // check received counter if (0) //packcnt <= station_packetcounter) { UART_PUTF2("Received packet counter %lu is lower than last received counter %lu. Ignoring packet.\r\n", packcnt, station_packetcounter); } else { // write received counter station_packetcounter = packcnt; eeprom_write_dword((uint32_t*)EEPROM_POS_STATION_PACKET_COUNTER, station_packetcounter); // check command ID uint8_t cmd = bufx[5]; UART_PUTF(" Command ID: %u\r\n", cmd); if (cmd != 141) // ID 141 == Dimmer Request { UART_PUTF("Received unknown command ID %u. Ignoring packet.\r\n", cmd); } else { // check device id uint8_t rcv_id = bufx[6]; UART_PUTF(" Receiver ID: %u\r\n", rcv_id); if (rcv_id != device_id) { UART_PUTF("Device ID %u does not match. Ignoring packet.\r\n", rcv_id); } else { // read animation mode and parameters uint8_t animation_mode = bufx[7] >> 5; // TODO: Implement support for multiple dimmers (e.g. RGB) // uint8_t dimmer_bitmask = bufx[7] & 0b111; animation_length = getBuf16(8); start_brightness = bufx[10]; end_brightness = bufx[11]; UART_PUTF(" Animation Mode: %u\r\n", animation_mode); // TODO: Set binary mode like 00010110 //UART_PUTF(" Dimmer Bitmask: %u\r\n", dimmer_bitmask); UART_PUTF(" Animation Time: %us\r\n", animation_length); UART_PUTF(" Start Brightness: %u\r\n", start_brightness); UART_PUTF(" End Brightness: %u\r\n", end_brightness); animation_length = (uint32_t)((float)animation_length * 1000 / ANIMATION_CYCLE_MS); animation_position = 0; /* TODO: Write to EEPROM (?) // write back switch state to EEPROM switch_state[i] = req_state; switch_timeout[i] = req_timeout; eeprom_write_word((uint16_t*)EEPROM_POS_SWITCH_STATE + i * 2, u16); */ // send acknowledge UART_PUTS("Sending ACK:\r\n"); // set device ID (base station has ID 0 by definition) bufx[0] = device_id; // update packet counter packetcounter++; if (packetcounter % PACKET_COUNTER_WRITE_CYCLE == 0) { eeprom_write_dword((uint32_t*)0, packetcounter); } setBuf32(1, packetcounter); // set command ID "Generic Acknowledge" bufx[5] = 1; // set sender ID of request bufx[6] = sender; // set Packet counter of request setBuf32(7, station_packetcounter); // zero unused bytes bufx[11] = 0; // set CRC32 uint32_t crc = crc32(bufx, 12); setBuf32(12, crc); // show info UART_PUTF(" CRC32: %lx\r\n", crc); uart_putstr(" Unencrypted: "); printbytearray(bufx, 16); rfm12_sendbuf(); UART_PUTS(" Send encrypted: "); printbytearray(bufx, 16); UART_PUTS("\r\n"); rfm12_tick(); led_blink(200, 0, 1); send_status_timeout = 25; } } } } } } // tell the implementation that the buffer can be reused for the next data. rfm12_rx_clear(); } _delay_ms(ANIMATION_UPDATE_MS); // React on button press. // - abort animation // - switch off, when brightness > 0 // - switch on otherwise if (!(BUTTON_PORT & (1 << BUTTON_PIN))) // button press { if (button_state == 0) { UART_PUTS("Button pressed\r\n"); animation_length = 0; animation_position = 0; } if (button_state < 5) { button_state++; } else // manual dimming { if (manual_dim_direction) // UP { if (current_brightness < 100) { current_brightness = (uint8_t)current_brightness / 2 * 2 + 2; setPWMDutyCycle(current_brightness); } else { UART_PUTS("manual dimming DOWN\r\n"); manual_dim_direction = 0; } } else // DOWN { if (current_brightness > 0) { current_brightness = (((uint8_t)current_brightness - 1) / 2) * 2; setPWMDutyCycle(current_brightness); } else { UART_PUTS("manual dimming UP\r\n"); manual_dim_direction = 1; } } } } else if (button_state && (BUTTON_PORT & (1 << BUTTON_PIN))) // button release { UART_PUTS("Button released\r\n"); if (button_state < 5) // short button press { if (current_brightness > 0) { UART_PUTS(" -> 0%\r\n"); setPWMDutyCycle(0); } else { UART_PUTS(" -> 100%\r\n"); setPWMDutyCycle(100); } } else { // reverse dim direction manual_dim_direction = !manual_dim_direction; } button_state = 0; } // update brightness according animation_position, updated by timer0 if (animation_length > 0) { pos = animation_position; // copy value to avoid that it changes in between by timer interrupt UART_PUTF2("%lu/%lu, ", pos, animation_length); if (pos == animation_length) { UART_PUTF("END Brightness %u%%, ", end_brightness * 100 / 255); setPWMDutyCycle((float)end_brightness * 100 / 255); animation_length = 0; animation_position = 0; } else { float brightness = (start_brightness + ((float)end_brightness - start_brightness) * pos / animation_length) * 100 / 255; UART_PUTF("Br.%u%%, ", (uint32_t)(brightness)); setPWMDutyCycle(brightness); } } // send status from time to time if (send_status_timeout == 0) { send_status_timeout = SEND_STATUS_EVERY_SEC * (1000 / ANIMATION_UPDATE_MS); send_dimmer_status(); led_blink(200, 0, 1); } rfm12_tick(); send_status_timeout--; checkSwitchOff(); }
void write_program(uint8_t number, uint32_t data) { eeprom_write_dword(&program_data_storage[number], data); }
int main() { long int savedfreq = 0; int s, c; unsigned char sw=0; // PORTB output for LCD DDRB = 0xff; PORTB = 0xff; #ifdef BOARD2 // PORTC PC0-4 output, PC5 input DDRC = 0x1f; PORTC = 0x00; sbi(PORTC, MUTE); #endif #ifdef BOARD1 // PORTC PC0,2-5 output, PC1 input DDRC = 0x3d; PORTC = 0x00; sbi(PORTC, MUTE); #endif // PORTD is input with pullup DDRD = 0x00; PORTD = 0xff; initLcd(); initADC(); // set reference freq fref = eeprom_read_word((unsigned int *)0x00); if (fref < 2000 || (fref % 100) != 0) { fref = 12000; eeprom_write_word((unsigned int *)0x00, fref); } // read squelch level from eeprom muteval = eeprom_read_word((unsigned int *)0x0c); if (muteval < 0 || muteval > 100) { muteval = 0; eeprom_write_word((unsigned int *)0x0c, muteval); } // read last frequency from eeprom freq = eeprom_read_dword((unsigned long int *)0x10); if (freq < 1240000UL || freq > 1300000UL) { freq = 1298375UL; eeprom_write_dword((unsigned long int *)0x10, freq); } // read shift from eeprom shift = eeprom_read_word((unsigned int *)0x18); if (shift < 60000UL || shift > 60000UL) { shift = -28000UL; eeprom_write_word((unsigned int *)0x18, shift); } // read tone (*10) from eeprom tone = eeprom_read_word((unsigned int *)0x1c); if (tone < 650 || tone > 1500) { tone = 650; eeprom_write_word((unsigned int *)0x1c, tone); } initInterrupts(); initPLL(freq - IF); update(); sprintf(str, "JPD 23cm v%s", version); lcdCmd(0x80); lcdStr(str); _delay_ms(500); for (;;) { lcdCmd(0x80); lcdStr("VFO "); lcdCmd(0xc0); lcdStr(" "); update(); for (;;) { // read switches on PORTD sw = PIND; // switch from tx to rx?? if (tx && (sw & (1<<PTT) )) { cbi(PORTC, TXON); // switch TX off tx = FALSE; // TCCR2A &= ~(1<<COM2A1); update(); } // switch from rx to tx? else if (!tx && !(sw & (1<<PTT) )) { tx = TRUE; displaySmeter(0); // switch TX on sbi(PORTC, TXON); sbi(PORTC, MUTE); // if (tone > 650) { // TCCR2A |= (1<<COM2A1); // } update(); } if (!tx) { s = readSmeter(); displaySmeter(s); if (s > muteval) cbi(PORTC, MUTE); else sbi(PORTC, MUTE); } // switch shift off if ( (shiftSwitch == TRUE) && (sw & (1<<SHIFTKEY) )) { shiftSwitch = FALSE; update(); } // switch shift on else if ( (shiftSwitch == FALSE) && !(sw & (1<<SHIFTKEY) )) { shiftSwitch = TRUE; update(); } // save vfo frequency in eeprom after ~2 secs inactivity if (tick > 200) { if (freq != savedfreq) { eeprom_write_dword((unsigned long int *)0x10, freq); savedfreq = freq; } } // handle encoder pulses c = handleRotary(); if (c!=0) { if (c>0) { freq += step; } else { freq -= step; } tick = 0; update(); } if (rotaryPushed()) { doMenu(); break; } } } }