Milos RTOS v0.3.4a
Real Time Operating System
gps.c
Go to the documentation of this file.
00001 /***************************************************************************
00002  * gps.c
00003  * (C) 2011 Ivan Meleca
00004  * www.milos.it
00005 
00006 #   This program is free software; you can redistribute it and/or modify
00007 #   it under the terms of the GNU General Public License as published by
00008 #   the Free Software Foundation; either version 2 of the License, or
00009 #   (at your option) any later version.
00010 #
00011 #   This program is distributed in the hope that it will be useful,
00012 #   but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 #   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 #   GNU General Public License for more details.
00015 #
00016 #   You should have received a copy of the GNU General Public License
00017 #   along with this program; if not, write to the Free Software
00018 #   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00019 
00020 ***************************************************************************/
00021 
00022 #include "gps.h"
00023 #include <core/thread.h>
00024 #include <core/system.h>
00025 #include <core/heap.h>
00026 #include <common/nmea.h>
00027 #include <common/mem.h>
00028 #include <core/dbgterm.h>
00029 
00030 #if __CONFIG_COMPILE_GPS
00031 
00051 __STATIC __VOID __gpsThread(__VOID)
00052 {
00053     __PDEVICE dv = __threadGetParameter();
00054     __PGPS_PDB pd = dv->dv_pdb;
00055     __BOOL res;
00056 
00057     for (;;)
00058     {
00059         /* Read a line of text (if the device is opened) */
00060         while (pd->pd_dv->dv_opcnt && __deviceReadLine(pd->pd_dv, pd->pd_buf, __GPS_MAX_LINE_LEN) != __DEV_ERROR)
00061         {
00062             /* Lock, we are about to write in the shared pd_data structure */
00063             if (__lockOwn(pd->pd_lock, 1000))
00064             {
00065                 /* Parse the read line with the NMEA parser */
00066                 res = __nmeaParseLine(pd->pd_buf, &pd->pd_data);
00067 
00068                 /* Release the lock */
00069                 __lockRelease(pd->pd_lock);
00070 
00071                 /* If the sentence is OK, output to terminal */
00072                 if (res) {
00073                     DBGMSG(pd->pd_terminal, (pd->pd_buf));
00074                 } else {
00075                     DBGMSG(pd->pd_terminal, ("GPS checksum error"));
00076                 }
00077 
00078             }
00079         }
00080 
00081         /* Give up the remaining time-to-live */
00082         __threadSleep(10);
00083     }
00084 }
00085 
00107 i32 __gpsInit(__PDEVICE dv, __PVOID params)
00108 {
00109     __PGPS_PDB pd = dv->dv_pdb;
00110 
00111     pd->pd_dv = (__PDEVICE) params;
00112 
00113     if (pd->pd_dv == __NULL)
00114     {
00115         /* Give a chance the platform to initialize a default
00116          * device for us.
00117          */
00118 
00119         if (((dv->dv_plat_ioctl) (dv, __GPS_PLAT_INIT_DEFAULTS, 0, __NULL, 0, __NULL, 0)) != __DEV_OK)
00120             return __DEV_ERROR;
00121 
00122         if (pd->pd_dv == __NULL)
00123             return __DEV_ERROR;
00124     }
00125 
00126     /* Allocate buffer for reception */
00127     pd->pd_buf = __heapAllocZero(__GPS_MAX_LINE_LEN);
00128     if (!pd->pd_buf) return __DEV_ERROR;
00129 
00130     /* Create a lock to protect pd->pd_data */
00131     pd->pd_lock = __lockCreate();
00132     if (!pd->pd_lock)
00133     {
00134         __heapFree(pd->pd_buf);
00135         return __DEV_ERROR;
00136     }
00137 
00138     /*  Init hardware */
00139     (dv->dv_plat_ioctl)(dv, __GPS_PLAT_INIT_HW, 0, __NULL, 0, __NULL, 0);
00140 
00141     return __DEV_OK;
00142 }
00143 
00153 i32 __gpsDeinit(__PDEVICE dv)
00154 {
00155     __PGPS_PDB pd = dv->dv_pdb;
00156 
00157     /* Check for still opened */
00158     if (dv->dv_opcnt != 0) return __DEV_ERROR;
00159 
00160     /* Destroy lock */
00161     __lockDestroy(pd->pd_lock);
00162 
00163     /* Free buffers */
00164     __heapFree(pd->pd_buf);
00165 
00166     /*  De-init hardware */
00167     if (dv->dv_plat_ioctl)
00168         (dv->dv_plat_ioctl)(dv, __GPS_PLAT_DEINIT_HW,   0, __NULL, 0, __NULL, 0);
00169 
00170     return __DEV_OK;
00171 }
00172 
00201 i32 __gpsIOCtl(__PDEVICE dv, u32 cmd, u32 param, __PVOID data, u32 len)
00202 {
00203     __PGPS_PDB pd = dv->dv_pdb;
00204 
00205     switch (cmd)
00206     {
00207         case __IOCTL_GET_POWER_STATUS:
00208             if (dv->dv_plat_ioctl)
00209                 return (dv->dv_plat_ioctl)(dv, __GPS_PLAT_GET_POWER, 0, __NULL, 0, __NULL, 0);
00210             break;
00211 
00212         case __IOCTL_SET_POWER_STATUS:
00213             if (dv->dv_plat_ioctl)
00214                 return (dv->dv_plat_ioctl)(dv, __GPS_PLAT_SET_POWER, (u8) param, __NULL, 0, __NULL, 0);
00215             break;
00216 
00217         case __IOCTL_GET_FIX_FLAG:
00218             if (dv->dv_plat_ioctl)
00219                 return (dv->dv_plat_ioctl)(dv, __GPS_PLAT_GET_FIX_FLAG, 0, __NULL, 0, __NULL, 0);
00220             break;
00221 
00222         case __IOCTL_TERMINAL_OUTPUT:
00223             pd->pd_terminal = (u8) param;
00224             break;
00225     }
00226 
00227     return __DEV_UNK_IOCTL;
00228 }
00229 
00239 i32 __gpsOpen(__PDEVICE dv, u32 mode)
00240 {
00241 
00242     __PGPS_PDB pd = dv->dv_pdb;
00243 
00244     if (pd->pd_thread == __NULL)
00245     {
00246         /* Create a thread for GPS reception */
00247         pd->pd_thread = __threadCreate("gps", __gpsThread, 150, __GPS_THREAD_STACK, 10, dv);
00248         if (pd->pd_thread == __NULL) {
00249             return __DEV_ERROR;
00250         }
00251     }
00252 
00253     (dv->dv_plat_ioctl)(dv, __GPS_PLAT_SET_POWER, 1, __NULL, 0, __NULL, 0);
00254 
00255     return __DEV_OK;
00256 }
00257 
00267 i32 __gpsClose(__PDEVICE dv)
00268 {
00269     (dv->dv_plat_ioctl)(dv, __GPS_PLAT_SET_POWER, 0, __NULL, 0, __NULL, 0);
00270     return __DEV_OK;
00271 }
00272 
00283 i32 __gpsSize(__PDEVICE dv, u8 mode)
00284 {
00285     return __DEV_OK;
00286 }
00287 
00297 i32 __gpsFlush(__PDEVICE dv)
00298 {
00299     __PGPS_PDB pd = dv->dv_pdb;
00300 
00301     return __deviceFlush(pd->pd_dv);
00302 }
00303 
00317 i32 __gpsRead(__PDEVICE dv, __PVOID buf, u16 qty)
00318 {
00319     __PGPS_PDB pd = dv->dv_pdb;
00320 
00321     if (qty != sizeof(__GPS_DATA) || !buf) return __DEV_ERROR;
00322 
00323     if (__lockOwn(pd->pd_lock, 1500))
00324     {
00325         __memCpy(buf, &pd->pd_data, sizeof(__GPS_DATA));
00326         __lockRelease(pd->pd_lock);
00327 
00328         return __DEV_OK;
00329     }
00330 
00331     return __DEV_ERROR;
00332 }
00333 
00344 i32 __gpsWrite(__PDEVICE dv, __CONST __PVOID buf, u16 qty)
00345 {
00346     __PGPS_PDB pd = dv->dv_pdb;
00347 
00348     return __deviceWrite(pd->pd_dv, buf, qty);
00349 }
00350 
00363 #endif /* __CONFIG_COMPILE_GPS */
00364 
00365 
 All Data Structures Files Functions Variables Typedefs Defines