Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: FreescaleIAP MMA8451Q mbed
Diff: main.cpp
- Revision:
- 0:17f544fcad6f
- Child:
- 1:19cb7d77efe1
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp Sat Sep 22 23:17:02 2018 +0000
@@ -0,0 +1,386 @@
+/* LELEC_2811 Accelerometer Project
+ UCL 2014 - P. Gérard
+*/
+#include "mbed.h"
+#include "FreescaleIAP.h" // Library for Flash Access
+#include "MMA8451Q.h" // Accelerometer
+
+#define MMA8451_I2C_ADDRESS (0x1d<<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 MMA8451
+MMA8451Q my8451(PTE25, PTE24, MMA8451_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];
+ 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;
+ }
+
+ myData[Data_Ptr].X = my8451.getAccAxis(REG_OUT_X_MSB);
+ myData[Data_Ptr].Y = my8451.getAccAxis(REG_OUT_Y_MSB);
+ myData[Data_Ptr].Z = my8451.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[0].Y, 4); // Bug corrected 23/11/2016
+ 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;
+}
\ No newline at end of file