Milos RTOS v0.3.4a
Real Time Operating System
device.c
Go to the documentation of this file.
00001 /***************************************************************************
00002  * device.c
00003  * (C) 2010 Ivan Meleca
00004  * Based on original code written by Ruben Meleca
00005  * www.milos.it
00006 
00007 #   This program is free software; you can redistribute it and/or modify
00008 #   it under the terms of the GNU General Public License as published by
00009 #   the Free Software Foundation; either version 2 of the License, or
00010 #   (at your option) any later version.
00011 #
00012 #   This program is distributed in the hope that it will be useful,
00013 #   but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 #   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 #   GNU General Public License for more details.
00016 #
00017 #   You should have received a copy of the GNU General Public License
00018 #   along with this program; if not, write to the Free Software
00019 #   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00020 
00021 ***************************************************************************/
00022 
00023 #include "device.h"
00024 #include <core/system.h>
00025 #include <core/dbgterm.h>
00026 #include <common/string.h>
00027 
00060 #define __DEV_INITIALIZED   0x80    
00061 #define __DEV_OPENED        0x40    
00062 #define __DEV_EOL           0x00    
00063 #define __DEV_CR            0x0D    
00064 #define __DEV_LF            0x0A    
00065 #define __DEV_RD_CRLFMASK   0x03    
00066 #define __DEV_WR_CRLFMASK   0x0C    
00080 __STATIC __PDEVICE __deviceChain = __NULL;  
00101 __PDEVICE __deviceFind(__CONST __PSTRING name)
00102 {
00103     __PDEVICE   dv = __deviceChain;
00104 
00105     while(dv)
00106     {
00107         if (__strCmp(dv->dv_name,name) == 0) return(dv);
00108         dv = dv->dv_next;
00109     }
00110     return(__NULL);
00111 }
00112 
00113 
00157 i32 __deviceInit(__PDEVICE dv, __PVOID params, u32 flags)
00158 {
00159 
00160     if (!dv) return __DEV_ERROR;
00161 
00162     /* Check if already initialized */
00163     if (!dv->dv_initd)
00164     {
00165         /* Check if device has an init function */
00166         if (dv->dv_init != __NULL)
00167         {
00168             if ((*dv->dv_init)(dv, params) != __DEV_OK) return __DEV_ERROR;
00169             dv->dv_initd = 1;
00170         }
00171     }
00172 
00173     dv->dv_flags = flags;
00174     return __DEV_OK;
00175 }
00176 
00188 i32 __deviceDeinit(__PDEVICE dv)
00189 {
00190     i32 ret;
00191 
00192     /* Check initialized */
00193     if (dv->dv_initd == 0) return __DEV_ERROR;
00194 
00195     /* Check if device has a destroy function */
00196     if (dv->dv_deinit == __NULL) {
00197         dv->dv_initd = 0;
00198         return __DEV_OK;
00199     }
00200 
00201     ret = (*dv->dv_deinit)(dv);
00202 
00203     if (ret == __DEV_OK) dv->dv_initd = 0;
00204 
00205     return ret;
00206 }
00207 
00220 i32 __deviceOpen(__PDEVICE dv, u32 param)
00221 {
00222     i32 ret;
00223 
00224     /* Must be called from inside a thread */
00225     if (__threadGetCurrent()) {
00226         /* Check initialized */
00227         if (dv->dv_initd == 0) return __DEV_ERROR;
00228 
00229         /* Check if already opened */
00230         if (dv->dv_opcnt == 0)
00231         {
00232             /* Check for an open function */
00233             if (dv->dv_open != __NULL)
00234             {
00235                 ret = (*dv->dv_open)(dv, param);
00236 
00237                 if (ret == __DEV_OK)
00238                 {
00239                     dv->dv_owner = __threadGetCurrent();
00240                     ++dv->dv_opcnt;
00241                 }
00242 
00243                 return ret;
00244             }
00245         } else {
00246             ++dv->dv_opcnt;
00247             return __DEV_OK;
00248         }
00249     }
00250 
00251     return __DEV_ERROR;
00252 }
00253 
00265 i32 __deviceClose(__PDEVICE dv)
00266 {
00267 
00268     i32 ret;
00269 
00270     /* Must be called from within a thread */
00271     if (__threadGetCurrent())
00272     {
00273         if (dv->dv_opcnt == 1)
00274         {
00275             /* Check for a close function */
00276             if (dv->dv_close != __NULL)
00277             {
00278                 ret = (*dv->dv_close)(dv);
00279 
00280                 if (ret == __DEV_OK)
00281                 {
00282                     dv->dv_owner = __NULL;
00283                     dv->dv_opcnt = 0;
00284                 }
00285 
00286                 return ret;
00287             }
00288         } else
00289         {
00290             --dv->dv_opcnt;
00291             return __DEV_OK;
00292         }
00293     }
00294 
00295     return __DEV_ERROR;
00296 }
00297 
00314 i32 __deviceIOCtl(__PDEVICE dv, u32 cmd, u32 param, __PVOID data, u32 len)
00315 {
00316     /* Check for initialized */
00317     if (!dv->dv_initd) return __DEV_ERROR;
00318 
00319     if (dv->dv_ioctl) return((*dv->dv_ioctl)(dv,cmd,param,data,len));
00320 
00321     return __DEV_ERROR;
00322 }
00323 
00338 i32 __deviceRead(__PDEVICE dv, __PVOID buf, u16 qty)
00339 {
00340     /* Check for initialized or opened */
00341     if (!dv->dv_initd || !dv->dv_opcnt) return __DEV_ERROR;
00342 
00343     if (dv->dv_owner != __NULL)
00344     {
00345         /* Check for a read function */
00346         if (dv->dv_read != __NULL)
00347         {
00348             return((*dv->dv_read)(dv,buf,qty));
00349         }
00350     }
00351 
00352     return __DEV_ERROR;
00353 }
00354 
00369 i32 __deviceWrite(__PDEVICE dv, __CONST __PVOID buf, u16 qty)
00370 {
00371     i32 res;
00372 
00373     /* Check for initialized or opened */
00374     if (!dv->dv_initd || !dv->dv_opcnt) return __DEV_ERROR;
00375 
00376     if (dv->dv_owner != __NULL)
00377     {
00378         if (dv->dv_write != __NULL)
00379         {
00380             res = ((*dv->dv_write)(dv,buf,qty));
00381 
00382             if (res > __DEV_OK) {
00383                 if (dv->dv_flags & __DEV_AUTOFLUSH)
00384                 {
00385                     if (__deviceFlush(dv) == __DEV_OK)
00386                         return res;
00387                 }
00388             }
00389 
00390             return res;
00391         }
00392     }
00393     return __DEV_ERROR;
00394 }
00395 
00404 i32 __deviceFlush(__PDEVICE dv)
00405 {
00406 
00407     /* Check for initialized or opened */
00408     if (!dv->dv_initd || !dv->dv_opcnt) return __DEV_ERROR;
00409 
00410     if (dv->dv_owner != __NULL)
00411     {
00412         if (dv->dv_flush != __NULL)
00413         {
00414             return((*dv->dv_flush)(dv));
00415         }
00416     }
00417 
00418     return __DEV_ERROR;
00419 }
00420 
00433 i32 __deviceSize(__PDEVICE dv, u8 mode)
00434 {
00435     /* Check for initialized or opened */
00436     if (!dv->dv_initd || !dv->dv_opcnt) return __DEV_ERROR;
00437 
00438     if (dv->dv_owner != __NULL) {
00439         if (dv->dv_size != __NULL) {
00440             return((*dv->dv_size)(dv,mode));
00441         }
00442     }
00443 
00444     return __DEV_ERROR;
00445 }
00446 
00459 i32 __deviceReadLine(__PDEVICE dv, __PSTRING buf, u16 qty)
00460 {
00461     u16     i;
00462     u8      c, cr = 0;
00463 
00464     /* Check for initialized or opened */
00465     if (!dv->dv_initd || !dv->dv_opcnt) return __DEV_ERROR;
00466 
00467     if (dv == __NULL || dv->dv_read == __NULL || dv->dv_owner == __NULL) return __DEV_ERROR;
00468 
00469     for (i = 0; i < (qty - 1); i++)
00470     {
00471         if ((*dv->dv_read)(dv,&c,1) != 1)
00472         {
00473             *buf = __DEV_EOL;
00474             return __DEV_ERROR;
00475         }
00476 
00477         if (c == __DEV_CR || c == __DEV_LF)
00478         {
00479             --i;
00480             if (dv->dv_flags & __DEV_RD_CR)
00481             {
00482                 if (!(dv->dv_flags &    __DEV_RD_LF))
00483                 {
00484                     *buf = __DEV_EOL;
00485                     return i;
00486                 }
00487                 cr = c;
00488             }
00489 
00490             if (dv->dv_flags & __DEV_RD_LF)
00491             {
00492                 if (!(dv->dv_flags &    __DEV_RD_CR))
00493                 {
00494                     *buf = __DEV_EOL;
00495                     return i;
00496                 }
00497 
00498                 if (cr == __DEV_CR)
00499                 {
00500                     *buf = __DEV_EOL;
00501                     return i;
00502                 }
00503                 cr = 0;
00504             }
00505         } else
00506         {
00507             *buf++ = c;
00508             cr = 0;
00509         }
00510     }
00511 
00512     return i;
00513 }
00514 
00526 i32 __deviceWriteLine(__PDEVICE dv, __CONST __PSTRING buf)
00527 {
00528     i16         qty = 0;
00529     u8          c;
00530 
00531     /* Check for initialized or opened */
00532     if (!dv->dv_initd || !dv->dv_opcnt) return __DEV_ERROR;
00533 
00534     if (dv == __NULL || dv->dv_write == __NULL || dv->dv_owner == __NULL) return __DEV_ERROR;
00535 
00536     if (buf == __NULL) return __DEV_ERROR;
00537 
00538     if ((*dv->dv_write)(dv, buf, __strLen(buf)) != __strLen(buf)) {
00539         return __DEV_ERROR;
00540     }
00541     
00542     qty = __strLen(buf);
00543     
00544     if (dv->dv_flags & __DEV_WR_CR) {
00545         c = __DEV_CR;
00546         if ((*dv->dv_write)(dv,&c,1) != 1)
00547         {
00548             return __DEV_ERROR;
00549         }
00550         ++qty;
00551     }
00552 
00553     if (dv->dv_flags & __DEV_WR_LF)
00554     {
00555         c = __DEV_LF;
00556         if ((*dv->dv_write)(dv,&c,1) != 1)
00557         {
00558             return __DEV_ERROR;
00559         }
00560         ++qty;
00561     }
00562 
00563     if (dv->dv_flags & __DEV_AUTOFLUSH)
00564     {
00565         if (dv->dv_flush) (*dv->dv_flush)(dv);
00566     }
00567 
00568     return qty;
00569 }
00570 
00582 __VOID __deviceAdd(__PDEVICE dv, u8 count)
00583 {
00584     u8 i;
00585 
00586     for (i = 0; i < count; i++)
00587     {
00588         dv->dv_next = __deviceChain;
00589         __deviceChain = dv;
00590         dv++;
00591     }
00592 }
00593 
00603 __VOID __deviceRemove(__PDEVICE dv)
00604 {
00605     __PDEVICE list;
00606 
00607     __systemDisableScheduler();
00608 
00609     list = __deviceChain;
00610 
00611     if (list == dv)
00612     {
00613         __deviceChain = dv->dv_next;
00614     } else {
00615         while (list)
00616         {
00617 
00618             if (list->dv_next == dv)
00619             {
00620                 list->dv_next = dv->dv_next;
00621                 break;
00622             }
00623 
00624             list = list->dv_next;
00625         }
00626     }
00627 
00628     __systemEnableScheduler();
00629 }
00630 
00634 __PDEVICE __deviceGetList(__VOID)
00635 {
00636     return __deviceChain;
00637 }
00638 
 All Data Structures Files Functions Variables Typedefs Defines