test

Dependencies:   FatFileSystem TextLCD mbed

gpsrtc.cpp

Committer:
y_notsu
Date:
2012-09-18
Revision:
0:2c37ad282618

File content as of revision 0:2c37ad282618:

//=========================================================
// 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 unsigned int I2CCount;
//extern volatile uint8_t  I2CMasterBuffer[BUFSIZE];
//extern volatile uint8_t  I2CSlaveBuffer[BUFSIZE];
extern volatile unsigned int I2CMasterState;
extern volatile unsigned int I2CReadLength, I2CWriteLength;
//
extern volatile unsigned int UARTCount;

//========================
// Get Number from GPS
//========================
unsigned char* Get_Number_from_GPS(unsigned char *pStr,
        signed int *pInteger, signed int *pIntrnd, signed int *pDecimal, unsigned int *pDeclen)
{
    unsigned char  ch;
    signed int  found_decimal;
    signed int  pol;
    signed int  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)
{
    unsigned char  ch;
    unsigned char  str[256];
    unsigned char  *pStr;
    unsigned int quit = 0;
    signed int  integer;
    signed int  intrnd;
    signed int  decimal;
    unsigned int declen;
    //device.baud(4800); //for SparkFun GPS-08936
    device.baud(9600); //for MARY-GB
    //unsigned int ti=0;

    //-------------------------
    // 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;
                //ti++;
                //if(ti==10000) goto L1;
            }
            quit = 1;
        }
    }
L1:
    pStr = str;
    //-------------
    // UTC
    //-------------
    pStr = Get_Number_from_GPS(pStr, &integer, &intrnd, &decimal, &declen);
    pG->bGPS_UTC_hour = (unsigned char) (integer / 10000);
    pG->bGPS_UTC_min  = (unsigned char) ((integer % 10000) / 100);
    pG->bGPS_UTC_sec  = (unsigned char) (integer % 100);
    //---------------
    // Latitude
    //---------------
    pStr = Get_Number_from_GPS(pStr, &integer, &intrnd, &decimal, &declen);
    pG->bGPS_LAT_deg = (unsigned char) (integer / 100);
    pG->bGPS_LAT_min = (unsigned char) (integer % 100);
    pG->bGPS_LAT_sec = (unsigned char) ((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 = (unsigned char) (integer / 100);
    pG->bGPS_LNG_min = (unsigned char) (integer % 100);
    pG->bGPS_LNG_sec = (unsigned char) ((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 = (unsigned char) integer;
    //-----------------
    // HDOP
    //-----------------
    pStr = Get_Number_from_GPS(pStr, &integer, &intrnd, &decimal, &declen);
    pG->bGPS_HDOP_I = (unsigned char) integer;
    pG->bGPS_HDOP_D = (unsigned char) ((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(unsigned int do_adj, unsigned char year, unsigned char month,  unsigned char day,
              unsigned char week,    unsigned char hour, unsigned char minute, unsigned char 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
//===================
unsigned char *Get_Week_String(unsigned int week)
{
    static const char *WEEK[] = {"SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"};

    return (unsigned char*) WEEK[week];
}

//=====================
// RTC Write Register
//=====================
void RTC_Write_Reg(unsigned int addr, unsigned int data)
{
   char cmd[2];
   cmd[0]=addr;
   cmd[1]=data;
   const int addrw=0xA2;
   i2c.write(addrw,cmd,2);
}

//====================
// RTC Read Register
//====================
unsigned int RTC_Read_Reg(unsigned int 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
//=====================
unsigned char BCD_INT(unsigned char num)
{
    return ((num / 10) << 4) + (num % 10);
}

//========================
// Calculate x^n
//========================
signed int power(signed int x, signed int n)
{
    unsigned int i;
    signed int  y;

    y = 1;
    for (i = 0; i < n; i++)
    {
        y = y * x;
    }
    return y;
}

//=====================
// Integer from BCD
//=====================
unsigned char INT_BCD(unsigned char bcd)
{
    return (((bcd >> 4) * 10) + (bcd & 0x0f));
}

//=========================================================
// End of Program
//=========================================================