Commit 70d32be5 authored by Bruno Laurencich's avatar Bruno Laurencich

eeprom address depending on KC rev

parent 781518c5
<!-- Chordata.xml -->
<Chordata version="0.1.0">
<Configuration>
<KC_revision> 2 </KC_revision>
<Communication>
<Adapter>
/dev/i2c-1
......@@ -41,11 +42,11 @@
</Configuration>
<Armature>
<Mux Name="main" id="0">
0x73
0x77
<Branch Name="left" id="1">
CH_1
<K_Ceptor Name="Unico" id="2">
4
0x0f
</K_Ceptor>
</Branch>
</Mux>
......
......@@ -48,6 +48,12 @@
</xs:annotation>
</xs:element>
<xs:simpleType name="versionType">
<xs:restriction base="xs:normalizedString">
<xs:whiteSpace value='collapse'/>
<xs:pattern value="[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}" />
</xs:restriction>
</xs:simpleType>
<xs:complexType name="root_type">
<xs:all>
......@@ -56,13 +62,35 @@
<xs:element type="ArmatureType" name="Armature"
minOccurs="1" maxOccurs="1"/>
</xs:all>
<xs:attribute type="xs:float" name="version"/>
<xs:attribute type="versionType" name="version"/>
</xs:complexType>
<!-- CONFIGURATION -->
<xs:simpleType name="CollapsedFloatType">
<xs:restriction base="xs:float">
<xs:whiteSpace value='collapse'/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="CollapsedIntType">
<xs:restriction base="xs:integer">
<xs:whiteSpace value='collapse'/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="revisionType">
<xs:restriction base="CollapsedIntType">
<xs:minInclusive value="1"/>
<xs:maxInclusive value="2"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="ConfigurationType">
<xs:all>
<xs:element type="revisionType" name="KC_revision"
minOccurs="0" maxOccurs="1"/>
<xs:element type="CommunicationType" name="Communication"
minOccurs="0" maxOccurs="1"/>
......@@ -77,29 +105,16 @@
<xs:complexType name="FusionType">
<xs:all>
<xs:element type="FusionValueType" name="Beta_final"
<xs:element type="CollapsedFloatType" name="Beta_final"
minOccurs="0" maxOccurs="1"/>
<xs:element type="FusionValueType" name="Beta_start"
<xs:element type="CollapsedFloatType" name="Beta_start"
minOccurs="0" maxOccurs="1"/>
<xs:element type="FusionValueType" name="Time"
<xs:element type="CollapsedIntType" name="Time"
minOccurs="0" maxOccurs="1"/>
</xs:all>
</xs:complexType>
<xs:simpleType name="FusionValueType">
<xs:restriction base="xs:float">
<xs:whiteSpace value='collapse'/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="FusionTimeType">
<xs:restriction base="xs:integer">
<xs:whiteSpace value='collapse'/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="OscType">
<xs:all>
<xs:element type="OscAddressType" name="Base"
......
//
// Copyright(c) 2016-2018 Gabi Melman.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
//
#pragma once
//
// Include a bundled header-only copy of fmtlib or an external one.
// By default spdlog include its own copy.
//
#if !defined(SPDLOG_FMT_EXTERNAL)
#ifndef FMT_HEADER_ONLY
#define FMT_HEADER_ONLY
#endif
#ifndef FMT_USE_WINDOWS_H
#define FMT_USE_WINDOWS_H 0
#endif
#include "bundled/core.h"
#include "bundled/format.h"
#else // external fmtlib
#include <fmt/core.h>
#include <fmt/format.h>
#endif
\ No newline at end of file
......@@ -61,7 +61,7 @@
/////////////////////////////////
///The version of the program
/////////////////////////////////
#define _CHORDATA_VERSION 0.1f
#define _CHORDATA_VERSION "0.1.0"
//////////////////////////////////
/// The name of the client (where the render is performed and the animation recorded)
......@@ -205,6 +205,11 @@
#define _CHORDATA_ODR 50
//////////////////////////////////
///The default version of K-Ceptor used
//////////////////////////////////
#define _KC_REV 2
//////////////////////////////////
/// The defaule Beta parameter of the Madgwick sensor fusion algorithm
//////////////////////////////////
......@@ -222,7 +227,7 @@
//////////////////////////////////
/// The maximun number of ports allowed by default on a Multiplexer
//////////////////////////////////
#define _CHORDATA_MUX_MAX 4
#define _CHORDATA_MUX_MAX 6
//////////////////////////////////
/// The starting chunk of the gyro calib data stored on the EEPROM
......@@ -278,7 +283,16 @@ namespace Chordata {
};
/**
* A Struct that contains all the configuration data.
* Utility template for gettinh size of array on compile time.
* From Efficient Modern c++ by S. Meyers
*/
template<typename T, std::size_t N>
constexpr std::size_t arraySize(T (&)[N]) noexcept {
return N;
}
/**
* Possible outputs fot data and logging.
*/
enum Output_Redirect{
NONE = 0,
......@@ -298,11 +312,6 @@ namespace Chordata {
return a= static_cast<Output_Redirect>(static_cast<char>(a) | static_cast<char>(b));
}
template<typename T, std::size_t N>
constexpr std::size_t arraySize(T (&)[N]) noexcept //From E. Modern c++ by S. Meyers
{
return N;
}
static const char* _Output_Redirect_keywords[] =
{"none","stdout", "stderr", "file", "osc"};
......@@ -336,12 +345,18 @@ namespace Chordata {
static const char invalid_i2c_addr_n = arraySize(invalid_i2c_addr);
/**
* A Struct that contains all the configuration data.
*/
struct Configuration_Data
{
Configuration_Data(); //defined in Chordata_utils.cpp
std::string exe_path;
int hardware_concurrency;
bool wait;
bool raw;
int kc_ver;
struct Program_State{
mutable char beta_timer_init;
......@@ -354,14 +369,13 @@ namespace Chordata {
uint16_t time;
} fusion;
Configuration_Data(); //defined in Chordata_utils.cpp
void append_path();
struct Conf_info{
std::string description;
std::string notes;
float version;
std::string version;
} info;
struct Conf_XML{
......@@ -415,6 +429,8 @@ namespace Chordata {
static const char *wait = "Disable confirmation to start the program. By default Notochord will wait for a confirmation from the user.";
static const char *kc_ver = "The revision of the K-Ceptor hardware used.";
static const char *xml_g = "\nCONFIGURATION FILES:";
static const char *xml_filename = "The path to the configuration file. Default [./Chordata.xml]";
......
......@@ -149,7 +149,10 @@ void KC::bang(){
return;
}
try{
auto eeprom = read_calib(i2c, this->getAddress());
uint8_t eeprom_addr = (Chordata::getConf().kc_ver == 1)? R1_EEPROM_ADDR : R2_EEPROM_ADDR;
eeprom_addr = this->getAddress() ^ eeprom_addr;
auto eeprom = read_calib(i2c, eeprom_addr);
static const std::array<int16_t,3> niente = {0,0,0};
static const std::array<int16_t,3> tutti = {0,0,0};
......@@ -167,11 +170,11 @@ void KC::bang(){
eeprom[0],eeprom[1],eeprom[2]);
//get gyro offsets
eeprom = read_calib(i2c, this->getAddress(), _CHORDATA_EEPROM_GYRO_OFFSET);
eeprom = read_calib(i2c, eeprom_addr, _CHORDATA_EEPROM_GYRO_OFFSET);
std::copy(std::begin(eeprom), std::end(eeprom), std::begin(imu->gBiasRaw));
//get acel offsets
eeprom = read_calib(i2c, this->getAddress(), _CHORDATA_EEPROM_ACEL_OFFSET);
eeprom = read_calib(i2c, eeprom_addr, _CHORDATA_EEPROM_ACEL_OFFSET);
std::copy(std::begin(eeprom), std::end(eeprom), std::begin(imu->aBiasRaw));
......
......@@ -54,7 +54,7 @@
#include "MadgwickAHRS.h"
#include "../src/EEPROM.h" //This can't be included anywhere else :P
#include "EEPROM.h" //This can't be included anywhere else :P << why?
#include <cstdint>
......
......@@ -127,7 +127,7 @@ Configuration_Data Chordata::parse_cmd_line(int argc, const char **argv){
args::Flag version(parser, "version", msgs::version, {'V', "version"});
args::Flag wait(parser, "no_wait", msgs::wait, {'y', "yes"});
args::Flag raw(parser, "raw_lectures", msgs::wait, {'r', "raw"});
args::ValueFlag<int> kc_ver(parser, "K_Ceptor revision", msgs::kc_ver, {'k', "kceptor"});
args::Group xml(parser, msgs::xml_g, args::Group::Validators::DontCare);
......@@ -171,6 +171,7 @@ Configuration_Data Chordata::parse_cmd_line(int argc, const char **argv){
}
using args::get;
if (version){
args::Error e("");
throw CMDLine_Parse_Error(format(msgs::version_dump, _CHORDATA_VERSION), e);
......@@ -178,8 +179,16 @@ Configuration_Data Chordata::parse_cmd_line(int argc, const char **argv){
conf.wait = (wait)? false : true;
conf.raw = (raw)? true : false;
using args::get;
if (kc_ver){
args::Error e("");
throw CMDLine_Parse_Error("At the moment the K-Ceptor version can only be set on the XML", e);
}
// conf.kc_ver = (kc_ver)? get(kc_ver) : _KC_REV;
// if ( conf.kc_ver != 1 && conf.kc_ver != 2 ) {
// args::Error e("");
// throw CMDLine_Parse_Error("Invalid K-Ceptor revision argument passed, only revisions 1 and 2 are valid.", e);
// }
if (xml_filename) conf.xml.filename = get(xml_filename);
if (xml_schema) conf.xml.schema = get(xml_schema);
......@@ -261,16 +270,15 @@ XML_Parser::XML_Parser(Configuration_Data & conf):
init_procedure();
const XMLElement *theNode;
const XMLElement *conf_node = getBaseNode()
->FirstChildElement("Configuration");
const XMLElement *comm_node = getBaseNode()
->FirstChildElement("Configuration")
const XMLElement *comm_node = conf_node
->FirstChildElement("Communication");
const XMLElement *osc_node = getBaseNode()
->FirstChildElement("Configuration")
const XMLElement *osc_node = conf_node
->FirstChildElement("Osc");
const XMLElement *fusion_node = getBaseNode()
->FirstChildElement("Configuration")
const XMLElement *fusion_node = conf_node
->FirstChildElement("Fusion");
auto get = [](const XMLElement* e, const char* t){
......@@ -306,6 +314,12 @@ XML_Parser::XML_Parser(Configuration_Data & conf):
}
};
//parse <Configuration> node
theNode = getBaseNode()->FirstChildElement("Configuration");
string temp;
putInConf(temp, "KC_revision");
conf.kc_ver = stoi(temp);
//parse <Communication> node
theNode = comm_node;
......@@ -318,7 +332,7 @@ XML_Parser::XML_Parser(Configuration_Data & conf):
if (are_the_same(conf.comm.filename , default_conf.comm.filename))
putInConf(conf.comm.filename, "Filename"); //** conf.comm.filename **
string temp;
temp;
if (are_the_same(conf.comm.port , default_conf.comm.port)){
putInConf(temp, "Port"); //** conf.comm.port **
conf.comm.port = stoi(temp);
......
......@@ -79,6 +79,7 @@ Chordata::Configuration_Data::Configuration_Data(): //from Chordata_def.h
hardware_concurrency(std::thread::hardware_concurrency()),
wait(true),
raw(false),
kc_ver(_KC_REV),
state({.beta_timer_init = 0, .imu_setup_complete = false})
{
......
......@@ -51,7 +51,8 @@
#include "i2c_manager.h"
#include "Chordata_utils.h"
#define EEPROM_ADDR 0x51
#define R1_EEPROM_ADDR 0x50
#define R2_EEPROM_ADDR 0x51
//TODO: set date on write!
......
......@@ -88,18 +88,18 @@ config_fn Chordata::getConf = []()-> const Chordata::Configuration_Data& {
//////////////////////////////////
#define EEPROM_RW_SLEEP 1
bool write_calib(I2C_io* io, uint16_t xor_val, std::array<int16_t, 3> vals, int offset){
bool write_calib(I2C_io* io, uint16_t address, std::array<int16_t, 3> vals, int offset){
// cout << "WRITING EEPROM OFFSET: " << offset << endl;
for (int i = 0; i < 6; i+=2)
{
int16_t val = vals[i/2];
int8_t msb = (val & 0xff00) >> 8;
io->writeByte( EEPROM_ADDR ^ xor_val, offset+i+0 , msb );
io->writeByte( address, offset+i+0 , msb );
thread_sleep(Chordata::millis(EEPROM_RW_SLEEP));
int8_t lsb = (val & 0x00ff);
io->writeByte( EEPROM_ADDR ^ xor_val, offset+i+1 , lsb );
io->writeByte( address, offset+i+1 , lsb );
thread_sleep(Chordata::millis(EEPROM_RW_SLEEP));
// printf("SLOT %d [ MSB:%2x LSB:%2x - VAL: %4x / %d]\n", i , msb, lsb, val, val);
......@@ -108,14 +108,14 @@ bool write_calib(I2C_io* io, uint16_t xor_val, std::array<int16_t, 3> vals, int
}
std::array<int16_t, 3> read_calib(I2C_io* io, uint16_t xor_val, int offset){
std::array<int16_t, 3> read_calib(I2C_io* io, uint16_t address, int offset){
std::array<int16_t, 3> results;
for (int i = 0; i < 6; i+=2)
{
int8_t msb = io->readByte( EEPROM_ADDR ^ xor_val, offset+i+0 ) ;
int8_t msb = io->readByte( address, offset+i+0 ) ;
thread_sleep(Chordata::millis(EEPROM_RW_SLEEP));
int8_t lsb = io->readByte( EEPROM_ADDR ^ xor_val, offset+i+1 ) ;
int8_t lsb = io->readByte( address, offset+i+1 ) ;
thread_sleep(Chordata::millis(EEPROM_RW_SLEEP));
results[i/2] = (msb << 8) | (lsb & 0x00ff);
......@@ -309,22 +309,25 @@ bool Notochord::run(){
comm::info("Writting to EEPROM, xor: {}", Chordata::K_Ceptor_addr);
write_calib(i2c, Chordata::K_Ceptor_addr, result, 0);
write_calib(i2c, Chordata::K_Ceptor_addr, gyro_offsets, _CHORDATA_EEPROM_GYRO_OFFSET);
write_calib(i2c, Chordata::K_Ceptor_addr, acel_offsets, _CHORDATA_EEPROM_ACEL_OFFSET);
uint8_t eeprom_addr = (Chordata::getConf().kc_ver == 1)? R1_EEPROM_ADDR : R2_EEPROM_ADDR;
eeprom_addr = eeprom_addr ^ Chordata::K_Ceptor_addr;
auto eeprom = read_calib(i2c, Chordata::K_Ceptor_addr);
write_calib(i2c, eeprom_addr, result, 0);
write_calib(i2c, eeprom_addr, gyro_offsets, _CHORDATA_EEPROM_GYRO_OFFSET);
write_calib(i2c, eeprom_addr, acel_offsets, _CHORDATA_EEPROM_ACEL_OFFSET);
auto eeprom = read_calib(i2c, eeprom_addr);
if (eeprom != result)
comm::err("The readed values (MAG) from the eeprom are different than those written:\n\t{}\n\t{}\n\t{}",
eeprom[0],eeprom[1],eeprom[2]);
eeprom = read_calib(i2c, Chordata::K_Ceptor_addr, _CHORDATA_EEPROM_GYRO_OFFSET);
eeprom = read_calib(i2c, eeprom_addr, _CHORDATA_EEPROM_GYRO_OFFSET);
if (eeprom != gyro_offsets)
comm::err("The readed values (GYRO) from the eeprom are different than those written:\n\t{}\n\t{}\n\t{}",
eeprom[0],eeprom[1],eeprom[2]);
eeprom = read_calib(i2c, Chordata::K_Ceptor_addr, _CHORDATA_EEPROM_ACEL_OFFSET);
eeprom = read_calib(i2c, eeprom_addr, _CHORDATA_EEPROM_ACEL_OFFSET);
if (eeprom != acel_offsets)
comm::err("The readed values (ACEL) from the eeprom are different than those written:\n\t{}\n\t{}\n\t{}",
eeprom[0],eeprom[1],eeprom[2]);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment