C++ Library for the PsiSwarm Robot - Version 0.8

Dependents:   PsiSwarm_V8_Blank_CPP Autonomia_RndmWlk

Fork of PsiSwarmV7_CPP by Psi Swarm Robot

eprom.cpp

Committer:
jah128
Date:
2016-10-17
Revision:
12:878c6e9d9e60
Parent:
8:6c92789d5f87

File content as of revision 12:878c6e9d9e60:

/** University of York Robotics Laboratory PsiSwarm Library: Eprom Functions Source File
 *
 * Copyright 2016 University of York
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and limitations under the License.
 *
 * File: eprom.cpp
 *
 * (C) Dept. Electronics & Computer Science, University of York
 * James Hilder, Alan Millard, Alexander Horsfield, Homero Elizondo, Jon Timmis
 *
 * PsiSwarm Library Version: 0.8
 *
 * October 2016
 *
 * Functions for accessing the 64Kb EPROM chip and reading the reserved firmware block
 *
 * Example:
 * @code
 * #include "psiswarm.h"
 *
 * int main() {
 *     init();
 *     eprom.write_eeprom_byte(0,0xDD);    //Writes byte 0xDD in EPROM address 0
 *     char c = eprom.read_eeprom_byte(0); //c will hold 0xDD
 *     //Valid address range is from 0 to 65279
 * }
 * @endcode
 */

#include "psiswarm.h"

/** Write a single byte to the EPROM
 *
 * @param address The address to store the data, range 0-65279
 * @param data The character to store
 */
void Eprom::write_eeprom_byte ( int address, char data )
{
    char write_array[3];
    if(address > 65279) {
        psi.debug("WARNING: Attempt to write to invalid EPROM address: %X",address);
    } else {
        write_array[0] = address / 256;
        write_array[1] = address % 256;
        write_array[2] = data;
        primary_i2c.write(EEPROM_ADDRESS, write_array, 3, false);
        //Takes 5ms to write a page: ideally this could be done with a timer or RTOS
        wait(0.005);
    }
}

/** Read a single byte from the EPROM
 *
 * @param address The address to read from, range 0-65279
 * @return The character stored at address
 */
char Eprom::read_eeprom_byte ( int address )
{
    char address_array [2];
    address_array[0] = address / 256;
    address_array[1] = address % 256;
    char data [1];
    primary_i2c.write(EEPROM_ADDRESS, address_array, 2, false);
    primary_i2c.read(EEPROM_ADDRESS, data, 1, false);
    return data [0];
}

/** Read the next byte from the EPROM, to be called after read_eeprom_byte
 *
 * @return The character stored at address after the previous one read from
 */
char Eprom::read_next_eeprom_byte ()
{
    char data [1];
    primary_i2c.read(EEPROM_ADDRESS, data, 1, false);
    return data [0];
}

/** Read the data stored in the reserved firmware area of the EPROM
 *
 * @return 1 if a valid firmware is read, 0 otherwise
 */
char Eprom::read_firmware ()
{
    char address_array [2] = {255,0};
    primary_i2c.write(EEPROM_ADDRESS, address_array, 2, false);
    primary_i2c.read(EEPROM_ADDRESS, firmware_bytes, 21, false);

    if(firmware_bytes[0] == PSI_BYTE) {
        // Parse firmware
        char firmware_string [8];
        sprintf(firmware_string,"%d.%d",firmware_bytes[9],firmware_bytes[10]);
        firmware_version = atof(firmware_string);
        char pcb_version_string [8];
        sprintf(pcb_version_string,"%d.%d",firmware_bytes[7],firmware_bytes[8]);
        pcb_version = atof(pcb_version_string);
        char serial_number_string [8];
        sprintf(serial_number_string,"%d.%d",firmware_bytes[5],firmware_bytes[6]);
        serial_number = atof(serial_number_string);
        has_compass = firmware_bytes[11];
        has_side_ir = firmware_bytes[12];
        has_base_ir = firmware_bytes[13];
        has_base_colour_sensor= firmware_bytes[14];
        has_top_colour_sensor= firmware_bytes[15];
        has_wheel_encoders= firmware_bytes[16];
        has_audio_pic= firmware_bytes[17];
        has_ultrasonic_sensor= firmware_bytes[18];
        has_temperature_sensor= firmware_bytes[19];
        has_recharging_circuit= firmware_bytes[20];
        has_433_radio= firmware_bytes[21];
        if(firmware_version > 1.0) {
            motor_calibration_set = firmware_bytes[22];
            if(motor_calibration_set == 1) {
                left_motor_calibration_value = (float) firmware_bytes[23] * 65536;
                left_motor_calibration_value += ((float) firmware_bytes[24] * 256);
                left_motor_calibration_value += firmware_bytes[25];
                left_motor_calibration_value /= 16777216;
                right_motor_calibration_value = (float) firmware_bytes[26] * 65536;
                right_motor_calibration_value += ((float) firmware_bytes[27] * 256);
                right_motor_calibration_value += firmware_bytes[28];
                right_motor_calibration_value /= 16777216;
            }
        } else motor_calibration_set = 0;
        return 1;
    }
    return 0;
}