Code for the project of LELEC2811 2017
Dependencies: FreescaleIAP MMA8491Q_PG mbed
Fork of LELEC_2811_Accelerometer by
Diff: main.cpp
- Revision:
- 0:a18d6e69c993
- Child:
- 1:1406d318a3b7
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Tue Oct 14 08:17:52 2014 +0000 @@ -0,0 +1,395 @@ +/* LELEC_2811 Accelerometer Project + UCL 2014 - P. Gérard +*/ +#include "mbed.h" +#include "FreescaleIAP.h" // Library for Flash Access +#include "MMA8491Q_PG.h" // Accelerometer + +#define MMA8491_I2C_ADDRESS (0x55<<1) + +#define NO_JUMPER 0 +#define JUMPER_PRESENT 1 + +#define LEVEL_0 0 +#define LEVEL_1 1 + +#define LED_ON 0 +#define LED_OFF 1 + +#define DISABLE_STATE 0 +#define ENABLE_STATE 1 + +#define REG_OUT_X_MSB 0x01 +#define REG_OUT_Y_MSB 0x03 +#define REG_OUT_Z_MSB 0x05 + +#define FLASH_NO_ACQ_DONE 0 +#define FLASH_ACQ_DONE 1 +#define ERASE_FLASH_ERROR -1 +#define WRITE_FLASH_ERROR -2 + +#define SECTOR_SIZE 1024 +#define RESERVED_SECTOR 32 + +#define ACQ_TIMER_PERIOD 0.01 // Time between 2 acquisitions (here 10 mSec) + +typedef struct{ + int16_t X; + int16_t Y; + int16_t Z; +} Accel_Data; + +// --- Setup I2C for MMA8491 +MMA8491Q my8491(PTE0, PTE1, MMA8491_I2C_ADDRESS); + +// --- Set Serial Port +Serial Host_Comm(USBTX, USBRX); // tx, rxSerial pc(USBTX, USBRX); // tx, rx + +Ticker myTick_Acq; // Periodical timer for Acquisition + +DigitalOut Led_Red(LED1); // Define I/O for Leds +DigitalOut Led_Green(LED2); +DigitalOut Led_Blue(LED3); + +DigitalOut Accel_Enable(PTA13); + +DigitalOut Start_Pulse_Out(PTC9); // Used to enter/exit Acquisition mode +DigitalIn Start_Pulse_In(PTC11); // ShortPin J1_15 and J1_16 to enter in Acq_Mode + + +// Globale variable +volatile bool bTimer; // 1 means a Timer tick is done + +int Flash_Base_Address = RESERVED_SECTOR * SECTOR_SIZE ; // Store Flash Base Adresse with 32K reserved for Application Code +int Nb_Sector; +uint32_t KL25_Flash_Size; + +// Function Declaration + +void Clear_Led(void); +int Acquisition_Flash(void); +int Read_Data_Logging(void); +bool Check_Jumper(void); +void myTimer_Acq_Task(void); +void Acquisition_Task(void); +void Read_Task(void); + +extern IAPCode verify_erased(int address, unsigned int length); + +int main() { + + uint8_t Count; + + Start_Pulse_In.mode(PullNone); // Input Pin is programmed as floating + Accel_Enable = DISABLE_STATE; // Turn Accel Enable to disabled state + +// --- Baud rate setting + Host_Comm.baud(115200); + + Clear_Led(); + + KL25_Flash_Size = flash_size(); // Get Size of KL25 Embedded Flash + Nb_Sector = (KL25_Flash_Size / SECTOR_SIZE) - RESERVED_SECTOR; // Reserve Max 32K for App Code + + myTick_Acq.attach(&myTimer_Acq_Task, ACQ_TIMER_PERIOD); + + Host_Comm.printf("\n\rLELEC2811 Accelerometer Logger V1.0 UCL 2014\n\r"); + + for (;;) + { + if (Check_Jumper() == JUMPER_PRESENT) + { + Clear_Led(); + + Count = 5; + while (Count !=0) + { + if (Check_Jumper() == JUMPER_PRESENT) + { + Led_Blue = LED_ON; // Blink to alert user "Enter in Acquisition" + wait_ms(900); + Led_Blue = LED_OFF; + wait_ms(100); + Count --; + if (Count == 0) + { + Acquisition_Task(); + } + } + else + { + Count = 0; + } + } + } + else + { + Read_Task(); + } + } +} + +void Read_Task() +{ + char host_cmd; + IAPCode Flash_State; + bool bAcq_Done; + + Flash_State = verify_erased(Flash_Base_Address, KL25_Flash_Size - (RESERVED_SECTOR * SECTOR_SIZE)); + if (Flash_State == 0) // Virgin Flash ? + { + bAcq_Done = 0; + } + else + { + bAcq_Done = 1; + } + + Clear_Led(); + wait_ms(500); + + if (bAcq_Done == 1) + { + Led_Green = LED_ON; + Host_Comm.putc('1'); + } + else + { + Led_Red = LED_ON; + Host_Comm.putc('0'); + } + + if(Host_Comm.readable()) // Did we receive a char from Host ? + { + host_cmd = Host_Comm.getc(); // Get it + + if ((host_cmd == 'R') || (host_cmd == 'r')) // Read Flash Command ? + { + Read_Data_Logging(); // Read and send acquisition data + } + } + wait_ms(50); +} + +void Acquisition_Task() +{ + int Acq_Status; + + Clear_Led(); + + Acq_Status = Acquisition_Flash(); + + Clear_Led(); + + while (Check_Jumper() == JUMPER_PRESENT) + { + if (Acq_Status != FLASH_ACQ_DONE) + { + Led_Red = !Led_Red; + } + else + { + Led_Green = !Led_Green; + } + wait_ms(100); + } +} + +void Clear_Led(void) +{ + Led_Red = LED_OFF; + Led_Green = LED_OFF; + Led_Blue = LED_OFF ; // Bug on board : Turning On Blue Led decrease consumption... +} + +bool Check_Jumper() // If J1_15 and J1_16 connected together -> return JUMPER_PRESENT +{ + uint8_t i; + + for (i = 0 ; i < 2 ; i ++) + { + Start_Pulse_Out = LEVEL_1; + wait_ms(1); + if (Start_Pulse_In != LEVEL_1) + { + return NO_JUMPER; + } + + Start_Pulse_Out = LEVEL_0; + wait_ms(1); + if (Start_Pulse_In != LEVEL_0) + { + return NO_JUMPER; + } + } + return JUMPER_PRESENT; +} + +int Acquisition_Flash(void) +{ + int Status; + int Flash_Ptr ; + uint8_t Data_Ptr; + Accel_Data myData[2]; + uint8_t Ready; + int Led_Counter; + + + for (Flash_Ptr = Flash_Base_Address ; Flash_Ptr < KL25_Flash_Size ; Flash_Ptr += 0x400) + { + Status = erase_sector(Flash_Ptr); // Erase sector + + if (Status !=0) + { + return ERASE_FLASH_ERROR; + } + } + + Flash_Ptr = Flash_Base_Address; + + Led_Blue = LED_ON; + + Led_Counter = 0; + Data_Ptr = 0; + while (Flash_Ptr < KL25_Flash_Size ) // Acq Loop + { + while (bTimer == 0) // Wait Acq Tick Timer + { + + } + bTimer = 0; + + Accel_Enable = ENABLE_STATE; // Rising Edge -> Start Accel Measure + + if ((float) Led_Counter * ACQ_TIMER_PERIOD == 1.0) // Blink at 1 Hz + { + Led_Counter = 0; + Led_Blue = !Led_Blue; + } + + + Ready = 0; + while((Ready && 0x10) == 0) // Wait Accelerometer have new data's + { + Ready = my8491.Read_Status(); + } + + myData[Data_Ptr].X = my8491.getAccAxis(REG_OUT_X_MSB); + myData[Data_Ptr].Y = my8491.getAccAxis(REG_OUT_Y_MSB); + myData[Data_Ptr].Z = my8491.getAccAxis(REG_OUT_Z_MSB); + + Led_Counter++; + + Accel_Enable = DISABLE_STATE; + + //Host_Comm.printf("\n\r%x\tX = %f", Flash_Ptr, float(myData[Data_Ptr].X)*4.0/4096.0 ); + //Host_Comm.printf("\tY = %f", float(myData[Data_Ptr].Y)*4.0/4096.0 ); + //Host_Comm.printf("\tZ = %f", float(myData[Data_Ptr].Z)*4.0/4096.0 ); + + Data_Ptr ++; + + if (Data_Ptr == 2)// Save 2 acquistions -> 2 * 3 * 2 bytes = 12 bytes + { + Data_Ptr = 0; + Status = program_flash(Flash_Ptr, (char *) &myData[0].X, 4); // Write 4 bytes in the Flash + if (Status !=0) + { + return WRITE_FLASH_ERROR; + } + + Flash_Ptr += 4; + Status = program_flash(Flash_Ptr, (char *) &myData[0].Z, 4); // Write 4 bytes in the Flash + if (Status !=0) + { + return WRITE_FLASH_ERROR; + } + + Flash_Ptr += 4; + Status = program_flash(Flash_Ptr, (char *) &myData[1].Y, 4); // Write 4 bytes in the Flash + if (Status !=0) + { + return WRITE_FLASH_ERROR; + } + + Flash_Ptr += 4; + + if ((Flash_Ptr & 0x3FC) == 0x3FC) + { + Flash_Ptr += 4; //170 * 6 = 1020 ---> skip 4 last bytes of each sector of 1024 bytes + } + } + if (Check_Jumper() != JUMPER_PRESENT) // If Jumper remoded -> Stop Acquisition + { + return FLASH_ACQ_DONE ; + } + } + return FLASH_ACQ_DONE ; +} + +int Read_Data_Logging() +{ + int16_t *data = (int16_t *) Flash_Base_Address; // uint16 pointer of data stored in Flash + int Flash_Ptr; + char cmd; + int Record_Counter; + float X_Val, Y_Val, Z_Val; + int16_t Raw_X, Raw_Y, Raw_Z; + int Max_Record; + + Clear_Led(); + + Max_Record = Nb_Sector * (SECTOR_SIZE / sizeof(Accel_Data)); + Record_Counter = 0; + Flash_Ptr = 0; + + //Host_Comm.printf("\n\rBegin of Data"); + + while (Record_Counter < Max_Record) + { + Led_Green = !Led_Green; + Led_Blue = !Led_Green; + + if(Host_Comm.readable()) + { + cmd = Host_Comm.getc(); + if ((cmd == 'S') || (cmd == 's')) // Receiving 'S' or 's' means stop Read Flash + { + Clear_Led(); + return 0; + } + } + + Record_Counter ++; + + Raw_X = data[Flash_Ptr++]; + Raw_Y = data[Flash_Ptr++]; + Raw_Z = data[Flash_Ptr++]; + + if ((Raw_X == -1) && (Raw_Y == -1) && (Raw_Z == -1)) // Valid data ? (!= 0xFFFFFFFF from empty Flash sector) + { + } + else + { + X_Val = float(Raw_X) * 4.0/4096.0; + Y_Val = float(Raw_Y) * 4.0/4096.0; + Z_Val = float(Raw_Z) * 4.0/4096.0; + + Host_Comm.printf("\n\r%d\tX=%.4f\tY=%.4f\tZ=%.4f", Record_Counter, X_Val, Y_Val, Z_Val); + } + + if ((Flash_Ptr & 0x1FE) == 0x1FE) + { + Flash_Ptr +=2; // skip the last bytes at the end of a sector + } + } + //Host_Comm.printf("\n\rEnd of Data"); + Clear_Led(); + return 0; +} + +/* Interrupt Task */ +void myTimer_Acq_Task() +{ + bTimer = 1; +} +