#include "storage_interface.h" #include #include // Manual implements of EEPROM.put() for few uint type uint16_t inline read_eeprom_uint16(uint8_t idx){ uint8_t tmp; tmp = EEPROM.read(idx); // read high byte return EEPROM.read(idx + 1) | (tmp << 8); // read low byte } void inline write_eeprom_uint16(uint8_t idx, uint16_t value){ EEPROM.write(idx, value >> 8); // write high byte EEPROM.write(idx + 1, value & 0xFF); // write low byte } uint32_t inline read_eeprom_uint32(uint8_t idx) { uint32_t result = 0; // Byte 1 (High level : MSB) result |= (uint32_t)EEPROM.read(idx) << 24; // Byte 2 result |= (uint32_t)EEPROM.read(idx + 1) << 16; // Byte 3 result |= (uint32_t)EEPROM.read(idx + 2) << 8; // Byte 4 (Low level : LSB) result |= (uint32_t)EEPROM.read(idx + 3); return result; } void inline write_eeprom_uint32(uint8_t idx, uint32_t value) { // Byte 1 (High level : MSB) EEPROM.write(idx, (uint8_t)(value >> 24)); // Byte 2 EEPROM.write(idx + 1, (uint8_t)(value >> 16)); // Byte 3 EEPROM.write(idx + 2, (uint8_t)(value >> 8)); // Byte 4 (Low level : LSB) EEPROM.write(idx + 3, (uint8_t)(value & 0xFF)); } Storage_interface::Storage_interface(){} Storage_interface::~Storage_interface(){} void Storage_interface::clear_eeprom(){ for (uint16_t i = 0 ; i < EEPROM.length() ; i++) { EEPROM.write(i, 0); } } void Storage_interface::clear_eeprom_at(uint16_t idx){ for (uint16_t i = idx ; i < EEPROM.length() ; i++) { EEPROM.write(i, 0); } } // legacy function (don't finished and never tested) /* uint16_t get_nb_package_legacy(){ uint8_t flags, nb_photo_sensor, nb_temp_sensor, temp_size_t, photo_size_t, schedule, tmp, timestamp_size_t; uint16_t nb_package = 0, nb_measure, start_package = 0, timestamp_sum_size, next_position; bool timestamp; flags = EEPROM.read(start_package); while ((flags & 0b1) != 0){ nb_package++; nb_photo_sensor = EEPROM.read(start_package + OFFSET_NB_PHOTO_SENSOR); photo_size_t = EEPROM.read(start_package + OFFSET_PHOTO_MEASURES_SIZE); nb_temp_sensor = EEPROM.read(start_package + OFFSET_NB_TEMP_SENSOR); temp_size_t = EEPROM.read(start_package + OFFSET_TEMP_MEASURES_SIZE); tmp = EEPROM.read(start_package + OFFSET_NB_TEMP_SENSOR); // read high byte nb_measure = EEPROM.read(start_package + OFFSET_NB_TEMP_SENSOR + 1) | (tmp << 8); // read low byte timestamp = false; timestamp_size_t = EEPROM.read(start_package + OFFSET_timestamp_SIZE); if ((flags & 0b001) != 0 ){ timestamp = true; schedule = EEPROM.read(start_package + OFFSET_MEASURES_SCH); timestamp_sum_size = (nb_measure/schedule) * timestamp_size_t; }else if ((flags & 0b01) != 0){ timestamp = true; timestamp_sum_size = nb_measure * timestamp_size_t; }else{ timestamp_sum_size = 0; } } return nb_package; }*/ /** * @brief get_last_header_nbpackage * * * * * @param last_header_idx @c uint16_t EEPROM index of the last header * @return @c uint16_t EEPROM stored package number */ uint16_t Storage_interface::get_last_header_nbpackage(uint16_t* last_header_idx){ uint8_t flags; uint16_t start_package = 0, nb_package = 0; *last_header_idx = 0; flags = EEPROM.read(start_package); while ((flags & 0b1) != 0){ nb_package++; *last_header_idx = start_package; start_package = read_eeprom_uint16(start_package + OFFSET_NEXT_PACKAGE); flags = EEPROM.read(start_package); nb_package++; } return nb_package; } // factorise reused code implementation and keep level acces uint16_t Storage_interface::get_nb_package(){ uint16_t pointer; return get_last_header_nbpackage(&pointer); } void Storage_interface::get_store_struct(uint16_t offset, bool* timestamp, bool* is_final_set, bool* photo_sensor, bool* temp_sensor, uint8_t* timestamp_schedule, uint8_t* nb_photo_sensor, uint8_t* nb_temp_sensor, uint8_t* photo_size, uint8_t* temp_size, uint16_t* p_next_package, uint16_t* nb_measures){ uint8_t flags; flags = EEPROM.read(offset); // Checking there if a struct is possibly at the index if ((flags & 0b1) == 0){ Serial.println("Missing struct index or bad index"); return; } // timestamps reads *timestamp = false; if ((flags & 0b001) != 0 ){ *timestamp = true; *timestamp_schedule = EEPROM.read(offset + OFFSET_MEASURES_SCH); } *timestamp_schedule = 0; if (flags & 0b01){ *timestamp = true; if (EEPROM.read(offset + OFFSET_MEASURES_SCH) != 0) Serial.println("Incoherent timestamp parameter in the header."); } // photo res reads *photo_sensor = false; if (flags & 0b0001){ *photo_sensor = true; *nb_photo_sensor = EEPROM.read(offset + OFFSET_NB_PHOTO_SENSOR); } // temp res reads *temp_sensor = false; if (flags & 0b00001){ *temp_sensor = true; *nb_temp_sensor = EEPROM.read(offset + OFFSET_NB_TEMP_SENSOR); } // gather the index of the next package in the EEPROM *p_next_package = read_eeprom_uint16(offset + OFFSET_NEXT_PACKAGE); // gather the number of measures *nb_measures = read_eeprom_uint16(offset + OFFSET_NB_TEMP_SENSOR); } void Storage_interface::set_store_struct(uint16_t offset, bool timestamp, bool is_final_set, bool photo_sensor, bool temp_sensor, uint8_t timestamp_schedule, uint8_t nb_photo_sensor, uint8_t nb_temp_sensor, uint8_t photo_size, uint8_t temp_size){ uint8_t flags = 0; // Existing package flag for function package searcher flags = flags | 0b10000000; // Timestamp init struct if(timestamp_schedule != 0){ flags = flags | 0b00100000; EEPROM.write(offset + OFFSET_MEASURES_SCH, timestamp_schedule); if(!timestamp) Serial.println("Bad timestamp parameter for header writer."); }else{ EEPROM.write(offset + OFFSET_MEASURES_SCH, 0); if (timestamp) flags = flags | 0b01000000; } // Sensor part if (photo_sensor){ flags = flags | 0b00010000; EEPROM.write(offset + OFFSET_NB_PHOTO_SENSOR, nb_photo_sensor); }else{ EEPROM.write(offset + OFFSET_NB_PHOTO_SENSOR, 0); if (nb_photo_sensor != 0) Serial.println("Bad photo sensor parameter for header writer."); } if (temp_sensor){ flags = flags | 0b00001000; EEPROM.write(offset + OFFSET_NB_TEMP_SENSOR, nb_temp_sensor); }else{ EEPROM.write(offset + OFFSET_NB_TEMP_SENSOR, 0); if (nb_temp_sensor != 0) Serial.println("Bad temperature sensor parameter for header writer."); } // TODO Analyse if is_final_set just be remove from parameter if (is_final_set){ flags = flags | 0b00000100; } // uint16_t next package pointer set at 0 write_eeprom_uint16(offset + OFFSET_NEXT_PACKAGE, offset + OFFSET_START_DATA_MEASURES); // set number of measures to 0 write_eeprom_uint16(offset + OFFSET_NB_MEASURES, 0); // write flags header EEPROM.write(offset , flags); clear_eeprom_at(offset + OFFSET_START_DATA_MEASURES); } void Storage_interface::add_last_package(bool timestamp, bool is_final_set, bool photo_sensor, bool temp_sensor, uint8_t timestamp_schedule, uint8_t nb_photo_sensor, uint8_t nb_temp_sensor, uint8_t photo_size, uint8_t temp_size, uint16_t nb_measures){ uint16_t p_last_header, free_space; uint8_t flags; get_last_header_nbpackage(&p_last_header); flags = EEPROM.read(p_last_header); // change is_last_package flag flags = flags & 0b11111011; EEPROM.write(p_last_header , flags); free_space = EEPROM.read(p_last_header + OFFSET_NEXT_PACKAGE); set_store_struct(free_space, timestamp, is_final_set, photo_sensor, temp_sensor, timestamp_schedule, nb_photo_sensor, nb_temp_sensor, photo_size, temp_size); } // Dont check if the stored measure structure match with the header void Storage_interface::add_measure(uint8_t* photo_values, uint8_t* temp_values, uint32_t timestamp, uint8_t nb_photo, uint8_t nb_temp){ uint16_t p_last_header, free_space, idx; get_last_header_nbpackage(&p_last_header); free_space = EEPROM.read(p_last_header + OFFSET_NEXT_PACKAGE); EEPROM.write(p_last_header + OFFSET_NB_MEASURES, EEPROM.read(p_last_header + OFFSET_NB_MEASURES) + 1); EEPROM.put(free_space, timestamp); idx = p_last_header + int32_size; for(int i = 0; i < nb_photo; i++, idx += int8_size){ EEPROM.put(idx, photo_values[i]); } for(int i = 0; i < nb_temp; i++, idx += int8_size){ EEPROM.put(idx, temp_values[i]); } }