00001
00002 #include "base/Gpio.h"
00003
00010
00012
00017 base::Gpio::Gpio(base::Board* board) :
00018 base::Peripheral(board)
00019 {
00020 }
00021
00022
00023
00024 base::Gpio::~Gpio()
00025 {
00026 }
00027
00028
00030
00048 int base::Gpio::setSyncBaud(int gpio_nr, uint32_t offset,
00049 uint32_t odd, uint32_t even)
00050 {
00051 uint32_t addr_offset[3] = {base::GPIO_SYNCM_BAUD_START,
00052 base::GPIO_SYNCS0_BAUD_START,
00053 base::GPIO_SYNCS1_BAUD_START};
00054 uint32_t addr_odd[3] = {base::GPIO_SYNCM_BAUD1,
00055 base::GPIO_SYNCS0_BAUD1,
00056 base::GPIO_SYNCS1_BAUD1};
00057 uint32_t addr_even[3] = {base::GPIO_SYNCM_BAUD2,
00058 base::GPIO_SYNCS0_BAUD2,
00059 base::GPIO_SYNCS1_BAUD2};
00060
00061 if (gpio_nr < 1 || gpio_nr > 3) return -1;
00062
00063 int rc = board().operPPP(addr_offset[gpio_nr-1], offset-1,
00064 addr_odd[gpio_nr-1], odd-1,
00065 addr_even[gpio_nr-1], even-1);
00066 return rc;
00067 }
00068
00069
00071
00084 int base::Gpio::setSyncBaud(int gpio_nr, uint32_t ratediv)
00085 {
00086 uint32_t offset = ratediv/4;
00087 uint32_t odd = ratediv/2;
00088 uint32_t even = ratediv-odd;
00089
00090 if (odd > 255 || even > 255) return -2;
00091
00092 return setSyncBaud(gpio_nr, offset, odd, even);
00093 }
00094
00095
00097
00102 int base::Gpio::getSyncBaud(int gpio_nr, uint32_t& offset,
00103 uint32_t& odd, uint32_t& even)
00104 {
00105 uint32_t addr_offset[3] = {base::GPIO_SYNCM_BAUD_START,
00106 base::GPIO_SYNCS0_BAUD_START,
00107 base::GPIO_SYNCS1_BAUD_START};
00108 uint32_t addr_odd[3] = {base::GPIO_SYNCM_BAUD1,
00109 base::GPIO_SYNCS0_BAUD1,
00110 base::GPIO_SYNCS1_BAUD1};
00111 uint32_t addr_even[3] = {base::GPIO_SYNCM_BAUD2,
00112 base::GPIO_SYNCS0_BAUD2,
00113 base::GPIO_SYNCS1_BAUD2};
00114
00115 if (gpio_nr < 1 || gpio_nr > 3) return -1;
00116
00117 uint32_t offset_raw;
00118 uint32_t odd_raw;
00119 uint32_t even_raw;
00120
00121 int rc = board().operGGG(addr_offset[gpio_nr-1], offset_raw,
00122 addr_odd[gpio_nr-1], odd_raw,
00123 addr_even[gpio_nr-1], even_raw);
00124
00125 offset = offset_raw + 1;
00126 odd = odd_raw + 1;
00127 even = even_raw + 1;
00128
00129 return rc;
00130 }
00131
00132
00134
00139 int base::Gpio::getSyncBaud(int gpio_nr, uint32_t& ratediv)
00140 {
00141 uint32_t offset;
00142 uint32_t odd;
00143 uint32_t even;
00144
00145 int rc = getSyncBaud(gpio_nr, offset, odd, even);
00146 ratediv = odd + even;
00147 return rc;
00148 }
00149
00150
00152
00190 int base::Gpio::setSyncScale(uint32_t val)
00191 {
00192 return board().put(base::GPIO_SYNCM_SCALEDOWN, val);
00193 }
00194
00195
00197
00202 int base::Gpio::getSyncScale(uint32_t& val)
00203 {
00204 return board().get(base::GPIO_SYNCM_SCALEDOWN, val);
00205 }
00206
00207
00209
00215 int base::Gpio::getConfig(uint32_t& mask)
00216 {
00217 return board().get(base::GPIO_CONFIG, mask);
00218 }
00219
00220
00222
00228 int base::Gpio::setConfig(uint32_t mask)
00229 {
00230 return board().put(base::GPIO_CONFIG, mask);
00231 }
00232
00233
00235
00258 int base::Gpio::setConfig(int gpio_nr, bool riseedge, bool falledge,
00259 bool throttled, bool extrafunc, bool altin)
00260 {
00261 uint32_t mask;
00262 int rc = getConfig(mask);
00263 if (rc) return rc;
00264 if (!packConfig(mask, gpio_nr, riseedge, falledge, throttled,
00265 extrafunc, altin)) return -1;
00266 rc = setConfig(mask);
00267 if (rc) base::Board::operErrBuildInc(rc,1);
00268 return 0;
00269 }
00270
00271
00273
00282 bool base::Gpio::packConfig(uint32_t& mask, int gpio_nr,
00283 bool riseedge, bool falledge,
00284 bool throttled, bool extrafunc,
00285 bool altin)
00286 {
00287 if (gpio_nr <2 || gpio_nr>7) return false;
00288
00289 if (gpio_nr==2 || gpio_nr==3) {
00290 riseedge = riseedge | falledge;
00291 falledge = false;
00292 }
00293
00294 mask = mask & (~(0xf<<(4*gpio_nr)));
00295 uint32_t submask = 0;
00296 if (riseedge) submask |= 0x1;
00297 if (falledge) submask |= 0x2;
00298 if (throttled) submask |= 0x4;
00299 if (extrafunc) submask |= 0x8;
00300 mask = mask | ( submask << (4*gpio_nr));
00301
00302 if (gpio_nr >= 4) {
00303 uint32_t bitmask = 1<<(gpio_nr-4);
00304 mask = mask & (~bitmask);
00305 if (altin) mask |= bitmask;
00306 }
00307
00308 return true;
00309 }
00310
00311
00313
00321 bool base::Gpio::unpackConfig(uint32_t mask, int gpio_nr,
00322 bool& riseedge, bool& falledge,
00323 bool& throttled, bool& extrafunc,
00324 bool& altin)
00325 {
00326 if (gpio_nr <2 || gpio_nr>7) return false;
00327
00328 uint32_t submask = (mask >> (4*gpio_nr)) & 0xf;
00329
00330 riseedge = (submask & 0x1) != 0;
00331 falledge = (submask & 0x2) != 0;
00332 throttled = (submask & 0x4) != 0;
00333 extrafunc = (submask & 0x8) != 0;
00334
00335 if ((gpio_nr==2)||(gpio_nr==3)) {
00336 riseedge = riseedge | falledge;
00337 falledge = false;
00338 }
00339
00340 altin = false;
00341
00342 if (gpio_nr >= 4) {
00343 uint32_t bitmask = 1<<(gpio_nr-4);
00344 altin = (mask & bitmask) != 0;
00345 }
00346
00347 return true;
00348 }
00349
00350
00352
00353 void base::Gpio::addAddrMap(base::Board* board)
00354 {
00355 board->addRegAddrMapping("base::GPIO_CONFIG", base::GPIO_CONFIG);
00356 board->addRegAddrMapping("base::GPIO_SYNCM_SCALEDOWN", base::GPIO_SYNCM_SCALEDOWN);
00357 board->addRegAddrMapping("base::GPIO_SYNCM_BAUD_START", base::GPIO_SYNCM_BAUD_START);
00358 board->addRegAddrMapping("base::GPIO_SYNCM_BAUD1", base::GPIO_SYNCM_BAUD1);
00359 board->addRegAddrMapping("base::GPIO_SYNCM_BAUD2", base::GPIO_SYNCM_BAUD2);
00360 board->addRegAddrMapping("base::GPIO_SYNCS0_BAUD_START", base::GPIO_SYNCS0_BAUD_START);
00361 board->addRegAddrMapping("base::GPIO_SYNCS0_BAUD1", base::GPIO_SYNCS0_BAUD1);
00362 board->addRegAddrMapping("base::GPIO_SYNCS0_BAUD2", base::GPIO_SYNCS0_BAUD2);
00363 board->addRegAddrMapping("base::GPIO_SYNCS1_BAUD_START", base::GPIO_SYNCS1_BAUD_START);
00364 board->addRegAddrMapping("base::GPIO_SYNCS1_BAUD1", base::GPIO_SYNCS1_BAUD1);
00365 board->addRegAddrMapping("base::GPIO_SYNCS1_BAUD2", base::GPIO_SYNCS1_BAUD2);
00366 }
00367
00368
00369
00370
00371 const char* base::Gpio::name(int n)
00372 {
00373 static const char* gpio_names[base::NumGpio] = { "SYNC_M", "SYNC_S0", "SYNC_S1", "AUX0", "AUX1", "AUX2", "AUX3" };
00374
00375 if ((n<0) || (n>=base::NumGpio)) return 0;
00376
00377 return gpio_names[n];
00378 }