This Program is for MAPLE board with OLED and GPS/RTC module. OLED module(OB) : 128 x 128 pixels, 4K color GPS/RTC module(GB) : UP501 These module can buy Marutyu (http://www.marutsu.co.jp)
Diff: gpsrtc.cpp
- Revision:
- 0:58e40a872950
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gpsrtc.cpp Sun Jun 05 15:10:48 2011 +0000 @@ -0,0 +1,370 @@ +//========================================================= +// LPC1114 Project +//========================================================= +// File Name : gpsrtc.c +// Function : GPS&RTC Control +//--------------------------------------------------------- +// Rev.01 2010.08.29 Munetomo Maruyama +//--------------------------------------------------------- +// Copyright (C) 2010-2011 Munetomo Maruyama +//========================================================= +// ---- License Information ------------------------------- +// Anyone can FREELY use this code fully or partially +// under conditions shown below. +// 1. You may use this code only for individual purpose, +// and educational purpose. +// Do not use this code for business even if partially. +// 2. You should use this code under the GNU GPL. +// 3. You should remain this header text in your codes +// including Copyright credit and License Information. +// 4. Your codes should inherit this license information. +//========================================================= +// ---- Patent Notice ------------------------------------- +// I have not cared whether this system (hw + sw) causes +// infringement on the patent, copyright, trademark, +// or trade secret rights of others. You have all +// responsibilities for determining if your designs +// and products infringe on the intellectual property +// rights of others, when you use technical information +// included in this system for your business. +//========================================================= +// ---- Disclaimers --------------------------------------- +// The function and reliability of this system are not +// guaranteed. They may cause any damages to loss of +// properties, data, money, profits, life, or business. +// By adopting this system even partially, you assume +// all responsibility for its use. +//========================================================= + +//#ifdef __USE_CMSIS +//#include "LPC11xx.h" +//#endif + +//#include "gpio.h" +#include "gpsrtc.h" +//#include "i2c.h" +//#include "systick.h +#include "type.h" +//#include "uart.h" +//#include "utility.h" +#include "mbed.h" + +Serial device(p9,p10); //tx,rx +I2C i2c(p28,p27); //sda.scl + +//====================== +// Time Zone Difference +//====================== +#define TZD (+9) // Japan + +//==================== +// RTC Device Address +//==================== +#define RTC_DEV_ADDR 0xa2 +#define RTC_WADDR 0xa2 +#define RTC_RADDR 0xa3 + +//======================= +// RTC Register Address +//======================= +#define RTC_CONTROL1 0x00 +#define RTC_CONTROL2 0x01 +#define RTC_SECONDS 0x02 +#define RTC_MINUTES 0x03 +#define RTC_HOURS 0x04 +#define RTC_DAYS 0x05 +#define RTC_WEEKDAYS 0x06 +#define RTC_C_MONTHS 0x07 +#define RTC_YEARS 0x08 +#define RTC_MINUTE_ALARM 0x09 +#define RTC_HOUR_ALARM 0x0a +#define RTC_DAY_ALARM 0x0b +#define RTC_WEEKDAY_ALARM 0x0c +#define RTC_CLKOUT_FREQ 0x0d +#define RTC_TIMER_CONTROL 0x0e +#define RTC_TIMER 0x0f + +//============ +// Globals +//============ +extern volatile uint32_t I2CCount; +//extern volatile uint8_t I2CMasterBuffer[BUFSIZE]; +//extern volatile uint8_t I2CSlaveBuffer[BUFSIZE]; +extern volatile uint32_t I2CMasterState; +extern volatile uint32_t I2CReadLength, I2CWriteLength; +// +extern volatile uint32_t UARTCount; + +//======================== +// Get Number from GPS +//======================== +uint8_t* Get_Number_from_GPS(uint8_t *pStr, + int32_t *pInteger, int32_t *pIntrnd, int32_t *pDecimal, uint32_t *pDeclen) +{ + uint8_t ch; + int32_t found_decimal; + int32_t pol; + int32_t decimal_1st; + + found_decimal = 0; + *pInteger = 0; + *pDecimal = 0; + *pDeclen = 0; + pol = 1; + while ((ch = *pStr++) != ',') + { + if (ch == '.') + { + found_decimal = 1; + } + else if (ch == '-') + { + pol = -1; + } + else + { + if (found_decimal == 0) + { + *pInteger = (*pInteger) * 10 + (ch - '0'); + } + else + { + *pDecimal = (*pDecimal) * 10 + (ch - '0'); + *pDeclen = *pDeclen + 1; + } + } + } + decimal_1st = (*pDeclen > 0)? *pDecimal / power(10, *pDeclen - 1) : 0; + *pIntrnd = (decimal_1st < 5)? *pInteger : *pInteger + 1; + // + *pInteger = *pInteger * pol; + *pIntrnd = *pIntrnd * pol; + *pDecimal = *pDecimal * pol; + return pStr; +} + +//=========================== +// Get_GPGGA Data from GPS +//=========================== +void Get_GPGGA_Data(sGPSRTC *pG) +{ + uint8_t ch; + uint8_t str[256]; + uint8_t *pStr; + uint32_t quit = 0; + int32_t integer; + int32_t intrnd; + int32_t decimal; + uint32_t declen; + device.baud(9600); + + //------------------------- + // Get String after $GPGGA + //------------------------- + while(quit == 0) + { + //-------------------------- + // Retry from 1st String + //-------------------------- + while(quit == 0) + { + //---------------- + // Check "$GPGGA," + //---------------- + if (device.getc() != '$') break; + if (device.getc() != 'G') break; + if (device.getc() != 'P') break; + if (device.getc() != 'G') break; + if (device.getc() != 'G') break; + if (device.getc() != 'A') break; + if (device.getc() != ',') break; + //----------------- + // Get String + //----------------- + pStr = str; + while ((ch = device.getc()) != '\r') // LF + { + *pStr++ = ch; + } + quit = 1; + } + } + pStr = str; + //------------- + // UTC + //------------- + pStr = Get_Number_from_GPS(pStr, &integer, &intrnd, &decimal, &declen); + pG->bGPS_UTC_hour = (uint8_t) (integer / 10000); + pG->bGPS_UTC_min = (uint8_t) ((integer % 10000) / 100); + pG->bGPS_UTC_sec = (uint8_t) (integer % 100); + //--------------- + // Latitude + //--------------- + pStr = Get_Number_from_GPS(pStr, &integer, &intrnd, &decimal, &declen); + pG->bGPS_LAT_deg = (uint8_t) (integer / 100); + pG->bGPS_LAT_min = (uint8_t) (integer % 100); + pG->bGPS_LAT_sec = (uint8_t) ((60 * decimal) / power(10, declen)); + pG->cGPS_LAT = (*pStr != ',')? *pStr++ : ' '; + ch = *pStr++; // ',' + //--------------- + // Longitude + //--------------- + pStr = Get_Number_from_GPS(pStr, &integer, &intrnd, &decimal, &declen); + pG->bGPS_LNG_deg = (uint8_t) (integer / 100); + pG->bGPS_LNG_min = (uint8_t) (integer % 100); + pG->bGPS_LNG_sec = (uint8_t) ((60 * decimal) / power(10, declen)); + pG->cGPS_LNG = (*pStr != ',')? *pStr++ : ' '; + ch = *pStr++; // ',' + //-------------- + // GPS Quality + //-------------- + pG->cGPS_Quality = *pStr++; + ch = *pStr++; // ',' + //----------------- + // Satellite Count + //----------------- + pStr = Get_Number_from_GPS(pStr, &integer, &intrnd, &decimal, &declen); + pG->bGPS_Sat = (uint8_t) integer; + //----------------- + // HDOP + //----------------- + pStr = Get_Number_from_GPS(pStr, &integer, &intrnd, &decimal, &declen); + pG->bGPS_HDOP_I = (uint8_t) integer; + pG->bGPS_HDOP_D = (uint8_t) ((decimal + power(10, declen) / 2) / power(10, declen)); + //------------------------- + // Altitude above Sea Level + //------------------------- + pStr = Get_Number_from_GPS(pStr, &integer, &intrnd, &decimal, &declen); + pG->wGPS_ASL_m = intrnd; + ch = *pStr++; // 'M' + ch = *pStr++; // ',' + //------------------------- + // Geoid Separation + //------------------------- + pStr = Get_Number_from_GPS(pStr, &integer, &intrnd, &decimal, &declen); + pG->wGPS_GEO_m = intrnd; + ch = *pStr++; // 'M' + ch = *pStr++; // ',' +} + +//================== +// Initialize RTC +//================== +void Init_RTC(uint32_t do_adj, uint8_t year, uint8_t month, uint8_t day, + uint8_t week, uint8_t hour, uint8_t minute, uint8_t second) +{ + + wait(1); // wait 1000ms + // + RTC_Write_Reg(RTC_CONTROL1, 0x20); // STOP + RTC_Write_Reg(RTC_CONTROL2, 0x00); + // + RTC_Write_Reg(RTC_HOURS, BCD_INT(hour)); + RTC_Write_Reg(RTC_MINUTES, BCD_INT(minute)); + RTC_Write_Reg(RTC_SECONDS, BCD_INT(second)); + // + RTC_Write_Reg(RTC_YEARS, BCD_INT(year)); + RTC_Write_Reg(RTC_C_MONTHS, BCD_INT(month)); + RTC_Write_Reg(RTC_DAYS, BCD_INT(day)); + RTC_Write_Reg(RTC_WEEKDAYS, BCD_INT(week)); + // + RTC_Write_Reg(RTC_MINUTE_ALARM, 0x00); + RTC_Write_Reg(RTC_HOUR_ALARM, 0x00); + RTC_Write_Reg(RTC_DAY_ALARM, 0x00); + RTC_Write_Reg(RTC_WEEKDAY_ALARM, 0x00); + // + RTC_Write_Reg(RTC_CLKOUT_FREQ, 0x00); + RTC_Write_Reg(RTC_TIMER_CONTROL,0x00); + RTC_Write_Reg(RTC_TIMER, 0x00); + // + RTC_Write_Reg(RTC_CONTROL1, 0x00); // START +} + +//==================== +// Get RTC Data +//==================== +void Get_RTC_Data(sGPSRTC *psGPSRTC) +{ + psGPSRTC->bRTC_year = INT_BCD(RTC_Read_Reg(RTC_YEARS)); + psGPSRTC->bRTC_mon = INT_BCD(RTC_Read_Reg(RTC_C_MONTHS) & 0x1f); + psGPSRTC->bRTC_day = INT_BCD(RTC_Read_Reg(RTC_DAYS) & 0x3f); + psGPSRTC->bRTC_week = RTC_Read_Reg(RTC_WEEKDAYS) & 0x07; + psGPSRTC->bRTC_hour = INT_BCD(RTC_Read_Reg(RTC_HOURS) & 0x3f); + psGPSRTC->bRTC_min = INT_BCD(RTC_Read_Reg(RTC_MINUTES) & 0x7f); + psGPSRTC->bRTC_sec = INT_BCD(RTC_Read_Reg(RTC_SECONDS) & 0x7f); +} + +//=================== +// Get Week String +//=================== +uint8_t *Get_Week_String(uint32_t week) +{ + static const char *WEEK[] = {"SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"}; + + return (uint8_t*) WEEK[week]; +} + +//===================== +// RTC Write Register +//===================== +void RTC_Write_Reg(uint32_t addr, uint32_t data) +{ + char cmd[2]; + cmd[0]=addr; + cmd[1]=data; + const int addrw=0xA2; + i2c.write(addrw,cmd,2); +} + +//==================== +// RTC Read Register +//==================== +uint32_t RTC_Read_Reg(uint32_t addr) +{ + char read_buf[2]; + const int addrw=0xa2; + const int addrr=0xa3; + char write_cmd[1]; + write_cmd[0]=char(addr); + i2c.write(addrw,write_cmd,1); + wait(0.01); + i2c.read(addrr,read_buf,1); + // + return read_buf[0]; +} + +//===================== +// BCD from Integer +//===================== +uint8_t BCD_INT(uint8_t num) +{ + return ((num / 10) << 4) + (num % 10); +} + +//======================== +// Calculate x^n +//======================== +int32_t power(int32_t x, int32_t n) +{ + uint32_t i; + int32_t y; + + y = 1; + for (i = 0; i < n; i++) + { + y = y * x; + } + return y; +} + +//===================== +// Integer from BCD +//===================== +uint8_t INT_BCD(uint8_t bcd) +{ + return (((bcd >> 4) * 10) + (bcd & 0x0f)); +} + +//========================================================= +// End of Program +//=========================================================