SFBHWPinsHost.h

Go to the documentation of this file.
00001 /*                                       -*- mode:C++; fill-column: 100 -*-
00002   SFBHWPinsHost.h Host-specific shims around pin definitions
00003   Copyright (C) 2008 The Regents of the University of New Mexico.  All rights reserved.
00004 
00005   This library is free software; you can redistribute it and/or
00006   modify it under the terms of the GNU Lesser General Public
00007   License as published by the Free Software Foundation; either
00008   version 2.1 of the License, or (at your option) any later version.
00009 
00010   This library is distributed in the hope that it will be useful,
00011   but WITHOUT ANY WARRANTY; without even the implied warranty of
00012   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013   Lesser General Public License for more details.
00014 
00015   You should have received a copy of the GNU General Public License
00016   along with this library; if not, write to the Free Software
00017   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
00018   USA
00019 
00020   $Id$
00021 */
00029 #ifdef SFBHWPINSBOARD_H
00030 #error SFBHWPinsHost.h and SFBHWPinsBoard.h must not be #included together!
00031 #endif
00032 
00033 #ifndef SFBHWPINSHOST_H
00034 #define SFBHWPINSHOST_H
00035 
00036 #include "SFBTypes.h"
00037 #include "SFBAssert.h"
00038 
00039 #ifdef __cplusplus
00040 extern "C" {
00041 #endif
00042 
00047 struct SFBHWHostRegister {
00048   SFBHWHostRegister(u32 address, u32 initVal = 0, u32 (*toRead)(u32,u32) = 0, u32 (*toWrite)(u32,u32) = 0) :
00049     reg(initVal),
00050     addr(address),
00051     doRead(toRead),
00052     doWrite(toWrite)
00053   { }
00054 
00055   operator u32() const { 
00056     return doRead?doRead(addr,reg):reg; 
00057   }
00058   SFBHWHostRegister & operator=(const u32 val) {
00059     if (doWrite) reg = doWrite(addr,val);
00060     else reg = val;
00061     return *this;
00062   }
00063   SFBHWHostRegister & operator&=(const u32 val) {
00064     if (doWrite) reg = doWrite(addr,reg&val);
00065     else reg &= val;
00066     return *this;
00067   }
00068   SFBHWHostRegister & operator|=(const u32 val) {
00069     if (doWrite) reg = doWrite(addr,reg|val);
00070     else  reg |= val;
00071     return *this;
00072   }
00073 
00074   u32 reg;
00075   u32 addr;
00076   u32 (*doRead)(u32 addr, u32 oldval);
00077   u32 (*doWrite)(u32 addr, u32 newval);
00078 };
00079 
00084 class SFBHWHostRegister ; // Forward
00085 class SFBHWHostRegisterAccess ; // Forward
00086 class SFBHWHostRegisterMap {
00087   void * vmap;
00088 public:
00089   SFBHWHostRegisterMap() ;
00090   ~SFBHWHostRegisterMap() ;
00091   void addRegister(u32 address, u32 initVal = 0, u32 (*toRead)(u32,u32) = 0, u32 (*toWrite)(u32,u32) = 0) ;
00092   SFBHWHostRegisterAccess registerAt(u32 address) const ;
00093   SFBHWHostRegisterAccess registerAtU16(u32 address) const ;
00094   SFBHWHostRegisterAccess registerAtU8(u32 address) const ;
00095 
00096   SFBHWHostRegister & getRegister(u32 address) ;
00097   void setMap(void * vmap) ;
00098   enum { PINMODE_REGISTER_PORT = 0 };
00099 };
00100 extern SFBHWHostRegisterMap hostRegisters;
00101 
00102 
00103 class SFBHWHostRegisterAccess {
00104   const u32 addr;
00105   const u8 size;
00106   const u8 phase;
00107 public:
00108   SFBHWHostRegisterAccess(u32 a, u8 s = 4) : addr(a&~3), size(s), phase(a&3) { 
00109     if (s==4) API_ASSERT_TRUE(phase==0);
00110     else if (s==2) API_ASSERT_TRUE(phase==0 || phase==2);
00111     else API_ASSERT_TRUE(s==1);
00112   }
00113 
00114   operator u32() const { 
00115     SFBHWHostRegister & reg = hostRegisters.getRegister(addr);
00116     u32 r = reg;
00117     switch (size) {
00118     case 4: 
00119       return r;
00120     case 2: 
00121       switch (phase) {
00122       case 0: return (r>>0)&0xffff;
00123       case 2: return (r>>16)&0xffff;
00124       }
00125       break;
00126     case 1: 
00127       switch (phase) {
00128       case 0: return (r>>0)&0xff;
00129       case 1: return (r>>8)&0xff;
00130       case 2: return (r>>16)&0xff;
00131       case 3: return (r>>24)&0xff;
00132       }
00133       break;
00134     }
00135    API_BUG(E_BUG_INCONSISTENT_STATE); 
00136   }
00137   //  operator u16() const { return (u16) (u32) *this; }
00138   //  operator u8() const { return (u8) (u32) *this; }
00139 
00140   SFBHWHostRegisterAccess & operator=(const u32 val) {
00141     *((const SFBHWHostRegisterAccess*) this) = val;
00142     return *this;
00143   }
00144 
00145   const SFBHWHostRegisterAccess & operator=(const u32 val) const {
00146     SFBHWHostRegister & reg = hostRegisters.getRegister(addr);
00147     u32 r;
00148     switch (size) {
00149     case 4: 
00150       r = val;
00151       break;
00152     case 2: 
00153       r = (u32) reg;
00154       switch (phase) {
00155       case 0: r = (r&0xffff0000)|(((u32)val)<<0);
00156       case 2: r = (r&0x0000ffff)|(((u32)val)<<16);
00157       default: API_BUG(E_BUG_INCONSISTENT_STATE); 
00158       }
00159       break;
00160     case 1: 
00161       r = (u32) reg;
00162       switch (phase) {
00163       case 0: r = (r&0xffffff00)|(((u32)val)<<0);
00164       case 1: r = (r&0xffff00ff)|(((u32)val)<<8);
00165       case 2: r = (r&0xff00ffff)|(((u32)val)<<16);
00166       case 3: r = (r&0x00ffffff)|(((u32)val)<<24);
00167       default: API_BUG(E_BUG_INCONSISTENT_STATE); 
00168       }
00169       break;
00170     default: API_BUG(E_BUG_INCONSISTENT_STATE); 
00171     }
00172     reg = r;
00173     return *this;
00174   }
00175 
00176   const SFBHWHostRegisterAccess & operator&=(const u32 val) const {
00177     SFBHWHostRegister & reg = hostRegisters.getRegister(addr);
00178     u32 r = (u32) reg;
00179     switch (size) {
00180     case 4: 
00181       r &= val;
00182       break;
00183     case 2: 
00184       switch (phase) {
00185       case 0: r = r&(0xffff0000|((val&0xffff)<<0));
00186       case 2: r = r&(0x0000ffff|((val&0xffff)<<16));
00187       default: API_BUG(E_BUG_INCONSISTENT_STATE); 
00188       }
00189       break;
00190     case 1: 
00191       switch (phase) {
00192       case 0: r = r&(0xffffff00|((val&0xff)<<0));
00193       case 1: r = r&(0xffff00ff|((val&0xff)<<8));
00194       case 2: r = r&(0xff00ffff|((val&0xff)<<16));
00195       case 3: r = r&(0x00ffffff|((val&0xff)<<24));
00196       default: API_BUG(E_BUG_INCONSISTENT_STATE); 
00197       }
00198       break;
00199     default: API_BUG(E_BUG_INCONSISTENT_STATE); 
00200     }
00201     reg = r;
00202     return *this;
00203   }
00204 
00205   const SFBHWHostRegisterAccess & operator|=(const u32 val) const {
00206     SFBHWHostRegister & reg = hostRegisters.getRegister(addr);
00207     u32 r = (u32) reg;
00208     switch (size) {
00209     case 4: 
00210       r |= val;
00211       break;
00212     case 2: 
00213       switch (phase) {
00214       case 0: r = r|((val&0xffff)<<0);
00215       case 2: r = r|((val&0xffff)<<16);
00216       default: API_BUG(E_BUG_INCONSISTENT_STATE); 
00217       }
00218       break;
00219     case 1: 
00220       switch (phase) {
00221       case 0: r = r|((val&0xff)<<0);
00222       case 1: r = r|((val&0xff)<<8);
00223       case 2: r = r|((val&0xff)<<16);
00224       case 3: r = r|((val&0xff)<<24);
00225       default: API_BUG(E_BUG_INCONSISTENT_STATE); 
00226       }
00227       break;
00228     default: API_BUG(E_BUG_INCONSISTENT_STATE); 
00229     }
00230     reg = r;
00231     return *this;
00232   }
00233 };
00234 
00237 #define SFB_PORT_IN_MAP(offset, port) hostRegisters.registerAt(((FIO_BASE_ADDR)+(offset))+(port)*0x20)
00238 
00239 #define SFB_PORT_PINMODE_REGISTER(offset) hostRegisters.registerAt((PINMODE_BASE_ADDR)+(offset))
00240 
00241 #define SFB_PINSEL_REGISTER(port,pinNumber) hostRegisters.registerAt((PINSEL_BASE_ADDR)+((port)*8)+(pinNumber>15?4:0))
00242 
00243 #define REFLEX_RGB_RED_ON BUG_UNIMPLEMENTED()
00244 #define REFLEX_RGB_RED_OFF BUG_UNIMPLEMENTED()
00245 #define REFLEX_RGB_GREEN_ON BUG_UNIMPLEMENTED()
00246 #define REFLEX_RGB_GREEN_OFF BUG_UNIMPLEMENTED()
00247 #define REFLEX_RGB_BLUE_ON BUG_UNIMPLEMENTED()
00248 #define REFLEX_RGB_BLUE_OFF BUG_UNIMPLEMENTED()
00249 
00250 #define SFB_PORT_DIR_REGISTER(port)  SFB_PORT_IN_MAP(0x00,port)
00251 #define SFB_PORT_MASK_REGISTER(port) SFB_PORT_IN_MAP(0x10,port)
00252 #define SFB_PORT_PIN_REGISTER(port)  SFB_PORT_IN_MAP(0x14,port)
00253 #define SFB_PORT_SET_REGISTER(port)  SFB_PORT_IN_MAP(0x18,port)
00254 #define SFB_PORT_CLR_REGISTER(port)  SFB_PORT_IN_MAP(0x1C,port)
00255 
00256 #define SFB_PORT_GET_BIT_MASK(port,mask) (SFB_PORT_PIN_REGISTER(port)&(mask))
00257 
00258 #define SFB_PORT_SET_BIT_MASK(port,mask) (SFB_PORT_SET_REGISTER(port) = (mask))
00259 #define SFB_PORT_CLR_BIT_MASK(port,mask) (SFB_PORT_CLR_REGISTER(port) = (mask))
00260 #define SFB_PORT_WRITE_BIT_MASK(port,mask,value) \
00261   ((value==LOW)?SFB_PORT_CLR_BIT_MASK(port,mask):SFB_PORT_SET_BIT_MASK(port,mask))
00262 
00263 extern void setPinSelFunction(u32 port,u32 pinNumber,u32 function);
00264 
00265 extern void reenterBootloader() __attribute__ ((noreturn));
00266 
00267 extern void reenterBrainstem() __attribute__ ((noreturn));
00268 
00269 extern void hwpins_startup_initialization();
00270 
00271 /* Low-level last ditch routine to set the rbg leds, bypassing (and
00272    thereby breaking) all the normal pin management stuff.  So don't
00273    use this unless the situation is dire enough that you don't care
00274    about that. */
00275 extern void debugRGB(int rgbBits, int wait);
00276 
00277 extern void debugRGBNum(int num, int bits, int loops);
00278 
00279 extern void _dieOnBoard_(u32 blinkCode, const char * file, int lineno) __attribute__ ((noreturn));
00280 
00281 extern u32 millisFunction();
00282 
00283 extern u32 microsFunction();
00284 
00294 #define micros() microsFunction()
00295 
00306 #define millis() millisFunction()
00307 
00313 extern u64 microseconds();
00314 
00320 extern u32 milliseconds();
00321 
00326 extern u32 seconds();
00327 
00328 #ifdef __cplusplus
00329 }
00330 #endif
00331 
00332 #endif  /* SFBHWPINSHOST_H */

Generated on Fri Apr 22 06:54:11 2011 for SFB by doxygen 1.5.9