399 lines
11 KiB
C
399 lines
11 KiB
C
/*
|
|
* ALS31313.c
|
|
*
|
|
* Created on: 8 Apr 2021
|
|
* Author: angoosh
|
|
*
|
|
* Datasheet: https://www.allegromicro.com/~/media/Files/Datasheets/ALS31313-Datasheet.ashx
|
|
*/
|
|
|
|
#include "ALS31313.h"
|
|
|
|
void Enable_Setting_Modification();
|
|
uint32_t Modify_Hall_EEPROM_Settings(int, uint32_t, ACCESS);
|
|
uint32_t Modify_Hall_Register_Settings(int, uint32_t, ACCESS);
|
|
int readHallData(int*, float*);
|
|
double readDegrees(AXIS_PAIR);
|
|
|
|
void Enable_Setting_Modification(){
|
|
uint8_t address = 0x35;
|
|
int value = 0x2C413534;
|
|
uint8_t registerData[4];
|
|
|
|
registerData[0] = 0x2C;
|
|
registerData[1] = 0x41;
|
|
registerData[2] = 0x35;
|
|
registerData[3] = 0x34;
|
|
|
|
sendI2CMaster(HALL_I2C_ADDR, address, registerData, 4, false);
|
|
}
|
|
|
|
/* @brief Settings 0-19
|
|
* 0: 3bit - BW select
|
|
* 1: 2bit - Hall mode
|
|
* 2: 1bit - I2C CRC Rnable
|
|
* 3: 1bit - Disable Slave ADC
|
|
* 4: 7bit - Slave Address
|
|
* 5: 1bit - I2C Threshold
|
|
* 6: 3bit - Axes Channel Enable
|
|
* 7: 1bit - INT Latch Enable
|
|
* 8: 1bit - Signed INT Enable
|
|
* 9: 1bit - INT Mode
|
|
* 10: 1bit - INT EEPROM Status
|
|
* 11: 1bit - INT EEPROM Enable
|
|
* 12: 3bit - Axes INT Enable
|
|
* 13: 6bit - Z INT Threshold
|
|
* 14: 6bit - Y INT Threshold
|
|
* 15: 6bit - X INT Threshold
|
|
* 16: 5bit - 0x02 Customer EEPROM
|
|
* 17: 26bit - 0x0D Customer EEPROM
|
|
* 18: 26bit - 0x0E Customer EEPROM
|
|
* 19: 26bit - 0x0F Customer EEPROM
|
|
* @param setting number
|
|
* @param value to write, if reading it doesn't matter
|
|
* @param READ/WRITE
|
|
* @retval read desired value of memory block, 1 if write successful or 0 if error
|
|
*/
|
|
|
|
uint32_t Modify_Hall_EEPROM_Settings(int setting, uint32_t value, ACCESS rw){
|
|
int address, returnVal;
|
|
uint8_t registerData[4];
|
|
|
|
if((setting < 8) || (setting == 16)){
|
|
address = 0x02;
|
|
}
|
|
else if(setting < 16){
|
|
address = 0x03;
|
|
}
|
|
else if((setting > 16)&&(setting < 20)){
|
|
address = 0x0D + (setting - 17);
|
|
}
|
|
|
|
if(rw == READ){
|
|
//read 32bit data (eeprom cell)
|
|
SendReadI2CMaster(HALL_I2C_ADDR, address, registerData, 4, false);
|
|
|
|
if(setting == 0){
|
|
returnVal = registerData[1];
|
|
returnVal &= 0xE0;
|
|
return returnVal >> 5;
|
|
}
|
|
else if(setting == 1){
|
|
returnVal = registerData[1];
|
|
returnVal &= 0x18;
|
|
return returnVal >> 3;
|
|
}
|
|
else if(setting == 2){
|
|
returnVal = registerData[1];
|
|
returnVal &= 0x04;
|
|
return returnVal >> 2;
|
|
}
|
|
else if(setting == 3){
|
|
returnVal = registerData[1];
|
|
returnVal &= 0x02;
|
|
return returnVal >> 1;
|
|
}
|
|
else if(setting == 4){
|
|
uint8_t returnVal_MSB = registerData[1];
|
|
uint8_t returnVal_LSB = registerData[2];
|
|
returnVal_MSB &= 0x01;
|
|
returnVal_LSB &= 0xFC;
|
|
returnVal = returnVal_MSB << 6;
|
|
returnVal += returnVal_LSB >> 2;
|
|
return returnVal;
|
|
}
|
|
else if(setting == 5){
|
|
returnVal = registerData[2];
|
|
returnVal &= 0x02;
|
|
return returnVal >> 1;
|
|
}
|
|
else if(setting == 6){
|
|
uint8_t returnVal_MSB = registerData[2];
|
|
uint8_t returnVal_LSB = registerData[3];
|
|
returnVal_MSB &= 0x01;
|
|
returnVal_LSB &= 0xC0;
|
|
returnVal = returnVal_MSB << 2;
|
|
returnVal += returnVal_LSB >> 6;
|
|
return returnVal;
|
|
}
|
|
else if(setting == 7){
|
|
returnVal = registerData[3];
|
|
returnVal &= 0x10;
|
|
return returnVal >> 4;
|
|
}
|
|
else if(setting == 16){
|
|
returnVal = registerData[3];
|
|
returnVal &= 0x0F;
|
|
return returnVal;
|
|
}
|
|
else if(setting == 8){
|
|
returnVal = registerData[0];
|
|
returnVal &= 0x01;
|
|
return returnVal;
|
|
}
|
|
else if(setting == 9){
|
|
returnVal = registerData[1];
|
|
returnVal &= 0x80;
|
|
return returnVal >> 7;
|
|
}
|
|
else if(setting == 10){
|
|
returnVal = registerData[1];
|
|
returnVal &= 0x40;
|
|
return returnVal >> 6;
|
|
}
|
|
else if(setting == 11){
|
|
returnVal = registerData[1];
|
|
returnVal &= 0x20;
|
|
return returnVal >> 5;
|
|
}
|
|
else if(setting == 12){
|
|
returnVal = registerData[1];
|
|
returnVal &= 0x1C;
|
|
return returnVal >> 2;
|
|
}
|
|
else if(setting == 13){
|
|
uint8_t returnVal_MSB = registerData[1];
|
|
uint8_t returnVal_LSB = registerData[2];
|
|
returnVal_MSB &= 0x03;
|
|
returnVal_LSB &= 0xF0;
|
|
returnVal = returnVal_MSB << 4;
|
|
returnVal += returnVal_LSB >> 4;
|
|
return returnVal;
|
|
}
|
|
else if(setting == 14){
|
|
uint8_t returnVal_MSB = registerData[2];
|
|
uint8_t returnVal_LSB = registerData[3];
|
|
returnVal_MSB &= 0x0F;
|
|
returnVal_LSB &= 0xC0;
|
|
returnVal = returnVal_MSB << 2;
|
|
returnVal += returnVal_LSB >> 6;
|
|
return returnVal;
|
|
}
|
|
else if(setting == 15){
|
|
returnVal = registerData[3];
|
|
returnVal &= 0x3F;
|
|
return returnVal;
|
|
}
|
|
else if(setting >= 17){
|
|
uint8_t returnVal_MSB = registerData[0];
|
|
uint8_t returnVal_LMSB = registerData[1];
|
|
uint8_t returnVal_MLSB = registerData[2];
|
|
uint8_t returnVal_LSB = registerData[3];
|
|
returnVal_MSB &= 0x01;
|
|
returnVal = returnVal_MSB << 24;
|
|
returnVal += returnVal_LMSB << 16;
|
|
returnVal += returnVal_MLSB << 8;
|
|
returnVal += returnVal_LSB;
|
|
|
|
return returnVal;
|
|
}
|
|
}
|
|
else{
|
|
//read 32bit data (eeprom cell)
|
|
SendReadI2CMaster(HALL_I2C_ADDR, address, registerData, 4, false);
|
|
|
|
if(setting == 0){
|
|
registerData[1] = ((registerData[1] & ~0xE0) | (value << 5));
|
|
}
|
|
else if(setting == 1){
|
|
registerData[1] = ((registerData[1] & ~0x18) | (value << 3));
|
|
}
|
|
else if(setting == 2){
|
|
registerData[1] = ((registerData[1] & ~0x04) | (value << 2));
|
|
}
|
|
else if(setting == 3){
|
|
registerData[1] = ((registerData[1] & ~0x02) | (value << 1));
|
|
}
|
|
else if(setting == 4){
|
|
uint8_t returnVal_MSB = (value >> 6);
|
|
uint8_t returnVal_LSB = (value << 2);
|
|
registerData[1] = ((registerData[1] & ~0x01) | (returnVal_MSB << 0));
|
|
registerData[2] = ((registerData[2] & ~0xFC) | (returnVal_LSB << 0));
|
|
}
|
|
else if(setting == 5){
|
|
registerData[2] = ((registerData[2] & ~0x02) | (value << 1));
|
|
}
|
|
else if(setting == 6){
|
|
uint8_t returnVal_MSB = (value >> 2);
|
|
uint8_t returnVal_LSB = (value << 6);
|
|
registerData[2] = ((registerData[2] & ~0x01) | (returnVal_MSB << 0));
|
|
registerData[3] = ((registerData[3] & ~0xC0) | (returnVal_LSB << 0));
|
|
}
|
|
else if(setting == 7){
|
|
registerData[3] = ((registerData[3] & ~0x10) | (value << 4));
|
|
}
|
|
else if(setting == 16){
|
|
registerData[3] = ((registerData[3] & ~0x0F) | (value << 0));
|
|
}
|
|
else if(setting == 8){
|
|
registerData[0] = ((registerData[0] & ~0x01) | (value << 0));
|
|
}
|
|
else if(setting == 9){
|
|
registerData[1] = ((registerData[1] & ~0x80) | (value << 7));
|
|
}
|
|
else if(setting == 10){
|
|
registerData[1] = ((registerData[1] & ~0x40) | (value << 6));
|
|
}
|
|
else if(setting == 11){
|
|
registerData[1] = ((registerData[1] & ~0x20) | (value << 5));
|
|
}
|
|
else if(setting == 12){
|
|
registerData[1] = ((registerData[1] & ~0x1C) | (value << 2));
|
|
}
|
|
else if(setting == 13){
|
|
uint8_t returnVal_MSB = (value >> 4);
|
|
uint8_t returnVal_LSB = (value << 4);
|
|
registerData[1] = ((registerData[1] & ~0x03) | (returnVal_MSB << 0));
|
|
registerData[2] = ((registerData[2] & ~0xF0) | (returnVal_LSB << 0));
|
|
}
|
|
else if(setting == 14){
|
|
uint8_t returnVal_MSB = (value >> 2);
|
|
uint8_t returnVal_LSB = (value << 6);
|
|
registerData[2] = ((registerData[2] & ~0x0F) | (returnVal_MSB << 0));
|
|
registerData[3] = ((registerData[3] & ~0xC0) | (returnVal_LSB << 0));
|
|
}
|
|
else if(setting == 15){
|
|
registerData[3] = ((registerData[3] & ~0x3F) | (value << 0));
|
|
}
|
|
else if(setting >= 17){
|
|
uint8_t returnVal_MSB = (value >> 24) & 0x01;
|
|
uint8_t returnVal_LMSB = (value >> 16) & 0xFF;
|
|
uint8_t returnVal_MLSB = (value >> 8) & 0xFF;
|
|
uint8_t returnVal_LSB = (value & 0xFF);
|
|
registerData[0] = ((registerData[0] & ~0xFF) | (returnVal_MSB << 0));
|
|
registerData[1] = ((registerData[1] & ~0xFF) | (returnVal_LMSB << 0));
|
|
registerData[2] = ((registerData[2] & ~0xFF) | (returnVal_MLSB << 0));
|
|
registerData[3] = ((registerData[3] & ~0xFF) | (returnVal_LSB << 0));
|
|
}
|
|
|
|
//write modified data to eeprom
|
|
sendI2CMaster(HALL_I2C_ADDR, address, registerData, 4, false);
|
|
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/* @brief Settings 0-2
|
|
* 0: 3bit - Low-Power Mode - Count Max
|
|
* 1: 2bit - I2C Loop-Mode
|
|
* 2: 2bit - Sleep
|
|
* @param setting number
|
|
* @param value to write, if reading it doesn't matter
|
|
* @param READ/WRITE
|
|
* @retval read desired value of memory block, 1 if write successful or 0 if error
|
|
*/
|
|
uint32_t Modify_Hall_Register_Settings(int setting, uint32_t value, ACCESS rw){
|
|
int address, returnVal;
|
|
uint8_t registerData[4];
|
|
|
|
address = 0x27;
|
|
|
|
if(rw == READ){
|
|
//read 32bit data (eeprom cell)
|
|
SendReadI2CMaster(HALL_I2C_ADDR, address, registerData, 4, false);
|
|
|
|
if(setting == 0){
|
|
returnVal = registerData[3];
|
|
returnVal &= 0x70;
|
|
return returnVal >> 4;
|
|
}
|
|
else if(setting == 1){
|
|
returnVal = registerData[3];
|
|
returnVal &= 0x0C;
|
|
return returnVal >> 2;
|
|
}
|
|
else if(setting == 2){
|
|
returnVal = registerData[3];
|
|
returnVal &= 0x03;
|
|
return returnVal;
|
|
}
|
|
}
|
|
else{
|
|
//read 32bit data (eeprom cell)
|
|
SendReadI2CMaster(HALL_I2C_ADDR, address, registerData, 4, false);
|
|
|
|
if(setting == 0){
|
|
registerData[3] = ((registerData[3] & ~0x70) | (value << 4));
|
|
}
|
|
else if(setting == 1){
|
|
registerData[3] = ((registerData[3] & ~0x0C) | (value << 2));
|
|
}
|
|
else if(setting == 2){
|
|
registerData[3] = ((registerData[3] & ~0x03) | (value << 0));
|
|
}
|
|
//write modified data to eeprom
|
|
sendI2CMaster(HALL_I2C_ADDR, address, registerData, 4, false);
|
|
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* @brief Read sensoric data from ALS31313
|
|
* @param int array of min size 3, stores x, y, z gauss value in this order
|
|
* @param float array of min size 1, temperature of the sensor in C
|
|
* @retval Hall Mode Status - 0 = Single-Ended, 1 = Differential, 2 = Common
|
|
*/
|
|
int readHallData(int *xyz, float *temp){
|
|
uint8_t registerData[8];
|
|
int16_t x, y, z;
|
|
int x_raw, y_raw, z_raw, temp_raw;
|
|
int x_g, y_g, z_g;
|
|
float tempr;
|
|
|
|
//read registers 0x28 and 0x29 respectively
|
|
SendReadI2CMaster(HALL_I2C_ADDR, 0x28, registerData, 8, false);
|
|
|
|
x_raw = registerData[0] << 4;
|
|
y_raw = registerData[1] << 4;
|
|
z_raw = registerData[2] << 4;
|
|
temp_raw = (registerData[3] & 0x3F) << 6;
|
|
|
|
x_raw += (registerData[5] & 0x0F);
|
|
y_raw += (registerData[6] & 0xF0) >> 4;
|
|
z_raw += (registerData[6] & 0x0F);
|
|
temp_raw += (registerData[7] & 0x3F);
|
|
|
|
x = (x_raw & 0x0800) ? (x_raw | 0xf800) : x_raw;
|
|
y = (y_raw & 0x0800) ? (y_raw | 0xf800) : y_raw;
|
|
z = (z_raw & 0x0800) ? (z_raw | 0xf800) : z_raw;
|
|
|
|
//convert raw data to gauss and temperature
|
|
x_g = x / LSB_GAUSS;
|
|
y_g = y / LSB_GAUSS;
|
|
z_g = z / LSB_GAUSS;
|
|
tempr = (((float)302*((float)temp_raw-(float)1708))/(float)4096);
|
|
temp[0] = tempr;
|
|
|
|
xyz[0] = x_g;
|
|
xyz[1] = y_g;
|
|
xyz[2] = z_g;
|
|
|
|
return ((registerData[7] & 0xC0) >> 6);
|
|
}
|
|
|
|
/**
|
|
* @brief Read degrees from ALS31313
|
|
* @param what axes to read: XY, XZ, YZ
|
|
* @retval degrees
|
|
*/
|
|
double readDegrees(AXIS_PAIR pair){
|
|
float temp;
|
|
int xyz[3];
|
|
readHallData(xyz, &temp);
|
|
|
|
if(pair == XY){
|
|
return ((atan2(xyz[1],xyz[0])*(180/3.14159))+180);
|
|
}
|
|
else if(pair == XZ){
|
|
return ((atan2(xyz[2],xyz[0])*(180/3.14159))+180);
|
|
}
|
|
else{
|
|
return ((atan2(xyz[1],xyz[2])*(180/3.14159))+180);
|
|
}
|
|
}
|