Code for the project of LELEC2811 2017

Dependencies:   FreescaleIAP MMA8491Q_PG mbed

Fork of LELEC_2811_Accelerometer by LELEC2811 - I&S

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;
+}
+