/**************************************************************************** Module IMU_SERVICE_SPI pseudo code /*----------------------------- Module Defines ----------------------------*/ #define READ_IMU_PERIOD #define BOOTING_PERIOD #define POWER_ON_PERIOD /*---------------------------- Module Variables ---------------------------*/ init a state variable init a MyPriority; init three byte variables to store data init a flag to indicate that we are obtaining real data, instead of init steps set NUM_OF_DATA to 6, acceleration and gyro for X Y Z axes set up array of int16_t to store the IMU data set up a counter to populate the array set up a counter to count the init steps define the "read data commands", each consists of a "read mask" and the register address set NUM_INIT_STEPS to 6 set up the two arrays, following startup sequence in chapter 3 of application note, and enable high pass filter /*------------------------------ Module Code ------------------------------*/ /**************************************************************************** ****************************************************************************/ bool InitIMU_Service_SPI ( uint8_t Priority ) { save our priority set CurrentState to POWER_ON_WAITING; init SPI kick off the timer to wait for the start up time update the flag indicating we are not receiving actual data return true; } /**************************************************************************** ****************************************************************************/ bool PostIMU_Service_SPI( ES_Event ThisEvent ) { return ES_PostToService( MyPriority, ThisEvent); } /**************************************************************************** ****************************************************************************/ ES_Event RunIMU_Service_SPI( ES_Event CurrentEvent ) { ES_Event ReturnEvent = { ES_NO_EVENT, 0 }; // assume no error switch ( CurrentState ) { case POWER_ON_WAITING: if the READ_IMU_TIMER times out set CurrentState to BOOTING_IMU; kick off the timer again break; case BOOTING_IMU: if READ_IMU_TIMER times out if the init steps have not yet finished write the address of the Init register to SPI write the value we want in that register to SPI enable SPI Interupt increment init step kick off timer to give some time until the next step if we finished configuring all the steps set FlagDoingData to 1, indicating useful data are coming clear the init step counter set CurrentState to COMMANDING_IMU kick off timer for real sensor reading break; case COMMANDING_IMU: if READ_IMU_TIMER times out if FlagDoingData is set to 1 write the lower of the data register address to read the IMU data, followed by two 0x00 to SPI enable SPI Interupt set CurrentState to RECEIVING_FROM_IMU; break; case RECEIVING_FROM_IMU : if we have an ES_EOT event clear an int16_t data buffer shift the data3 by 8 bit to the left, and combine that with data2 to form int16_t number store in the IMU data array increment IMU data counter start the timer for the next IMU read cycle set CurrentState to COMMANDING_IMU; break; default: break; } return (ReturnEvent); } /********************************************SPI FUNCTIONS********************************************/ void SPI_Init(void){ Enable the clock to the GPIO Port (we are going to use Port D) Enable clock to SSI - set to SSI Module 3 Wait for GPIO Port to be ready by killing a few cycles Program the GPIO to use the alternate functions on the SSI pins PD0,1,2,3 Set Mux position in GPIOPCTL to select the SSI use of the pins Program the port lines for digital I/O Program the required data directions on the port line program the pull-up on the clock line Wait for the SSI3 to be ready Make sure that the SSI is disabled before programming mode bits Select Master mode and TXRES indicating EOT Configure the SSI clock source to the system clock Configure the clock pre-scaler: here we want CPSDVSR =80 , 1+SCR = 61 Configure phase (SPH)- 1 and polarity (SPO)- 1 ,mode (FRF) - freescale(0) and datasize (DSS) - 8 bit Locally Enable Interrupts (TXIM in SSIIM) enable SPI Interupt(); Enable SSI3 Globally enable interupts Enable the NVIC interrupt for the SSI when starting to transmit enable SSI3 interrupt in the NVIC, it is interrupt number 58 so appears in EN2 at bit 0 make sure we disable loopback mode } static void enable_SPI_Interupt(void){ set SSI_IM_TXIM; } static void disable_SPI_Interupt(void){ clear SSI_IM_TXIM; } void SPI_Interupt_Response(void){ disable SPI Interupt read and store data, three times if we are doing data post an ES_EOT event to this service } } void SPI_Write(uint8_t data){ Set the data to SPI register } // Read the data from SPI register uint8_t SPI_Read(void){ Read the data from SPI register return that data }