#include "tle_device.h"
#include "eval_board.h"
void setup();
double calculateAngleSpeed(double angRange, int16_t rawAngleSpeed, uint16_t firMD, uint16_t predictionVal);
uint8_t crcCalc(uint8_t* crcData, uint8_t length);
double angleValue;
uint8_t crc8(uint8_t *data, uint8_t length);
uint8_t getSecondByte(uint16_t twoByteWord);
uint8_t getFirstByte(uint16_t twoByteWord);
void enableSensor();
void disableSensor();
enum errorTypes getAngleValue();
enum errorTypes readFromSensor(uint16_t command, uint16_t *data);
/************************************************** ***************************/
/** SSC1: sends one byte (0xAA) as SPI master @ 1 Mbaud **/
/************************************************** ***************************/
/** program SSC1 to operate at 1 Mbaud **/
/** SSC1 sends one byte at P0.3 (CLK), P0.2 (MTSR) **/
/************************************************** ***************************/
#define TLE5012B_H
// Sensor registers
#define READ_SENSOR 0x8000 //!< base command for read
#define WRITE_SENSOR 0x5000 //!< base command for write
#define READ_BLOCK_CRC 0x8088 //!< initialize block CRC check command
#define SYSTEM_ERROR_MASK 0x4000 //!< System error masks for safety words
#define INTERFACE_ERROR_MASK 0x2000 //!< Interface error masks for safety words
#define INV_ANGLE_ERROR_MASK 0x1000 //!< Angle error masks for safety words
#define CRC_POLYNOMIAL 0x1D //!< values used for calculating the CRC
#define CRC_SEED 0xFF
#define CRC_NUM_REGISTERS 0x0008 //!< number of CRC relevant registers
#define MAX_REGISTER_MEM 0x0030 //!< max readable register values buffer
#define DELETE_BIT_15 0x7FFF //!< Value used to delete everything except the first 15 bits
#define CHANGE_UINT_TO_INT_15 0x8000 //!< Value used to change unsigned 16bit integer into signed
#define CHECK_BIT_14 0x4000 //!<
#define GET_BIT_14_4 0x7FF0 //!<
#define DELETE_7BITS 0x01FF //!< values used to calculate 9 bit signed integer sent by the sensor
#define CHANGE_UNIT_TO_INT_9 0x0200 //!< Value used to change unsigned 9bit integer into signed
#define CHECK_BIT_9 0x0100
#define POW_2_15 32768.0 //!< values used to for final calculations of angle speed, revolutions, range and value
#define POW_2_7 128.0 //!<
#define ANGLE_360_VAL 360.0
#define TEMP_OFFSET 152.0 //!< values used to calculate the temperature
#define TEMP_DIV 2.776
//!< Prints a binary number with leading zeros (Automatic Handling)
#define PRINTBIN(Num) for (uint32_t t = (1UL<< (sizeof(Num)*8)-1); t; t >>= 1) Serial.write(Num & t ? '1' : '0');
//!< Prints a binary number with leading zeros (Automatic Handling) with space
#define PRINTBINS(Num) for (uint32_t t = (1UL<< (sizeof(Num)*8)-1); t; t >>= 1) Serial.write(Num & t ? " 1 " : " 0 ");
/*!
* Error types from safety word
*/
enum errorTypes
{
NO_ERROR = 0x00, //!< NO_ERROR = Safety word was OK
SYSTEM_ERROR = 0x01, //!< SYSTEM_ERROR = over/under voltage, VDD negative, GND off, ROM defect
INTERFACE_ACCESS_ERROR = 0x02, //!< INTERFACE_ACCESS_ERROR = wrong address or wrong lock
INVALID_ANGLE_ERROR = 0x03, //!< INVALID_ANGLE_ERROR = NO_GMR_A = 1 or NO_GMR_XY = 1
ANGLE_SPEED_ERROR = 0x04, //!< ANGLE_SPEED_ERROR = combined error, angular speed calculation wrong
CRC_ERROR = 0xFF //!< CRC_ERROR = Cyclic Redundancy Check (CRC), which includes the STAT and RESP bits wrong
};
/*!
* Set the UPDate bit high (read from update buffer) or low (read directly)
*/
enum updTypes
{
UPD_low = 0x0000, //!< read normal registers
UPD_high = 0x0400, //!< read update buffer registers
};
/*!
* Switch on/off safety word generation
*/
enum safetyTypes
{
SAFE_low = 0x0000, //!< switch of safety word generation
SAFE_high = 0x0001, //!< switch on safety word generation
};
uint8_t mMOSI; //!< Pin for SPI MOSI (pin 0.6 on test board);
uint8_t mMISO; //!< Pin for SPI MISO (pin 0.7 on test board)
uint8_t mSCK; //!< Pin for CLOCK (pin 0.8 on test board)
uint8_t mCS; //!< Pin for chip select (pin 0.9 on test board)
uint16_t data;
uint16_t _command1; //!< command write data [0] = command [1] = data to write
uint16_t _command2; //!< command write data [0] = command [1] = data to write
uint16_t _received[MAX_REGISTER_MEM]; //!< fetched data from sensor with last word = safety word
uint16_t _registers[CRC_NUM_REGISTERS]; //!< keeps track of the values stored in the 8 _registers, for which the CRC is calculated
int main(void)
{
/************************************************** ***************************
** initialization of the hardware modules based on the configuration done **
** by using the IFXConfigWizard **
************************************************** ***************************/
TLE_Init();
setup();
for (;;)
{
(void)WDT1_Service();
Delay_us(1000000);
enableSensor();
getAngleValue();
}
}
void setup()
{
mMOSI=0x02; //!< Pin for SPI MOSI (pin 0.6 on test board);
mMISO=0x24; //!< Pin for SPI MISO (pin 0.7 on test board)
mSCK=0x03; //!< Pin for CLOCK (pin 0.8 on test board)
mCS=0x01;
enableSensor();
}
enum errorTypes getAngleValue()
{
angleValue=0;
int16_t rawAnglevalue=0;
uint16_t rawData = 0;
enum errorTypes status = readFromSensor(REG_AVAL, &rawData);
if (status != NO_ERROR)
{
return (status);
}
rawData = (rawData & (DELETE_BIT_15));
//check if the value received is positive or negative
if (rawData & CHECK_BIT_14)
{
rawData = rawData - CHANGE_UINT_TO_INT_15;
}
rawAnglevalue = rawData;
angleValue = (ANGLE_360_VAL / POW_2_15) * ((double) rawAnglevalue);
return (status);
}
enum errorTypes readFromSensor(uint16_t command, uint16_t *data)
{
enum errorTypes checkError = NO_ERROR;
_command1 = READ_SENSOR | command | UPD_low | SAFE_low;
uint16_t _received[MAX_REGISTER_MEM] = {0};
//_spiConnection->setCSPin(mCS);
PORT_ChangePin(LED1, PORT_ACTION_SET);
//Delay_us(100);
//_spiConnection->sendReceiveSpi(_command1, 1, _received, 2);
PORT_ChangePin(LED1, PORT_ACTION_CLEAR);
SSC1_SendWord(_command1);
Delay_us(5000);
_received[0]=SSC1_ReadWord();
_received[1]=SSC1_ReadWord();
*data = _received[0];
PORT_ChangePin(LED1, PORT_ACTION_SET);
if (true)
{
// checkError = checkSafety(_received[1], _command1, &_received[0], 1);
if (checkError != NO_ERROR)
{
data = 0;
}
}
checkError=NO_ERROR;
return (checkError);
}
void enableSensor()
{
PORT_ChangePin(LED1, PORT_ACTION_SET);
//digitalWrite(mCS, HIGH);
}
void disableSensor()
{
PORT_ChangePin(LED1, PORT_ACTION_CLEAR);
//digitalWrite(mCS, low);
}
//-----------------------------------------------------------------------------
// none_class functions
/*!
* Gets the first byte of a 2 byte word
* @param twoByteWord insert word of two bytes long
* @return returns the first byte
*/
uint8_t getFirstByte(uint16_t twoByteWord)
{
return ((uint8_t) (twoByteWord >> 8));
}
/*!
* Gets the second byte of the 2 byte word
* @param twoByteWord insert word of two bytes long
* @return returns the second byte
*/
uint8_t getSecondByte(uint16_t twoByteWord)
{
return ((uint8_t) twoByteWord);
}
/*!
* Function for calculation the CRC.
* @param data byte long data for CRC check
* @param length length of data
* @return returns 8bit CRC
*/
uint8_t crc8(uint8_t *data, uint8_t length)
{
uint32_t crc;
int16_t i, bit;
crc = CRC_SEED;
for (i = 0; i < length; i++)
{
crc ^= data[i];
for (bit = 0; bit < 8; bit++)
{
if ((crc & 0x80) != 0)
{
crc <<= 1;
crc ^= CRC_POLYNOMIAL;
}else{
crc <<= 1;
}
}
}
return ((~crc) & CRC_SEED);
}
/*!
* Function for calculation of the CRC
* @param crcData byte long data for CRC check
* @param length length of data
* @return runs crc8 calculation and returns CRC
*/
uint8_t crcCalc(uint8_t* crcData, uint8_t length)
{
return (crc8(crcData, length));
}
/*!
* Calculate the angle speed
* @param angRange set angular range value
* @param rawAngleSpeed raw speed value from read function
* @param firMD
* @param predictionVal
* @return calculated angular speed
*/
double calculateAngleSpeed(double angRange, int16_t rawAngleSpeed, uint16_t firMD, uint16_t predictionVal)
{
double finalAngleSpeed;
double microsecToSec = 0.000001;
double firMDVal;
if (firMD == 1)
{
firMDVal = 42.7;
}else if (firMD == 0)
{
firMDVal = 21.3;
}else if (firMD == 2)
{
firMDVal = 85.3;
}else if (firMD == 3)
{
firMDVal = 170.6;
}else{
firMDVal = 0;
}
finalAngleSpeed = ((angRange / POW_2_15) * ((double) rawAngleSpeed)) / (((double) predictionVal) * firMDVal * microsecToSec);
return (finalAngleSpeed);
}
Attachment 4416