Main Page | Modules | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

# prism2.c

Go to the documentation of this file.

    00001 /*! \file prism2.c \brief Prism2 802.11b Wireless-LAN Interface Driver. */
    00002 //*****************************************************************************
    00003 //
    00004 // File Name    : 'prism2.c'
    00005 // Title        : Prism2 802.11b Wireless-LAN Interface Driver
    00006 // Author       : Pascal Stang
    00007 // Created      : 12/27/2004
    00008 // Revised      : 1/7/2005
    00009 // Version      : 0.1
    00010 // Target MCU   : Atmel AVR series
    00011 // Editor Tabs  : 4
    00012 //
    00013 // Description  : This driver provides initialization and transmit/receive
    00014 //      functions for the Prism2 802.11b Wireless-LAN Controller.
    00015 //
    00016 //*****************************************************************************
    00017
    00018 #include <avr/io.h>
    00019 #include <avr/interrupt.h>
    00020 #include <string.h>
    00021
    00022 #include "global.h"
    00023 #include "timer.h"
    00024 #include "rprintf.h"
    00025 #include "debug.h"
    00026
    00027 #include "net.h"
    00028 #include "prism2.h"
    00029
    00030 // include configuration
    00031 #include "prism2conf.h"
    00032
    00033 u16 TxHeader[34];
    00034
    00035 void nicInit(void)
    00036 {
    00037     prism2Init();
    00038 }
    00039
    00040 void nicSend(unsigned int len, unsigned char* packet)
    00041 {
    00042     u16 i;
    00043     u16 txfid;
    00044     u08 stat;
    00045     // request free buffer space to store outgoing frame
    00046     prism2Command(PRISM2_CMD_ALLOC, len+44+14+6);
    00047     // wait for buffer to be allocated
    00048     while( !(prism2Read16(PRISM2_REG_EVSTAT) & PRISM2_EVENT_ALLOC) );
    00049     // get the buffer FID
    00050     txfid = prism2Read16(PRISM2_REG_ALLOCFID);
    00051     // ACK the alloc event
    00052     prism2Write16(PRISM2_REG_EVACK, PRISM2_EVENT_ALLOC);
    00053
    00054 //  rprintf("PRISM2: TxFID=0x");
    00055 //  rprintfu16(txfid);
    00056 //  rprintfCRLF();
    00057
    00058     // adjust packet length because MAC addresses and type
    00059     // will be written seperately from packet payload
    00060     len-=14;
    00061
    00062     // write the outgoing frame to BAP
    00063     // begin with control structure
    00064     prism2SetupTxHeader(TxHeader);
    00065
    00066     // write dest and src MAC addresses
    00067     for(i=0;i<6;++i)
    00068         TxHeader[23+i] = packet[i*2+1]<<8 | packet[i*2];
    00069     // write length
    00070     TxHeader[29] = htons(len+8);
    00071     // write type
    00072     TxHeader[33] = packet[13]<<8 | packet[12];
    00073
    00074 //  debugPrintHexTable(34*2, (u08*)TxHeader);
    00075 //  rprintfCRLF();
    00076 //  debugPrintHexTable(len, &packet[14]);
    00077
    00078     // write Tx header out to BAP
    00079     prism2WriteBAP0(txfid, 0, TxHeader, 34);
    00080     // write packet out to BAP
    00081     prism2WriteBAP0(txfid, 68, (u16*)&packet[14], (len+1)>>1);
    00082     // issue transmit command
    00083     stat = prism2Command(PRISM2_CMD_TX, txfid);
    00084     if(stat)
    00085         rprintf("Transmit failed: 0x%x\r\n", stat);
    00086     // do cleanup
    00087     prism2EventCheck();
    00088 }
    00089
    00090 void nicGetMacAddress(u08* macaddr)
    00091 {
    00092     prism2GetMacAddress(macaddr);
    00093 }
    00094
    00095 void nicSetMacAddress(u08* macaddr)
    00096 {
    00097     // not yet supported
    00098 }
    00099
    00100 void nicRegDump(void)
    00101 {
    00102     prism2CardRegDump();
    00103     prism2RegDump();
    00104 }
    00105
    00106 void prism2SetupTxHeader(u16* header)
    00107 {
    00108     u16 i;
    00109
    00110     // clear out header
    00111     for(i=0;i<22;i++)
    00112         header[i] = 0x00;
    00113
    00114     // set TxRate and retry count
    00115     header[5] = (0<<8) | 0;
    00116     // 0x00 = automatic selection
    00117     // 0x0A = 10  = 1.0Mbit/s
    00118     // 0x14 = 20  = 2.0Mbit/s
    00119     // 0x37 = 55  = 5.5Mbit/s
    00120     // 0x6E = 110 = 11 Mbit/s
    00121
    00122     // set TxControl
    00123     header[6] = 0x0004;
    00124
    00125     // write length
    00126     // (not really needed since card will pull info from 802.3 header)
    00127     //TxHeader[22] = len+8;
    00128
    00129     // fill in 802.3 header fields
    00130     TxHeader[30] = 0xAAAA;
    00131     TxHeader[31] = 0x0003;
    00132     TxHeader[32] = 0x0000;
    00133
    00134     // src mac address @ byte offset 52
    00135 }
    00136
    00137 void prism2EventCheck(void)
    00138 {
    00139     unsigned int evstat_data;
    00140
    00141     evstat_data = prism2Read16(PRISM2_REG_EVSTAT);
    00142
    00143     if(evstat_data & PRISM2_EVENT_TX)
    00144     {
    00145         prism2Write16(PRISM2_REG_EVACK,PRISM2_EVENT_TX);
    00146     }
    00147
    00148     if(evstat_data & PRISM2_EVENT_TXEXEC)
    00149     {
    00150         prism2Write16(PRISM2_REG_EVACK,PRISM2_EVENT_TXEXEC);
    00151     }
    00152
    00153     if(evstat_data & PRISM2_EVENT_ALLOC)
    00154     {
    00155         prism2Write16(PRISM2_REG_EVACK, 0x0002);
    00156     }
    00157
    00158     if(evstat_data & PRISM2_EVENT_CMD)
    00159     {
    00160         prism2Write16(PRISM2_REG_EVACK, PRISM2_EVENT_CMD);
    00161     }
    00162
    00163     if(evstat_data & PRISM2_EVENT_INFO)
    00164     {
    00165         prism2Read16(PRISM2_REG_INFOFID);
    00166         prism2Write16(PRISM2_REG_EVACK, PRISM2_EVENT_INFO);
    00167     }
    00168
    00169     if(evstat_data & PRISM2_EVENT_INFDROP)
    00170     {
    00171         prism2Write16(PRISM2_REG_EVACK, PRISM2_EVENT_INFDROP);
    00172     }
    00173
    00174     if(evstat_data & PRISM2_EVENT_WTERR)
    00175     {
    00176         prism2Write16(PRISM2_REG_EVACK, PRISM2_EVENT_WTERR);
    00177     }
    00178 }
    00179
    00180
    00181 unsigned int nicPoll(unsigned int maxlen, unsigned char* packet)
    00182 {
    00183     u16 rxfid=0;
    00184     u16 packetLength=0;
    00185
    00186     // check if packets have been received
    00187     if(prism2Read16(PRISM2_REG_EVSTAT) & PRISM2_EVENT_RX)
    00188     {
    00189         // we have a receive event
    00190         // get RxFID
    00191         rxfid = prism2Read16(PRISM2_REG_RXFID);
    00192         // read the packet length
    00193         prism2ReadBAP0(rxfid, 44, &packetLength, 1);
    00194     }
    00195
    00196     // if there's no packet or an error - exit
    00197     if( !packetLength )
    00198         return 0;
    00199
    00200     // drop anything too big for the buffer
    00201     if( packetLength > maxlen )
    00202     {
    00203         // ACK the receive event to finish up
    00204         prism2Write16(PRISM2_REG_EVACK, PRISM2_EVENT_RX);
    00205         return 0;
    00206     }
    00207
    00208     // packet is available, retrieve data
    00209     // this is a hack: while reading in data,
    00210     // convert 802.2/3 header to ethernet header
    00211     // first get dest and src MAC addresses
    00212     prism2ReadBAP0(rxfid, 46, (u16*)&packet[0], 6);
    00213     // skip length, snap, and ctrl fields
    00214     // begin data copy again at type field
    00215     prism2ReadBAP0(rxfid, 46+12+8, (u16*)&packet[12], packetLength-6);
    00216     // ACK the receive event to finish up
    00217     prism2Write16(PRISM2_REG_EVACK, PRISM2_EVENT_RX);
    00218
    00219     return packetLength;
    00220 }
    00221
    00222 void prism2InitPorts(void)
    00223 {
    00224 #if NIC_CONNECTION == MEMORY_MAPPED
    00225     // enable external SRAM interface - no wait states
    00226     sbi(MCUSR, SRE);
    00227 #else
    00228     // set address port to output
    00229     outb(PRISM2_ADDRESS_DDR, PRISM2_ADDRESS_MASK);
    00230     outb(PRISM2_HADDRESS_DDR, PRISM2_HADDRESS_MASK);
    00231
    00232     // set data port to input with pull-ups
    00233     outb(PRISM2_DATA_DDR, 0x00);
    00234     outb(PRISM2_DATA_PORT, 0xFF);
    00235
    00236     // initialize the control port read and write pins to de-asserted
    00237     sbi( PRISM2_CONTROL_PORT, PRISM2_CONTROL_IORD );
    00238     sbi( PRISM2_CONTROL_PORT, PRISM2_CONTROL_IOWR );
    00239     sbi( PRISM2_CONTROL_PORT, PRISM2_CONTROL_MEMRD );
    00240     sbi( PRISM2_CONTROL_PORT, PRISM2_CONTROL_MEMWR );
    00241     // set the read and write pins to output
    00242     sbi( PRISM2_CONTROL_DDR, PRISM2_CONTROL_IORD );
    00243     sbi( PRISM2_CONTROL_DDR, PRISM2_CONTROL_IOWR );
    00244     sbi( PRISM2_CONTROL_DDR, PRISM2_CONTROL_MEMRD );
    00245     sbi( PRISM2_CONTROL_DDR, PRISM2_CONTROL_MEMWR );
    00246 #endif
    00247     // set reset pin to output
    00248     sbi( PRISM2_RESET_DDR, PRISM2_RESET_PIN );
    00249
    00250     // clear -REG pin
    00251     sbi(DDRB, 6);
    00252     cbi(PORTB, 6);
    00253     // setup IREQ pin
    00254     cbi(DDRB, 7);
    00255     sbi(PORTB, 7);
    00256 }
    00257
    00258 void prism2Init(void)
    00259 {
    00260     u08 result;
    00261     u16 buffer[20];
    00262
    00263 //  rprintf("Init ports\r\n");
    00264     prism2InitPorts();
    00265
    00266     // assert hardware reset
    00267     sbi( PRISM2_RESET_PORT, PRISM2_RESET_PIN );
    00268     // wait
    00269     delay_ms(10);
    00270     // release hardware reset
    00271     cbi( PRISM2_RESET_PORT, PRISM2_RESET_PIN );
    00272     delay_ms(100);
    00273
    00274 /*
    00275     // soft-reset card
    00276     prism2WriteMem(0x3E0+PCMCIA_ATTR_COR, 0x80);
    00277     delay_ms(10);
    00278     prism2WriteMem(0x3E0+PCMCIA_ATTR_COR, 0x00);
    00279     // wait until soft-reset is done
    00280     delay_ms(500);
    00281
    00282     // set 8-bit PCMCIA I/O mode
    00283     prism2WriteMem(0x3E0+PCMCIA_ATTR_CSR, 0x20);
    00284
    00285     prism2WriteMem(0x3E0+PCMCIA_ATTR_CSR, 0x04);
    00286     timerPause(1000);
    00287     prism2WriteMem(0x3E0+PCMCIA_ATTR_CSR, 0x00);
    00288 */
    00289     // enable PCMCIA I/O mode
    00290     prism2WriteMem(0x3E0+PCMCIA_ATTR_COR, prism2ReadMem(0x3E0+PCMCIA_ATTR_COR) | 0x01);
    00291 //  prism2CardRegDump();
    00292
    00293     rprintf("Prism2 Initializing...\r\n");
    00294     if( (result = prism2Command(PRISM2_CMD_INIT,0)) )
    00295     {
    00296         rprintf("Prism2 Initialization Failure\r\n");
    00297         rprintf("Result Code = %x\r\n",result);
    00298     }
    00299
    00300     rprintf("Prism2 Initialized\r\n");
    00301
    00302     // set SSID
    00303     prism2SetSSID("airdrop");
    00304
    00305     // set max packet size
    00306     buffer[0] = 0x0002;
    00307     buffer[1] = PRISM2_RID_CNFMAXDATALEN;
    00308     buffer[2] = 0x05DC;
    00309     prism2WriteRID(PRISM2_RID_CNFMAXDATALEN, 0, buffer, 3);
    00310
    00311     // set operating mode / port type
    00312     buffer[0] = 0x0002;
    00313     buffer[1] = PRISM2_RID_CNFPORTTYPE;
    00314     //buffer[2] = 0x0000; // IBSS
    00315     buffer[2] = 0x0001; // BSS
    00316     prism2WriteRID(PRISM2_RID_CNFPORTTYPE, 0, buffer, 3);
    00317
    00318     // set channel
    00319 //  buffer[0] = 0x0002;
    00320 //  buffer[1] = 0xFC03;
    00321 //  buffer[2] = 0x0001;
    00322 //  prism2WriteRID(0xFC00, 0, buffer, 3);
    00323
    00324     // enable the interface
    00325     prism2Command(PRISM2_CMD_ENABLE_MAC0,0);
    00326 }
    00327
    00328 void prism2Off(void)
    00329 {
    00330     // turn off communication
    00331     prism2Command(PRISM2_CMD_DISABLE_MAC0,0);
    00332     // wait for all events to complete
    00333     delay_ms(100);
    00334     // reset card
    00335     prism2Command(PRISM2_CMD_INIT,0);
    00336 }
    00337
    00338 void prism2GetMacAddress(u08* macaddr)
    00339 {
    00340     u16 buffer[5];
    00341
    00342     // read MAC address register
    00343     prism2ReadRID(PRISM2_RID_CNFOWNMACADDR, 0, buffer, 5);
    00344
    00345     *macaddr++ = buffer[2];
    00346     *macaddr++ = buffer[2]>>8;
    00347     *macaddr++ = buffer[3];
    00348     *macaddr++ = buffer[3]>>8;
    00349     *macaddr++ = buffer[4];
    00350     *macaddr++ = buffer[4]>>8;
    00351 }
    00352
    00353 void prism2SetSSID(u08* ssid)
    00354 {
    00355     u16 buffer[12];
    00356
    00357     // prepare buffer for SSID write
    00358     buffer[0] = 0x0012;
    00359     buffer[1] = PRISM2_RID_CNFDESIREDSSID;
    00360     buffer[2] = strlen(ssid);
    00361     // copy ssid string to buffer
    00362     strcpy((unsigned char*)&buffer[3], ssid);
    00363     // write SSID
    00364     prism2WriteRID(PRISM2_RID_CNFDESIREDSSID, 0, buffer, buffer[0]);
    00365 }
    00366
    00367 void prism2SetWEPKey(u08* wepkey)
    00368 {
    00369     u16 buffer[9];
    00370
    00371     // prepare buffer for SSID write
    00372     buffer[0] = 0x0008;
    00373     buffer[1] = PRISM2_RID_CNFWEPDEFAULTKEY0;
    00374     // copy ssid string to buffer
    00375     strncpy((unsigned char*)&buffer[2], wepkey, 13);
    00376     buffer[8] &= 0x00FF;
    00377     // write SSID
    00378     prism2WriteRID(PRISM2_RID_CNFWEPDEFAULTKEY0, 0, buffer, buffer[0]);
    00379
    00380     // set WEP active
    00381     buffer[0] = 0x0002;
    00382     buffer[1] = PRISM2_RID_CNFWEPFLAGS;
    00383     buffer[2] = 0x0001;
    00384     prism2WriteRID(PRISM2_RID_CNFWEPFLAGS, 0, buffer, buffer[0]);
    00385     // set WEP active
    00386     buffer[0] = 0x0002;
    00387     buffer[1] = 0xfc2a;
    00388     buffer[2] = 0x0001;
    00389     prism2WriteRID(0xfc2a, 0, buffer, buffer[0]);
    00390     // set WEP active
    00391     buffer[0] = 0x0002;
    00392     buffer[1] = 0xfc23;
    00393     buffer[2] = 0x0000;
    00394     prism2WriteRID(0xfc23, 0, buffer, buffer[0]);
    00395
    00396 }
    00397
    00398 u08 prism2Command(u16 cmd, u16 param0)
    00399 {
    00400     u16 result;
    00401
    00402     // wait until card not busy
    00403 //  rprintf("PRISM_CMD: Wait until card ready\r\n");
    00404     while(prism2Read16(PRISM2_REG_CMD) & PRISM2_CMD_BUSY);
    00405
    00406 //  rprintf("PRISM_CMD: Issue Command = 0x%x\r\n", cmd);
    00407     prism2Write16(PRISM2_REG_PARAM0, param0);
    00408     prism2Write16(PRISM2_REG_CMD, cmd);
    00409
    00410     // wait until card not busy
    00411 //  rprintf("PRISM_CMD: Wait until card ready\r\n");
    00412     while(prism2Read16(PRISM2_REG_CMD) & PRISM2_CMD_BUSY);
    00413
    00414     // read event register - wait for command to complete
    00415 //  rprintf("PRISM_CMD: Wait for command to complete\r\n");
    00416     while(!(prism2Read16(PRISM2_REG_EVSTAT) & PRISM2_EVENT_CMD));
    00417
    00418     // read status register
    00419     result = prism2Read16(PRISM2_REG_STATUS)>>8;
    00420 //  rprintf("PRISM_CMD: Result  = 0x%x\r\n", result>>8);
    00421 //  rprintf("PRISM_CMD: CmdCode = 0x%x\r\n", result);
    00422
    00423     // acknowledge event
    00424 //  rprintf("PRISM_CMD: Ack command event\r\n");
    00425     prism2Write16(PRISM2_REG_EVACK, PRISM2_EVENT_CMD);
    00426
    00427     // return command result
    00428     return result;
    00429 }
    00430
    00431 u08 prism2ReadRID(u16 id, u16 offset, u16* data, u16 len)
    00432 {
    00433     prism2Command(PRISM2_CMD_ACCESS_RD, id);
    00434     return prism2ReadBAP0(id, offset, data, len);
    00435 }
    00436
    00437 u08 prism2WriteRID(u16 id, u16 offset, u16* data, u16 len)
    00438 {
    00439     u08 result;
    00440     result = prism2WriteBAP0(id, offset, data, len);
    00441     prism2Command(PRISM2_CMD_ACCESS_WR, id);
    00442     return result;
    00443 }
    00444
    00445 u08 prism2ReadBAP0(u16 id, u16 offset, u16* data, u16 len)
    00446 {
    00447     // wait for BAP to be ready
    00448     //rprintf("PRISM_BAP: Wait1\r\n");
    00449     while( prism2Read16(PRISM2_REG_BAP0OFFSET) & PRISM2_BAPOFFSET_BUSY);
    00450     // set ID
    00451     prism2Write16(PRISM2_REG_BAP0SEL, id);
    00452     // set offset
    00453     prism2Write16(PRISM2_REG_BAP0OFFSET, offset);
    00454     // wait for BAP to be ready
    00455     //rprintf("PRISM_BAP: Wait2\r\n");
    00456     while( prism2Read16(PRISM2_REG_BAP0OFFSET) & PRISM2_BAPOFFSET_BUSY);
    00457     // check for error
    00458     if(prism2Read16(PRISM2_REG_BAP0OFFSET) & PRISM2_BAPOFFSET_ERROR)
    00459         return -1;
    00460     // read data
    00461     //rprintf("PRISM_BAP: Read\r\n");
    00462     while(len--)
    00463         *data++ = prism2Read16(PRISM2_REG_BAP0DATA);
    00464     // return success
    00465     return 0;
    00466 }
    00467
    00468 u08 prism2WriteBAP0(u16 id, u16 offset, u16* data, u16 len)
    00469 {
    00470     // wait for BAP to be ready
    00471     //rprintf("PRISM_BAP: Wait1\r\n");
    00472     while( prism2Read16(PRISM2_REG_BAP0OFFSET) & PRISM2_BAPOFFSET_BUSY);
    00473     // set ID
    00474     prism2Write16(PRISM2_REG_BAP0SEL, id);
    00475     // set offset
    00476     prism2Write16(PRISM2_REG_BAP0OFFSET, offset);
    00477     // wait for BAP to be ready
    00478     //rprintf("PRISM_BAP: Wait2\r\n");
    00479     while( prism2Read16(PRISM2_REG_BAP0OFFSET) & PRISM2_BAPOFFSET_BUSY);
    00480     // check for error
    00481     if(prism2Read16(PRISM2_REG_BAP0OFFSET) & PRISM2_BAPOFFSET_ERROR)
    00482         return -1;
    00483     // write data
    00484     //rprintf("PRISM_BAP: Write\r\n");
    00485     while(len--)
    00486         prism2Write16(PRISM2_REG_BAP0DATA, *data++);
    00487     // return success
    00488     return 0;
    00489 }
    00490
    00491 void prism2Write(unsigned short address, unsigned char data)
    00492 {
    00493     cli();
    00494     // assert the address
    00495     outb(PRISM2_HADDRESS_PORT, (address>>8) | (inb(PRISM2_HADDRESS_PORT)&~PRISM2_HADDRESS_MASK));
    00496     outb(PRISM2_ADDRESS_PORT, address | (inb(PRISM2_ADDRESS_PORT)&~PRISM2_ADDRESS_MASK));
    00497     // set data bus as output
    00498     outb(PRISM2_DATA_DDR, 0xFF);
    00499     // place data on bus
    00500     outb(PRISM2_DATA_PORT, data);
    00501     // assert write
    00502     cbi(PRISM2_CONTROL_PORT, PRISM2_CONTROL_IOWR);
    00503     // delay
    00504     PRISM2_IO_ACCESS_DELAY;
    00505     // negate write
    00506     sbi(PRISM2_CONTROL_PORT, PRISM2_CONTROL_IOWR);
    00507     // set data bus back to input with pullups enabled
    00508     outb(PRISM2_DATA_DDR, 0x00);
    00509     outb(PRISM2_DATA_PORT, 0xFF);
    00510     sei();
    00511 }
    00512
    00513 unsigned char prism2Read(unsigned short address)
    00514 {
    00515     unsigned char data;
    00516     cli();
    00517     // assert the address
    00518     outb(PRISM2_HADDRESS_PORT, (address>>8) | (inb(PRISM2_HADDRESS_PORT)&~PRISM2_HADDRESS_MASK));
    00519     outb(PRISM2_ADDRESS_PORT, address | (inb(PRISM2_ADDRESS_PORT)&~PRISM2_ADDRESS_MASK));
    00520     // set data bus to input with pullups enabled
    00521     outb(PRISM2_DATA_DDR, 0x00);
    00522     outb(PRISM2_DATA_PORT, 0xFF);
    00523     // assert read
    00524     cbi(PRISM2_CONTROL_PORT, PRISM2_CONTROL_IORD);
    00525     // delay
    00526     PRISM2_IO_ACCESS_DELAY;
    00527     // read in the data
    00528     data = inb( PRISM2_DATA_PIN );
    00529     // negate read
    00530     sbi(PRISM2_CONTROL_PORT, PRISM2_CONTROL_IORD);
    00531     // return data
    00532     sei();
    00533     return data;
    00534 }
    00535
    00536 void prism2Write16(unsigned short address, unsigned short data)
    00537 {
    00538     prism2Write(address, data);
    00539     prism2Write(address+1, data>>8);
    00540 }
    00541
    00542 unsigned short prism2Read16(unsigned short address)
    00543 {
    00544     return prism2Read(address) | (prism2Read(address+1)<<8);
    00545 }
    00546
    00547 void prism2WriteMem(unsigned short address, unsigned short data)
    00548 {
    00549     cli();
    00550     // assert the address
    00551     outb(PRISM2_HADDRESS_PORT, (address>>8) | (inb(PRISM2_HADDRESS_PORT)&~PRISM2_HADDRESS_MASK));
    00552     outb(PRISM2_ADDRESS_PORT, address | (inb(PRISM2_ADDRESS_PORT)&~PRISM2_ADDRESS_MASK));
    00553     // set data bus as output
    00554     outb(PRISM2_DATA_DDR, 0xFF);
    00555     // place data on bus
    00556     outb(PRISM2_DATA_PORT, data);
    00557     // assert write
    00558     cbi(PRISM2_CONTROL_PORT, PRISM2_CONTROL_MEMWR);
    00559     // delay
    00560     PRISM2_MEM_ACCESS_DELAY;
    00561     // negate write
    00562     sbi(PRISM2_CONTROL_PORT, PRISM2_CONTROL_MEMWR);
    00563     // set data bus back to input with pullups enabled
    00564     outb(PRISM2_DATA_DDR, 0x00);
    00565     outb(PRISM2_DATA_PORT, 0xFF);
    00566     sei();
    00567 }
    00568
    00569 unsigned short prism2ReadMem(unsigned short address)
    00570 {
    00571     unsigned char data;
    00572     cli();
    00573     // assert the address
    00574     outb(PRISM2_HADDRESS_PORT, (address>>8) | (inb(PRISM2_HADDRESS_PORT)&~PRISM2_HADDRESS_MASK));
    00575     outb(PRISM2_ADDRESS_PORT, address | (inb(PRISM2_ADDRESS_PORT)&~PRISM2_ADDRESS_MASK));
    00576     // set data bus to input with pullups enabled
    00577     outb(PRISM2_DATA_DDR, 0x00);
    00578     outb(PRISM2_DATA_PORT, 0xFF);
    00579     // assert read
    00580     cbi(PRISM2_CONTROL_PORT, PRISM2_CONTROL_MEMRD);
    00581     // delay
    00582     PRISM2_MEM_ACCESS_DELAY;
    00583     // read in the data
    00584     data = inb( PRISM2_DATA_PIN );
    00585     // negate read
    00586     sbi(PRISM2_CONTROL_PORT, PRISM2_CONTROL_MEMRD);
    00587     sei();
    00588     // return data
    00589     return data;
    00590 }
    00591
    00592 void prism2CardRegDump(void)
    00593 {
    00594     u16 i;
    00595     u08 buffer[0x100];
    00596
    00597     rprintfProgStrM("Card Config Registers\r\n");
    00598     rprintfProgStrM("-------------------------------\r\n");
    00599     // read card CIS (16 bytes)
    00600     rprintf("CIS : \r\n");
    00601     for(i=0; i<0x100; i++)
    00602         buffer[i] = prism2ReadMem(i<<1);
    00603     debugPrintHexTable(0x100, buffer);
    00604
    00605     rprintfCRLF();
    00606
    00607     rprintf("COR : "); rprintfu08(prism2ReadMem(0x3E0+PCMCIA_ATTR_COR)); rprintfCRLF();
    00608     rprintf("CSR : "); rprintfu08(prism2ReadMem(0x3E0+PCMCIA_ATTR_CSR)); rprintfCRLF();
    00609     rprintf("PRR : "); rprintfu08(prism2ReadMem(0x3E0+PCMCIA_ATTR_PRR)); rprintfCRLF();
    00610     rprintf("SCR : "); rprintfu08(prism2ReadMem(0x3E0+PCMCIA_ATTR_SCR)); rprintfCRLF();
    00611 }
    00612
    00613 void prism2RegDump(void)
    00614 {
    00615     rprintfProgStrM("Prism2 Registers\r\n");
    00616     rprintfProgStrM("CMD     : "); rprintfu16(prism2Read16(PRISM2_REG_CMD));        rprintfCRLF();
    00617     rprintfProgStrM("PARAM0  : "); rprintfu16(prism2Read16(PRISM2_REG_PARAM0));     rprintfCRLF();
    00618     rprintfProgStrM("PARAM1  : "); rprintfu16(prism2Read16(PRISM2_REG_PARAM1));     rprintfCRLF();
    00619     rprintfProgStrM("PARAM2  : "); rprintfu16(prism2Read16(PRISM2_REG_PARAM2));     rprintfCRLF();
    00620     rprintfProgStrM("STATUS  : "); rprintfu16(prism2Read16(PRISM2_REG_STATUS));     rprintfCRLF();
    00621     rprintfProgStrM("RESP0   : "); rprintfu16(prism2Read16(PRISM2_REG_RESP0));      rprintfCRLF();
    00622     rprintfProgStrM("RESP1   : "); rprintfu16(prism2Read16(PRISM2_REG_RESP1));      rprintfCRLF();
    00623     rprintfProgStrM("RESP2   : "); rprintfu16(prism2Read16(PRISM2_REG_RESP2));      rprintfCRLF();
    00624
    00625     rprintfProgStrM("INFOFID : "); rprintfu16(prism2Read16(PRISM2_REG_INFOFID));    rprintfCRLF();
    00626     rprintfProgStrM("RXFID   : "); rprintfu16(prism2Read16(PRISM2_REG_RXFID));      rprintfCRLF();
    00627     rprintfProgStrM("ALLOCFID: "); rprintfu16(prism2Read16(PRISM2_REG_ALLOCFID));   rprintfCRLF();
    00628     rprintfProgStrM("TXFID   : "); rprintfu16(prism2Read16(PRISM2_REG_TXFID));      rprintfCRLF();
    00629
    00630     rprintfProgStrM("BAP0SEL : "); rprintfu16(prism2Read16(PRISM2_REG_BAP0SEL));    rprintfCRLF();
    00631     rprintfProgStrM("BAP0OFFS: "); rprintfu16(prism2Read16(PRISM2_REG_BAP0OFFSET)); rprintfCRLF();
    00632     rprintfProgStrM("BAP0DATA: "); rprintfu16(prism2Read16(PRISM2_REG_BAP0DATA));   rprintfCRLF();
    00633
    00634     rprintfProgStrM("BAP1SEL : "); rprintfu16(prism2Read16(PRISM2_REG_BAP1SEL));    rprintfCRLF();
    00635     rprintfProgStrM("BAP1OFFS: "); rprintfu16(prism2Read16(PRISM2_REG_BAP1OFFSET)); rprintfCRLF();
    00636     rprintfProgStrM("BAP1DATA: "); rprintfu16(prism2Read16(PRISM2_REG_BAP1DATA));   rprintfCRLF();
    00637
    00638     rprintfProgStrM("EVSTAT  : "); rprintfu16(prism2Read16(PRISM2_REG_EVSTAT));     rprintfCRLF();
    00639     rprintfProgStrM("INTEN   : "); rprintfu16(prism2Read16(PRISM2_REG_INTEN));      rprintfCRLF();
    00640     rprintfProgStrM("EVACK   : "); rprintfu16(prism2Read16(PRISM2_REG_EVACK));      rprintfCRLF();
    00641
    00642     rprintfProgStrM("SWSUP0  : "); rprintfu16(prism2Read16(PRISM2_REG_SWSUP0));     rprintfCRLF();
    00643     rprintfProgStrM("SWSUP0  : "); rprintfu16(prism2Read16(PRISM2_REG_SWSUP1));     rprintfCRLF();
    00644     rprintfProgStrM("SWSUP0  : "); rprintfu16(prism2Read16(PRISM2_REG_SWSUP2));     rprintfCRLF();
    00645
    00646     rprintfProgStrM("AUXPAGE : "); rprintfu16(prism2Read16(PRISM2_REG_AUXPAGE));    rprintfCRLF();
    00647     rprintfProgStrM("AUXOFFS : "); rprintfu16(prism2Read16(PRISM2_REG_AUXOFFSET));  rprintfCRLF();
    00648     rprintfProgStrM("AUXDATA : "); rprintfu16(prism2Read16(PRISM2_REG_AUXDATA));    rprintfCRLF();
    00649
    00650     delay_ms(25);
    00651 }