/****************************************************************************** * @file main.c * @brief Fichier main du projet. * @author Etienne Le Jolu ******************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include #include "string_TD1208.h" #include "gps_custom.h" #include "magnetometer.h" #include "i2c_custom.h" #include "MMA.h" /* This file declare all "dynamic" library data. It should be last included file * Standard size value can be override before including this file */ #define TD_SENSOR_USE_CODE 0 #define TD_GEOLOC_USE_CODE 0 #include /******************************************************************************* ************************* DEFINES ***************************************** ******************************************************************************/ #define TAP_PORT TIM2_PORT /**< LED port */ #define TAP_BIT TIM2_BIT /**< LED bit */ #define TAP_MASK TIM2_MASK /**************************Varibles Globales**********************************/ const uint8_t BasicFont[96][8] = { {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, {0x00,0x00,0x5F,0x00,0x00,0x00,0x00,0x00}, {0x00,0x00,0x07,0x00,0x07,0x00,0x00,0x00}, {0x00,0x14,0x7F,0x14,0x7F,0x14,0x00,0x00}, {0x00,0x24,0x2A,0x7F,0x2A,0x12,0x00,0x00}, {0x00,0x23,0x13,0x08,0x64,0x62,0x00,0x00}, {0x00,0x36,0x49,0x55,0x22,0x50,0x00,0x00}, {0x00,0x00,0x05,0x03,0x00,0x00,0x00,0x00}, {0x00,0x1C,0x22,0x41,0x00,0x00,0x00,0x00}, {0x00,0x41,0x22,0x1C,0x00,0x00,0x00,0x00}, {0x00,0x08,0x2A,0x1C,0x2A,0x08,0x00,0x00}, {0x00,0x08,0x08,0x3E,0x08,0x08,0x00,0x00}, {0x00,0xA0,0x60,0x00,0x00,0x00,0x00,0x00}, {0x00,0x08,0x08,0x08,0x08,0x08,0x00,0x00}, {0x00,0x60,0x60,0x00,0x00,0x00,0x00,0x00}, {0x00,0x20,0x10,0x08,0x04,0x02,0x00,0x00}, {0x00,0x3E,0x51,0x49,0x45,0x3E,0x00,0x00}, {0x00,0x00,0x42,0x7F,0x40,0x00,0x00,0x00}, {0x00,0x62,0x51,0x49,0x49,0x46,0x00,0x00}, {0x00,0x22,0x41,0x49,0x49,0x36,0x00,0x00}, {0x00,0x18,0x14,0x12,0x7F,0x10,0x00,0x00}, {0x00,0x27,0x45,0x45,0x45,0x39,0x00,0x00}, {0x00,0x3C,0x4A,0x49,0x49,0x30,0x00,0x00}, {0x00,0x01,0x71,0x09,0x05,0x03,0x00,0x00}, {0x00,0x36,0x49,0x49,0x49,0x36,0x00,0x00}, {0x00,0x06,0x49,0x49,0x29,0x1E,0x00,0x00}, {0x00,0x00,0x36,0x36,0x00,0x00,0x00,0x00}, {0x00,0x00,0xAC,0x6C,0x00,0x00,0x00,0x00}, {0x00,0x08,0x14,0x22,0x41,0x00,0x00,0x00}, {0x00,0x14,0x14,0x14,0x14,0x14,0x00,0x00}, {0x00,0x41,0x22,0x14,0x08,0x00,0x00,0x00}, {0x00,0x02,0x01,0x51,0x09,0x06,0x00,0x00}, {0x00,0x32,0x49,0x79,0x41,0x3E,0x00,0x00}, {0x00,0x7E,0x09,0x09,0x09,0x7E,0x00,0x00}, {0x00,0x7F,0x49,0x49,0x49,0x36,0x00,0x00}, {0x00,0x3E,0x41,0x41,0x41,0x22,0x00,0x00}, {0x00,0x7F,0x41,0x41,0x22,0x1C,0x00,0x00}, {0x00,0x7F,0x49,0x49,0x49,0x41,0x00,0x00}, {0x00,0x7F,0x09,0x09,0x09,0x01,0x00,0x00}, {0x00,0x3E,0x41,0x41,0x51,0x72,0x00,0x00}, {0x00,0x7F,0x08,0x08,0x08,0x7F,0x00,0x00}, {0x00,0x41,0x7F,0x41,0x00,0x00,0x00,0x00}, {0x00,0x20,0x40,0x41,0x3F,0x01,0x00,0x00}, {0x00,0x7F,0x08,0x14,0x22,0x41,0x00,0x00}, {0x00,0x7F,0x40,0x40,0x40,0x40,0x00,0x00}, {0x00,0x7F,0x02,0x0C,0x02,0x7F,0x00,0x00}, {0x00,0x7F,0x04,0x08,0x10,0x7F,0x00,0x00}, {0x00,0x3E,0x41,0x41,0x41,0x3E,0x00,0x00}, {0x00,0x7F,0x09,0x09,0x09,0x06,0x00,0x00}, {0x00,0x3E,0x41,0x51,0x21,0x5E,0x00,0x00}, {0x00,0x7F,0x09,0x19,0x29,0x46,0x00,0x00}, {0x00,0x26,0x49,0x49,0x49,0x32,0x00,0x00}, {0x00,0x01,0x01,0x7F,0x01,0x01,0x00,0x00}, {0x00,0x3F,0x40,0x40,0x40,0x3F,0x00,0x00}, {0x00,0x1F,0x20,0x40,0x20,0x1F,0x00,0x00}, {0x00,0x3F,0x40,0x38,0x40,0x3F,0x00,0x00}, {0x00,0x63,0x14,0x08,0x14,0x63,0x00,0x00}, {0x00,0x03,0x04,0x78,0x04,0x03,0x00,0x00}, {0x00,0x61,0x51,0x49,0x45,0x43,0x00,0x00}, {0x00,0x7F,0x41,0x41,0x00,0x00,0x00,0x00}, {0x00,0x02,0x04,0x08,0x10,0x20,0x00,0x00}, {0x00,0x41,0x41,0x7F,0x00,0x00,0x00,0x00}, {0x00,0x04,0x02,0x01,0x02,0x04,0x00,0x00}, {0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00}, {0x00,0x01,0x02,0x04,0x00,0x00,0x00,0x00}, {0x00,0x20,0x54,0x54,0x54,0x78,0x00,0x00}, {0x00,0x7F,0x48,0x44,0x44,0x38,0x00,0x00}, {0x00,0x38,0x44,0x44,0x28,0x00,0x00,0x00}, {0x00,0x38,0x44,0x44,0x48,0x7F,0x00,0x00}, {0x00,0x38,0x54,0x54,0x54,0x18,0x00,0x00}, {0x00,0x08,0x7E,0x09,0x02,0x00,0x00,0x00}, {0x00,0x18,0xA4,0xA4,0xA4,0x7C,0x00,0x00}, {0x00,0x7F,0x08,0x04,0x04,0x78,0x00,0x00}, {0x00,0x00,0x7D,0x00,0x00,0x00,0x00,0x00}, {0x00,0x80,0x84,0x7D,0x00,0x00,0x00,0x00}, {0x00,0x7F,0x10,0x28,0x44,0x00,0x00,0x00}, {0x00,0x41,0x7F,0x40,0x00,0x00,0x00,0x00}, {0x00,0x7C,0x04,0x18,0x04,0x78,0x00,0x00}, {0x00,0x7C,0x08,0x04,0x7C,0x00,0x00,0x00}, {0x00,0x38,0x44,0x44,0x38,0x00,0x00,0x00}, {0x00,0xFC,0x24,0x24,0x18,0x00,0x00,0x00}, {0x00,0x18,0x24,0x24,0xFC,0x00,0x00,0x00}, {0x00,0x00,0x7C,0x08,0x04,0x00,0x00,0x00}, {0x00,0x48,0x54,0x54,0x24,0x00,0x00,0x00}, {0x00,0x04,0x7F,0x44,0x00,0x00,0x00,0x00}, {0x00,0x3C,0x40,0x40,0x7C,0x00,0x00,0x00}, {0x00,0x1C,0x20,0x40,0x20,0x1C,0x00,0x00}, {0x00,0x3C,0x40,0x30,0x40,0x3C,0x00,0x00}, {0x00,0x44,0x28,0x10,0x28,0x44,0x00,0x00}, {0x00,0x1C,0xA0,0xA0,0x7C,0x00,0x00,0x00}, {0x00,0x44,0x64,0x54,0x4C,0x44,0x00,0x00}, {0x00,0x08,0x36,0x41,0x00,0x00,0x00,0x00}, {0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0x00}, {0x00,0x41,0x36,0x08,0x00,0x00,0x00,0x00}, {0x00,0x02,0x01,0x01,0x02,0x01,0x00,0x00}, {0x00,0x02,0x05,0x05,0x02,0x00,0x00,0x00} }; uint8_t grayH; uint8_t grayL; float temp = 0, humi; unsigned int rawtemp, rawhumi; float ttemp, thumi; uint16_t resultI2C; /******************************************************************************* ****************************** CONSTANTS ************************************ ******************************************************************************/ /****************************Fonction OLED************************************/ void sendCommandOLED(uint8_t command){ uint8_t values[2] = {0,0}; // Prepare for a write of 2 bytes I2C_TransferSeq_TypeDef i2cTransfert; values[0] = 0x80; values[1] = command; i2cTransfert.addr = 0x78; i2cTransfert.flags = I2C_FLAG_WRITE_WRITE; i2cTransfert.buf[0].len = 1; i2cTransfert.buf[0].data = &values[0]; i2cTransfert.buf[1].len = 1; i2cTransfert.buf[1].data = &values[1]; // Start I2C read int _status = I2C_TransferInit(I2C0, &i2cTransfert); while ( _status == i2cTransferInProgress) { _status = I2C_Transfer(I2C0); } } void sendDataOLED(uint8_t data){ uint8_t values[2] = {0,0}; // Prepare for a write of 2 bytes I2C_TransferSeq_TypeDef i2cTransfert; values[0] = 0x40; values[1] = data; i2cTransfert.addr = 0x78; i2cTransfert.flags = I2C_FLAG_WRITE_WRITE; i2cTransfert.buf[0].len = 1; i2cTransfert.buf[0].data = &values[0]; i2cTransfert.buf[1].len = 1; i2cTransfert.buf[1].data = &values[1]; // Start I2C read int _status = I2C_TransferInit(I2C0, &i2cTransfert); while ( _status == i2cTransferInProgress) { _status = I2C_Transfer(I2C0); } } void initOLED(void) { sendCommandOLED(0xFD); // Unlock OLED driver IC MCU interface from entering command. i.e: Accept commands sendCommandOLED(0x12); sendCommandOLED(0xAE); // Set display off sendCommandOLED(0xA8); // set multiplex ratio sendCommandOLED(0x5F); // 96 sendCommandOLED(0xA1); // set display start line sendCommandOLED(0x00); sendCommandOLED(0xA2); // set display offset sendCommandOLED(0x60); sendCommandOLED(0xA0); // set remap sendCommandOLED(0x46); sendCommandOLED(0xAB); // set vdd internal sendCommandOLED(0x01); // sendCommandOLED(0x81); // set contrasr sendCommandOLED(0x53); // 100 nit sendCommandOLED(0xB1); // Set Phase Length sendCommandOLED(0X51); // sendCommandOLED(0xB3); // Set Display Clock Divide Ratio/Oscillator Frequency sendCommandOLED(0x01); sendCommandOLED(0xB9); // sendCommandOLED(0xBC); // set pre_charge voltage/VCOMH sendCommandOLED(0x08); // (0x08); sendCommandOLED(0xBE); // set VCOMH sendCommandOLED(0X07); // (0x07); sendCommandOLED(0xB6); // Set second pre-charge period sendCommandOLED(0x01); // sendCommandOLED(0xD5); // enable second precharge and enternal vsl sendCommandOLED(0X62); // (0x62); sendCommandOLED(0xA4); // Set Normal Display Mode sendCommandOLED(0x2E); // Deactivate Scroll sendCommandOLED(0xAF); // Switch on display TD_RTC_Delay(T100MS); // Row Address sendCommandOLED(0x75); // Set Row Address sendCommandOLED(0x00); // Start 0 sendCommandOLED(0x5f); // End 95 // Column Address sendCommandOLED(0x15); // Set Column Address sendCommandOLED(0x08); // Start from 8th Column of driver IC. This is 0th Column for OLED sendCommandOLED(0x37); // End at (8 + 47)th column. Each Column has 2 pixels(segments) //tfp_printf("FIN INIT OLED\r\n"); // Init gray level for text. Default:Brightest White grayH= 0xF0; grayL= 0x0F; } void clearDisplay(void) { unsigned char i,j; for(j=0;j<48;j++) { for(i=0;i<96;i++) //clear all columns { sendDataOLED(0x00); } } } void putChar(char C) { unsigned char i,j; if(C < 32 || C > 127) //Ignore non-printable ASCII characters. This can be modified for multilingual font. { C=' '; //Space } for(i=0;i<8;i=i+2) { for(j=0;j<8;j++) { // Character is constructed two pixel at a time using vertical mode from the default 8x8 font char c=0x00; char bit1=(BasicFont[C-32][i] >> j) & 0x01; char bit2=(BasicFont[C-32][i+1] >> j) & 0x01; // Each bit is changed to a nibble c|=(bit1)?grayH:0x00; c|=(bit2)?grayL:0x00; sendDataOLED(c); } } } void putString(const char *String) { unsigned char i=0; while(String[i]) { putChar(String[i]); i++; } } unsigned char putNumber(long long_num) { unsigned char char_buffer[10]=""; unsigned char i = 0; unsigned char f = 0; if (long_num < 0) { f=1; putChar('-'); long_num = -long_num; } else if (long_num == 0) { f=1; putChar('0'); return f; } while (long_num > 0) { char_buffer[i++] = long_num % 10; long_num /= 10; } f=f+i; for(; i > 0; i--) { putChar('0'+ char_buffer[i - 1]); } return f; } void setVerticalMode(void) { sendCommandOLED(0xA0); // remap to sendCommandOLED(0x46); // Vertical mode } void setTextXY(uint8_t Row, uint8_t Column) { //Column Address sendCommandOLED(0x15); /* Set Column Address */ sendCommandOLED(0x08+(Column*4)); /* Start Column: Start from 8 */ sendCommandOLED(0x37); /* End Column */ // Row Address sendCommandOLED(0x75); /* Set Row Address */ sendCommandOLED(0x00+(Row*8)); /* Start Row*/ sendCommandOLED(0x07+(Row*8)); /* End Row*/ } void setGrayLevel(uint8_t grayLevel) { grayH = (grayLevel << 4) & 0xF0; grayL = grayLevel & 0x0F; } /******************************************************************************* ************************** PUBLIC FUNCTIONS ******************************* ******************************************************************************/ static bool dtinterrupt = false; static bool detressInt = false; static bool readInt = false; static void dtInterrupt(uint32_t mask) { dtinterrupt = true; } static void detrInt(uint32_t mask) { detressInt = true; } static void RFIDInt(uint32_t mask) { readInt = true; } static void Stop(uint32_t arg, uint8_t repetition) { dtinterrupt = false; } /***************************************************************************//** * @brief * User setup function. ******************************************************************************/ void TD_USER_Setup(void) { int type; IRQn_Type irq_parity; IRQn_Type irq_parity1; IRQn_Type irq_parity2; TD_UART_Options_t options = {LEUART_DEVICE, LEUART_LOCATION, 9600, 8, 'N',1, false}; TD_UART_Open(&options, TD_STREAM_RDWR); CMU_ClockEnable(cmuClock_GPIO, true); CMU_ClockEnable(cmuClock_I2C0, true); GPIO_PinModeSet(SCL_PORT, SCL_BIT,gpioModeWiredAnd,1); GPIO_PinModeSet(SDA_PORT, SDA_BIT,gpioModeWiredAnd,1); I2C0->ROUTE = I2C_ROUTE_SDAPEN | I2C_ROUTE_SCLPEN | _I2C_ROUTE_LOCATION_LOC0; I2C_Init_TypeDef i2cInit = I2C_INIT_DEFAULT; I2C_Init(I2C0, &i2cInit); initMMA(); initOLED(); clearDisplay(); sendCommandOLED(0xA4); setVerticalMode(); setTextXY(0,0); setGrayLevel(5); TD_RTC_Delay(T500MS); // Define USR0 pin as an output in push-pull drive mode GPIO_PinModeSet(USR0_PORT, USR0_BIT, gpioModePushPullDrive, 1); GPIO_DriveModeSet(USR0_PORT, gpioDriveModeHigh); GPIO_PinOutSet(USR0_PORT, USR0_BIT); // config gps gps_output_config_GLL(); TD_RTC_Delay(T500MS); gps_sleep(); // Define the TIM2 pin as an input with an internal pull-up resistor GPIO_PinModeSet(TAP_PORT, TAP_BIT, gpioModeInputPull, 1); // Define USR3 pin as an input with an internal pull-up resistor GPIO_PinModeSet(USR3_PORT, USR3_BIT, gpioModeInputPull, 1); // Define USR4 pin as an input with an internal pull-up resistor GPIO_PinModeSet(USR4_PORT, USR4_BIT, gpioModeInputPull, 1); //***************** Config Interruption Double Tap detection*********************** type = (TAP_MASK & TD_GPIO_ODD_MASK) ? TD_GPIO_USER_ODD : TD_GPIO_USER_EVEN; TD_GPIO_SetCallback(type, dtInterrupt, TAP_MASK); // Enable rising edge interrupts on interrupt MMA pin GPIO_IntConfig(TAP_PORT, TAP_BIT, true, false, true); // Clear and enable the corresponding interrupt in the CPU's Nested Vector // Interrupt Controller irq_parity = (TAP_MASK & TD_GPIO_ODD_MASK) ? GPIO_ODD_IRQn : GPIO_EVEN_IRQn; //***************** Config Interruption Boutton*********************** type = (USR3_MASK & TD_GPIO_ODD_MASK) ? TD_GPIO_USER_ODD : TD_GPIO_USER_EVEN; TD_GPIO_SetCallback(type, detrInt, USR3_MASK); // Enable rising edge interrupts on interrupt MMA pin GPIO_IntConfig(USR3_PORT, USR3_BIT, true, false, true); // Clear and enable the corresponding interrupt in the CPU's Nested Vector // Interrupt Controller irq_parity1 = (USR3_MASK & TD_GPIO_ODD_MASK) ? GPIO_ODD_IRQn : GPIO_EVEN_IRQn; //***************** Config Interruption Boutton*********************** type = (USR4_MASK & TD_GPIO_ODD_MASK) ? TD_GPIO_USER_ODD : TD_GPIO_USER_EVEN; TD_GPIO_SetCallback(type, RFIDInt, USR4_MASK); // Enable rising edge interrupts on interrupt MMA pin GPIO_IntConfig(USR4_PORT, USR4_BIT, true, false, true); // Clear and enable the corresponding interrupt in the CPU's Nested Vector // Interrupt Controller irq_parity2 = (USR4_MASK & TD_GPIO_ODD_MASK) ? GPIO_ODD_IRQn : GPIO_EVEN_IRQn; //********************************************************************************* NVIC_ClearPendingIRQ(irq_parity); NVIC_EnableIRQ(irq_parity); NVIC_ClearPendingIRQ(irq_parity1); NVIC_EnableIRQ(irq_parity1); NVIC_ClearPendingIRQ(irq_parity2); NVIC_EnableIRQ(irq_parity2); //**********************Interruption réveil mode sleep****************************** RTC_IRQHandler(); } /***************************************************************************//** * @brief * User loop function. ******************************************************************************/ void TD_USER_Loop(void) { uint16_t i=0; char lat[50];char lng[50]; // variables qui vont contenir la position gps int c; char rfid[20]; char rst_lat[54]; char rst_lng[54]; if(dtinterrupt){ setTextXY(0,0); putString(" "); setTextXY(1,0); putString(" "); setTextXY(2,0); putString(" "); setTextXY(3,0); putString(" "); sendCommandOLED(0xAF); // On allume l'écran setTextXY(0,0); TD_SCHEDULER_AppendIrq(10, 0 , 0, 1, Stop, 0); resultI2C = I2C_WriteRead(0x80, 0xE3, 2); rawtemp = ((resultI2C&0xFF)<<8) | ((resultI2C>>8)&0x00FF); ttemp = (float) rawtemp / (float) 65536; temp = ttemp*175.72 - 46.85; putString("T:"); putNumber((long)temp); putString("C"); setTextXY(1,0); resultI2C = I2C_WriteRead(0x80, 0xE5, 2); rawhumi = ((resultI2C&0xFF)<<8) | ((resultI2C>>8)&0x00FF); thumi = (float) rawhumi/(float) 65536; humi = (125*thumi)-6; putString("H:"); putNumber((long)humi); putString("%"); setTextXY(2,0); putString("Pos :"); while(dtinterrupt){ //LECTURE MAGNETOMETRE i=(int)readHeading(); if(i<10){ setTextXY(2,7); putString(" "); } if(i>= 10 && i<100){ setTextXY(2,8); putString(" "); } setTextXY(2,6); putNumber(i); setTextXY(2,6); i++; } i=0; sendCommandOLED(0xAE); // On étein l'écran } else if(detressInt){ setTextXY(0,0); putString(" "); setTextXY(1,0); putString(" "); setTextXY(2,0); putString(" "); sendCommandOLED(0xAF); // On allume l'écran setTextXY(2,0); putString("ENVOIS SOS"); TD_SIGFOX_Send((uint8_t *) "sos", 12, 2); gps_hot_on(); TD_RTC_Delay(T1S); gps_output_config_GLL(); TD_RTC_Delay(T1S); gps_get_coordinates(lat,lng,0); setTextXY(2,0); putString(" "); sprintf(rst_lat,"lat:%s",lat); sprintf(rst_lng,"lng:%s",lng); setTextXY(2,0); putString("SENDING"); setTextXY(3,0); putString("ALERT..."); TD_SIGFOX_Send((uint8_t *) rst_lat, 12, 2); TD_SIGFOX_Send((uint8_t *) rst_lng, 12, 2); setTextXY(2,0); putString(" "); setTextXY(3,0); putString(" "); setTextXY(2,0); putString("SEND !"); TD_RTC_Delay(T1S); setTextXY(2,0); putString(" "); sendCommandOLED(0xAE); // On étein l'écran detressInt = false; } else if(readInt){ GPIO_PinOutClear(USR0_PORT, USR0_BIT); setTextXY(0,0); putString(" "); setTextXY(1,0); putString(" "); setTextXY(2,0); putString(" "); setTextXY(3,0); putString(" "); sendCommandOLED(0xAF); // On allume l'écran setTextXY(0,0); putString("INIT..."); TD_RTC_Delay(T1S); TD_UART_Flush(); setTextXY(0,0); putString(" "); setTextXY(0,0); putString("READING"); setTextXY(1,0); i = 4; rfid[0] = 'r'; rfid[1] = 'f'; rfid[2] = 'i'; rfid[3] = ':'; TD_UART_RxIRQWait(); while(TD_UART_AvailableChars()==0); while ((c = TD_UART_GetChar()) >= 0) { rfid[i] = c; putChar(rfid[i]); i++; } rfid[i] = '\0'; TD_SIGFOX_Send((uint8_t*)"sos", 12, 2); TD_SIGFOX_Send((uint8_t*)rfid, 12, 2); sendCommandOLED(0xAE); // On étein l'écran GPIO_PinOutSet(USR0_PORT, USR0_BIT); readInt = false; } TD_RTC_Sleep(); }