Maxim Integrated / LP_Receiver_Wakeup

Dependencies:   MAX30208 mbed-dev max32630fthr USBDevice

Revision:
2:e4fcc385e824
Parent:
1:8834bc22c2e7
Child:
3:4af4942a59f2
--- a/main.cpp	Wed Jan 24 01:15:14 2018 +0000
+++ b/main.cpp	Fri Sep 04 16:57:37 2020 +0000
@@ -1,3 +1,55 @@
+/*******************************************************************************
+* Copyright (C) Maxim Integrated Products, Inc., All Rights Reserved.
+*
+* Permission is hereby granted, free of charge, to any person obtaining a
+* copy of this software and associated documentation files (the "Software"),
+* to deal in the Software without restriction, including without limitation
+* the rights to use, copy, modify, merge, publish, distribute, sublicense,
+* and/or sell copies of the Software, and to permit persons to whom the
+* Software is furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included
+* in all copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
+* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+* OTHER DEALINGS IN THE SOFTWARE.
+*
+* Except as contained in this notice, the name of Maxim Integrated
+* Products, Inc. shall not be used except as stated in the Maxim Integrated
+* Products, Inc. Branding Policy.
+*
+* The mere transfer of this software does not imply any licenses
+* of trade secrets, proprietary technology, copyrights, patents,
+* trademarks, maskwork rights, or any other form of intellectual
+* property whatsoever. Maxim Integrated Products, Inc. retains all
+* ownership rights.
+*******************************************************************************
+This is code for the MAX1473 RF Receiver circuit. This program will capture,
+translate, and unencrypt messages received using the ForwardErrCorr.h format.
+The example uses MAX30208 temperature data as an example. The MAX1473 will turn
+on for 5ms every 500ms to check for data. If there is data to be read, the reciever
+will remain on to listen for a full packet. If there is no data, it will return to
+sleep mode for another 500ms.
+
+Hardware Setup and connections:
+
+    MAX32630FTHR->  MAX1473 Ev-Kit
+    
+    3.3V        ->  VDD
+    GND         ->  GND
+    P3_0        ->  DATA_OUT
+    P5_6        ->  DATA_OUT
+    P5_1        ->  ENABLE
+    1.8V -> 200KOhm -> TP2
+    
+*******************************************************************************
+*/
+
 #include "mbed.h"
 #include "max32630fthr.h"
 #include "mxc_config.h"
@@ -5,34 +57,107 @@
 #include "gpio.h"
 #include "rtc.h"
 #include "MAX14690.h"
+#include "USBSerial.h"
+#include "MAX30208.h"
+#include "ForwardErrCorr.h"
+
+MAX32630FTHR pegasus(MAX32630FTHR::VIO_3V3);   
+
+I2C i2c(P3_4, P3_5);  //sda,scl
+
+RawSerial uart(P3_1,P3_0); //tx,rx
+MAX30208 TempSensor(i2c, 0x50); //Constructor, takes 7-bit slave adrs
+
+char  TransTable[] = {0x1F,0x18,0x06,0x01}; //Used to translate data for FEC -- Make sure it is identical to transmitter
+#define SymmetricKey "RfIsCoOl" //Set Symmetric Key here -- Make sure it is identical to transmitter
+Translator transRx(SymmetricKey, TransTable);
+
+USBSerial microUSB;         //Micro USB Connection for printing to Serial Monitor
 
 DigitalOut rLED(LED1);
 DigitalOut gLED(LED2);
 DigitalOut bLED(LED3);
 
-DigitalIn sw1(SW1);
+InterruptIn CheckData(P5_6);        //Interrupt pin for detecting incoming messages
+
+DigitalIn sw1(SW1);                 //Used on start-up to stay in active mode for re-programming
+DigitalOut RXEnable(P5_1);          //Used to Enable Reciever
+
+
+volatile bool reading;      //Check interrupt to dtermin if there is incoming data
+volatile char dataIn[50];            //Hold incoming message
+volatile int datacounter;   //Count the incoming data
+
 
 // *****************************************************************************
+/**
+* @brief  Setup RTC with scaler set to 1 tick per ~ 1 ms 
+*/
 void RTC_Setup()
 {
-    rtc_cfg_t RTCconfig;
-    
-    RTCconfig.compareCount[0] = 1;//1 second timer
-    RTCconfig.compareCount[1] = 10;//10 second timer
-    RTCconfig.prescaler = RTC_PRESCALE_DIV_2_12; //1Hz clock
-    RTCconfig.prescalerMask = RTC_PRESCALE_DIV_2_12;//used for prescaler compare
+    rtc_cfg_t RTCconfig;        //Declare RTC Object
+    RTCconfig.prescaler = RTC_PRESCALE_DIV_2_2;     //~1ms per RTC tick
+    RTCconfig.prescalerMask = RTC_PRESCALE_DIV_2_2; //~1ms per RTC tick(0.97656ms)
     RTCconfig.snoozeCount = 0;
     RTCconfig.snoozeMode = RTC_SNOOZE_DISABLE;
 
-    RTC_Init(&RTCconfig);
+    RTC_Init(&RTCconfig);   //initialize RTC with desired configuration
+
+    RTC_Start();            //Begin RTC
+}
 
-    RTC_Start();
+//*****************************************************************************
+/**
+* @brief  Serial Intterupt to read incoming data from Reciever
+*/
+void SerialCallback(){ 
+    wait_ms(1);
+    if (datacounter  < 50){
+        while(uart.readable() && datacounter <= 50){
+            dataIn[datacounter] = uart.getc();
+            datacounter++;
+        }
+    }
 }
 
-/******************************************************************************/
+//*****************************************************************************
+/**
+* @brief  Shorten input data array to only one full transmission (eliminate excess and partial transactions)
+* @param  start - array position that contatins starting character ('b')
+* @param  input - Character array that holds the recorded data
+* @param  output - Output array that holds one packet of data
+* @return 0 on success, 1 if the end character cannot be found
+*/
+int buildArray(int start, volatile char *input,char *output){
+    int i = start+1;
+    int k = 0;
+    while(input[i] != 'c'){
+        output[k] = input[i];
+        i++;
+        k++;
+        if (i > 50){
+            return (1);
+        }
+    }
+    return(0);
+}
+
+//*****************************************************************************
+/**
+* @brief  Intterupt for checking incoming data. When triggered, intterupt is added for reading incoming data, and flag is set for incoming data
+*/
+void CheckUart(){
+    uart.attach(&SerialCallback);
+    CheckData.disable_irq();
+    reading = 1;
+}
+
+//******************************************************************************
+
 int main(void)
 {
     MAX32630FTHR pegasus(MAX32630FTHR::VIO_3V3);
+    uart.baud(9600);
     
     //check if starting at main because of LP0 wake-up
     if(LP_IsLP0WakeUp()) {
@@ -43,46 +168,118 @@
         //Only configure RTC the first time around 
         RTC_Setup();
     }
-
     gLED = LED_ON;
     rLED = LED_ON;
     bLED = LED_ON;
-
+    
+    CheckData.mode(PullNone);   //Set Interrupt pin to no pull
+    
+    //microUSB.printf("Waking Up\r\n");
+    
     while(1) {
-        
-        //hold down switch 1 to prevent the microcontroller from going into LP0
-        while(sw1 == 0);
-        
-        //keep LED on long enough to see it!
-        wait_ms(100);
-        
-        gLED = LED_OFF;
-        rLED = LED_OFF;
-        bLED = LED_OFF;
-
-        //disable unused PMIC rails to minimize power consumption
-        pegasus.max14690.ldo2SetMode(MAX14690::LDO_DISABLED);
-        pegasus.max14690.ldo3SetMode(MAX14690::LDO_DISABLED);
-
         //Clear existing wake-up config
         LP_ClearWakeUpConfig();
 
         //Clear any event flags
         LP_ClearWakeUpFlags();
+        
+        //hold down switch 1 to prevent the microcontroller from going into LP0
+        //Hold down Switch 1 in order to re-program device
+        while(sw1 == 0);
+        
+        RXEnable = 1;   //Enable the Reciever
+        wait_us(250);       //Give the Reciever time to wake-up (250us on data Sheet)
+        datacounter = 0;    //Reset Data Counter for transaction
+        reading = 0;        //REset reading flag
+        CheckData.fall(&CheckUart); //Set falling edge intterupt to check for incoming data
+        wait_ms(5);      //Wait for incoming data
+        printf("Checking for data\r\n");
+        
+        //If CheckData intterupt is triggered, reading flag is set
+        if(reading == 1){
+            
+            //Variables used for translation of incoming data
+            char dataOut[50];
+            uint16_t output[2];
+             
+            wait_ms(50);    //Wait for a full transimission of data
+            uart.attach(NULL);  //Turn off intterupt on data Read
+            RXEnable = 0;   //Turn off Receiver
+            int start = 0; //Variable to find start of packet
+            
+            //Find starting position of full transmission
+            while(dataIn[start] != 'b' && start < datacounter){
+                start++;
+            }
+            
+            //Make sure this is the starting character for transmission
+            if (dataIn[start] == 'b'){        
 
+                //Condense array to just one data transmission
+                if (buildArray(start,dataIn,dataOut) == 0){
+                    //Decrypt message with Symmetric Key and FEC to readible data
+                    if (transRx.Decrypt(dataOut,output) == 1){
+                        printf("Error reconstructing\r\n");
+                    } //if
+                    
+                    //Read Device ID and Type
+                    char DeviceType = dataIn[start+1];
+                    char DeviceID = dataIn[start+2];
+                    
+                    //Print out the Device Type, ID, and Temperature
+                    printf("Device Type: %c\r\n", DeviceType);
+                    printf("Device ID: %i\r\n", DeviceID);
+                    printf("data = %i\r\n",output[0]);
+                    wait(1);
+                    
+                    //Allow the computer Serial Port to establish connection with computer
+                    //wait(5);
+                    
+                    //Convert translated data into temperature data
+                    float clesius = TempSensor.toCelsius(output[0]);
+                    float fare = TempSensor.toFahrenheit(clesius);
+                    printf("C = %f\r\n",clesius);
+                    printf("F = %f\r\n",fare);
+                    wait(2);    //Allow time to print all information before returning to sleep mode
+                } //if    
+                //End character cannot be found while condensing array (incomplete transmission)
+                else{
+                    printf("No end character found\r\n");
+                } //else
+            } //if
+        
+            //Reset dataIn array for next transmission
+            for (int i = 0;i<datacounter;i++){
+                dataIn[i] = 0;
+            } //for
+        }//if
+        
+        //Turn off intterupt for checking data
+        CheckData.disable_irq();
+        
         //configure wake-up on RTC compare 0
         //LP_ConfigRTCWakeUp(enable compare 0, enable compare 1, set prescale, set rollover)
         LP_ConfigRTCWakeUp(1, 0, 0, 0);
         
-        //read the current RTC timer and add 5 seconds to it
-        uint32_t cmp = RTC_GetCount() + 5;
+        RXEnable = 0;   //Turn off Reciever
+        
+        //disable unused PMIC rails to minimize power consumption
+        pegasus.max14690.ldo2SetMode(MAX14690::LDO_DISABLED);
+        pegasus.max14690.ldo3SetMode(MAX14690::LDO_DISABLED);
+        
+        //Reset RTC value
+        RTC_SetCount(0);
+        gLED = LED_OFF;
+        rLED = LED_OFF;
+        bLED = LED_OFF;
         
         //set RTC to generate an interrupt 5 seconds from current value
-        RTC_SetCompare(0,cmp);
+        RTC_SetCompare(0,500);
         
         //clear comparison flag in the RTC registers
         RTC_ClearFlags(MXC_F_RTC_FLAGS_COMP0);
 
+        //Enter Deep Sleep Mode
         LP_EnterLP0();
 
         //firmware will reset with no prior knowledge on wake-up