# 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 case
    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
    00287 extern u32 micros();
    00288
    00293 extern u32 millis();
    00294
    00300 extern u64 microseconds();
    00301
    00307 extern u32 milliseconds();
    00308
    00313 extern u32 seconds();
    00314
    00315 #ifdef __cplusplus
    00316 }
    00317 #endif
    00318
    00319 #endif  /* SFBHWPINSHOST_H */