/* * futek_driver.c * * Created on: Feb 15, 2020 * Author: saili.desai */ #include #include "stdint.h" #include "ADM-E_AAIF_ESCObjects.h" #include "futek_driver.h" #include "dbg.h" #include "crc16.h" #include "Dave\Generated\INTERRUPT\interrupt_extern.h" //delay counts #define CYCLE_COUNT_1us_144MHz (5UL) #define CYCLE_COUNT_1ms_144MHz (142857UL) //Futek packet structure macros #define TRANSMIT_RECEIVE_BYTES 15 #define TRANSMIT_RECEIVE_BYTE_NO_CRC 13 #define ERROR_CODE_INDEX 0 #define CRC_MSB_INDEX 13 #define CRC_LSB_INDEX 14 #define COMMAND_BYTE_INDEX 12 #define ADC_CHANNEL1_MSB_INDEX 1 #define ADC_CHANNEL1_LSB_INDEX 2 #define CALIBRATION_DATA_POINTS 12 //Futek load cell command codes //Get ADC Data #define GADC 0x00 //Get sensor serial number #define GSSN 0x0D //Get instrument serial number #define GISN 0x0E /******************************************************************************* * LOCAL VARIABLES *******************************************************************************/ static bool is_initialized = 0; /******************************************************************************* * GLOBAL VARIABLES *******************************************************************************/ int32_t futek_data[FUTEK_DATA_LENGTH] = { 0 }; //CRC for all commands starting from 0x00 to 0x22 static const uint16_t calculated_transmit_crc[35] = {0xEB03, 0x6A01, 0xA904, 0x2806, 0x6F0D, 0xEE0F, 0x2D0A, 0xAC08, 0xA31C, 0x221E, 0xE11B, 0x6019, 0x2712, 0xA610, 0x6515, 0xE417, 0x7B3D, 0xFA3F, 0x393A, 0xB838, 0xFF33, 0x7E31, 0xBD34, 0x3C36, 0x3322, 0xB220, 0x7125, 0xF027, 0xB72C, 0x362E, 0xF52B, 0x7429, 0x8B7C, 0x0A7E, 0xC97B}; /******************************************************************************* * LOCAL FUNCTIONS *******************************************************************************/ //static void delay_us(uint32_t cycles) //{ // volatile uint32_t i; // // for(i = 0UL; i < cycles ;++i) // { // __NOP(); // } //} static int send_command_and_read(const uint8_t command); //============================================================================== /*! This function is used to initialize and configure the SPI master for Futek load cell \fn int Futek_Init(void) \param none \return 0 on success, non-zero otherwise */ //============================================================================== int Futek_Init(void) { // Some of these may repeat initialization done in the Dave system files, // but it helps to document the choices to put them here, with comments. // FIFOs are not enabled currently, but might be used in the code (later). // Disable automatic updating of the hardware parameters, such as 4-bit IO. SPI_MASTER_0.channel->TCSR &= (uint32_t)~USIC_CH_TCSR_HPCMD_Msk; // Enable Frame End Mode, which means don't end the frame if there is not // new data waiting in the Tx buffer after the last word was shifted out. // The processor may be busy (maybe handling an interrupt...). // We will end the frame manually, either by setting the EOF bit, // or by clearing the MSLS flag. XMC_SPI_CH_EnableFEM(SPI_MASTER_0.channel); // Disable automatic frame ending. Contrary to what the above option seems // to indicate, the SPI module will still automatically end the frame // after any number of bits less than 64. // So the frame length MUST be set to 64 here (63 in the register...) // to stop indicate to ignore the frame length setting. XMC_SPI_CH_SetFrameLength(SPI_MASTER_0.channel, 64U); //Start with 8-bit words. We will explicitly set to more (and back to 16-bit) in the code. XMC_SPI_CH_SetWordLength(SPI_MASTER_0.channel, 8U); // Start with the Most Significant Bit XMC_SPI_CH_SetBitOrderMsbFirst(SPI_MASTER_0.channel); //SPI Config SPI_MASTER_SetMode(&SPI_MASTER_0, XMC_SPI_CH_MODE_STANDARD); // Select slave 0. Actually already done in SPI config, but here for doc... //XMC_SPI_CH_EnableSlaveSelect(SPI_MASTER_0.channel, XMC_SPI_CH_SLAVE_SELECT_0); USIC0_CH1->DX3CR = 0x4U; // start SPI XMC_SPI_CH_Start(SPI_MASTER_0.channel); return 0; } void Futek_Calculate_CRC(void) { //Data to be sent without the CRC bytes uint8_t transmit_data[TRANSMIT_RECEIVE_BYTE_NO_CRC] = { 0 }; uint8_t reverse_transmit_data[TRANSMIT_RECEIVE_BYTE_NO_CRC] = { 0 }; uint16_t crc = 0; for (uint8_t command=0x00; command<0x23; command++) { transmit_data[COMMAND_BYTE_INDEX] = command; //Reverse the data to pass it to the CRC calculation function for (uint8_t i=0; i> 8); futek_transmit_data[CRC_LSB_INDEX] = (uint8_t) (calculated_transmit_crc[command] & 0x00FF); //Drive CS low SPI_MASTER_EnableSlaveSelectSignal(&SPI_MASTER_0, SPI_MASTER_SS_SIGNAL_0); //Send the command to Futek load cell SPI_MASTER_Transmit(&SPI_MASTER_0, futek_transmit_data, TRANSMIT_RECEIVE_BYTES); while(SPI_MASTER_0.runtime->tx_busy); //Drive CS high SPI_MASTER_DisableSlaveSelectSignal(&SPI_MASTER_0); } void Futek_Transfer (const uint8_t command) { uint8_t futek_transmit_data[TRANSMIT_RECEIVE_BYTES] = { 0 }; uint8_t futek_receive_data[TRANSMIT_RECEIVE_BYTES] = { 0 }; futek_transmit_data[COMMAND_BYTE_INDEX] = command; futek_transmit_data[CRC_MSB_INDEX] = (uint8_t) ((calculated_transmit_crc[command] & 0xFF00) >> 8); futek_transmit_data[CRC_LSB_INDEX] = (uint8_t) (calculated_transmit_crc[command] & 0x00FF); //Drive CS low SPI_MASTER_EnableSlaveSelectSignal(&SPI_MASTER_0, SPI_MASTER_SS_SIGNAL_0); //Send the command to Futek load cell SPI_MASTER_Transfer(&SPI_MASTER_0, futek_transmit_data, futek_receive_data, TRANSMIT_RECEIVE_BYTES); while(SPI_MASTER_0.runtime->tx_busy); while(SPI_MASTER_0.runtime->rx_busy); //Drive CS high SPI_MASTER_DisableSlaveSelectSignal(&SPI_MASTER_0); DBG_PRINTF("futek_receive_data[0]: 0x%02X\n", futek_receive_data[0]); //No error was received if (futek_receive_data[0] == 0x00) { futek_data[0] = (uint32_t) (futek_receive_data[0]); for (uint8_t i=1; irx_busy); //Drive CS High SPI_MASTER_DisableSlaveSelectSignal(&SPI_MASTER_0); DBG_PRINTF("futek_receive_data[0]: 0x%02X\n", futek_receive_data[0]); //No error was received if (futek_receive_data[0] == 0x00) { futek_data[0] = (uint32_t) (futek_receive_data[0]); for (uint8_t i=1; i> 8); futek_transmit_data[CRC_LSB_INDEX] = (uint8_t) (crc & 0x00FF); //Copy command data to transmit data memcpy(futek_transmit_data, transmit_data, TRANSMIT_RECEIVE_BYTE_NO_CRC); while(DIGITAL_IO_GetInput(&DRDY)) { //wait for DRDY line to go low } //Drive CS low SPI_MASTER_EnableSlaveSelectSignal(&SPI_MASTER_0, SPI_MASTER_SS_SIGNAL_0); //Send the command to Futek load cell SPI_MASTER_Transmit(&SPI_MASTER_0, futek_transmit_data, TRANSMIT_RECEIVE_BYTES); while(SPI_MASTER_0.runtime->tx_busy); //Drive CS high SPI_MASTER_DisableSlaveSelectSignal(&SPI_MASTER_0); while(!(DIGITAL_IO_GetInput(&DRDY))) { //wait for DRDY line to go high } while(DIGITAL_IO_GetInput(&DRDY)) { //wait for DRDY line to go low } //Drive CS low SPI_MASTER_EnableSlaveSelectSignal(&SPI_MASTER_0, SPI_MASTER_SS_SIGNAL_0); //Read data SPI_MASTER_Receive(&SPI_MASTER_0, receive_data, TRANSMIT_RECEIVE_BYTES); while(SPI_MASTER_0.runtime->rx_busy); //Drive CS High SPI_MASTER_DisableSlaveSelectSignal(&SPI_MASTER_0); // //Get received CRC // received_crc = ((uint16_t)receive_data[CRC_MSB_INDEX] << 8)|receive_data[CRC_LSB_INDEX]; // // //calculate received data crc // for (uint8_t i=0; i