more WIFI registers implemented, some fixed to match behavior on hardware

This commit is contained in:
MightyMax 2009-01-01 17:54:16 +00:00
parent 43880c9a21
commit 0a909c831d
2 changed files with 976 additions and 855 deletions

View File

@ -384,17 +384,23 @@ void WIFI_setBB_DATA(wifimac_t *wifi, u8 val)
*******************************************************************************/
void WIFI_triggerIRQ(wifimac_t *wifi, u8 irq)
void WIFI_triggerIRQMask(wifimac_t *wifi, u16 mask)
{
/* trigger an irq */
u16 irqBit = 1 << irq ;
if (wifi->IE.val & irqBit)
u16 oResult,nResult ;
oResult = wifi->IE.val & wifi->IF.val ;
wifi->IF.val = wifi->IF.val | (mask & ~0x0400) ;
nResult = wifi->IE.val & wifi->IF.val ;
if (!oResult && nResult)
{
wifi->IF.val |= irqBit ;
NDS_makeARM7Int(24) ; /* cascade it via arm7 wifi irq */
}
}
void WIFI_triggerIRQ(wifimac_t *wifi, u8 irq)
{
WIFI_triggerIRQMask(wifi,1<<irq) ;
}
void WIFI_Init(wifimac_t *wifi)
{
WIFI_resetRF(&wifi->RF) ;
@ -451,6 +457,7 @@ void WIFI_TXStart(wifimac_t *wifi,u8 slot)
void WIFI_write16(wifimac_t *wifi,u32 address, u16 val)
{
BOOL action = FALSE ;
if (!(MMU_read32(ARMCPU_ARM7,REG_PWRCNT) & 0x0002)) return ; /* access to wifi hardware was disabled */
if ((address & 0xFF800000) != 0x04800000) return ; /* error: the address does not describe a wiifi register */
/* the first 0x1000 bytes are mirrored at +0x1000,+0x2000,+0x3000,+06000,+0x7000 */
@ -461,7 +468,7 @@ void WIFI_write16(wifimac_t *wifi,u32 address, u16 val)
if (((address & 0x00007000) >= 0x00004000) && ((address & 0x00007000) < 0x00006000))
{
/* access to the circular buffer */
address &= 0x1FFFF ;
address &= 0x1FFF ;
wifi->circularBuffer[address >> 1] = val ;
return ;
}
@ -470,7 +477,16 @@ void WIFI_write16(wifimac_t *wifi,u32 address, u16 val)
address &= 0x00000FFF ;
switch (address)
{
case REG_WIFI_ID:
break ;
case REG_WIFI_MODE:
if (val & 0x4000)
{
/* does some resets */
wifi->RXRangeBegin = 0x4000 ;
/* this bit does not save */
val &= ~0x4000 ;
}
wifi->macMode = val ;
break ;
case REG_WIFI_WEP:
@ -492,10 +508,6 @@ void WIFI_write16(wifimac_t *wifi,u32 address, u16 val)
case REG_WIFI_BSS2:
wifi->bss.words[(address - REG_WIFI_BSS0) >> 1] = val ;
break ;
case REG_WIFI_AID: /* CHECKME: are those two really the same? */
case REG_WIFI_AIDCPY:
wifi->aid = val ;
break ;
case REG_WIFI_RETRYLIMIT:
wifi->retryLimit = val ;
break ;
@ -515,7 +527,7 @@ void WIFI_write16(wifimac_t *wifi,u32 address, u16 val)
}
break ;
case REG_WIFI_CIRCBUFRADR:
wifi->CircBufReadAddress = val ;
wifi->CircBufReadAddress = (val & 0x1FFE);
break ;
case REG_WIFI_RXREADCSR:
wifi->RXReadCursor = val ;
@ -530,15 +542,15 @@ void WIFI_write16(wifimac_t *wifi,u32 address, u16 val)
{
/* move to next hword */
wifi->CircBufWriteAddress+=2 ;
if (wifi->CircBufWriteAddress == wifi->CircBufEnd)
if (wifi->CircBufWriteAddress == wifi->CircBufWrEnd)
{
/* on end of buffer, add skip hwords to it */
wifi->CircBufEnd += wifi->CircBufSkip * 2 ;
wifi->CircBufWrEnd += wifi->CircBufWrSkip * 2 ;
}
}
break ;
case REG_WIFI_CIRCBUFWR_SKIP:
wifi->CircBufSkip = val ;
wifi->CircBufWrSkip = val ;
break ;
case REG_WIFI_BEACONTRANS:
wifi->BEACONSlot = val & 0x7FFF ;
@ -592,6 +604,33 @@ void WIFI_write16(wifimac_t *wifi,u32 address, u16 val)
case REG_WIFI_BBSIOWRITE:
WIFI_setBB_DATA(wifi,val) ;
break ;
case REG_WIFI_RXBUF_COUNT:
wifi->RXBufCount = val & 0x0FFF ;
break ;
case REG_WIFI_EXTRACOUNTCNT:
wifi->eCountEnable = (val & 0x0001) ;
break ;
case REG_WIFI_EXTRACOUNT:
wifi->eCount = val ;
break ;
case REG_WIFI_POWER_US:
wifi->crystalEnabled = !(val & 0x0001) ;
break ;
case REG_WIFI_IF_SET:
WIFI_triggerIRQMask(wifi,val) ;
break ;
case REG_WIFI_CIRCBUFRD_END:
wifi->CircBufRdEnd = (val & 0x1FFE) ;
break ;
case REG_WIFI_CIRCBUFRD_SKIP:
wifi->CircBufRdSkip = val & 0xFFF ;
break ;
case REG_WIFI_AID_LOW:
wifi->pid = val & 0x0F ;
break ;
case REG_WIFI_AID_HIGH:
wifi->aid = val & 0x07FF ;
break ;
default:
val = 0 ; /* not handled yet */
break ;
@ -601,6 +640,8 @@ void WIFI_write16(wifimac_t *wifi,u32 address, u16 val)
u16 WIFI_read16(wifimac_t *wifi,u32 address)
{
BOOL action = FALSE ;
u16 temp ;
if (!(MMU_read32(ARMCPU_ARM7,REG_PWRCNT) & 0x0002)) return 0 ; /* access to wifi hardware was disabled */
if ((address & 0xFF800000) != 0x04800000) return 0 ; /* error: the address does not describe a wiifi register */
/* the first 0x1000 bytes are mirrored at +0x1000,+0x2000,+0x3000,+06000,+0x7000 */
@ -618,6 +659,8 @@ u16 WIFI_read16(wifimac_t *wifi,u32 address)
address &= 0x00000FFF ;
switch (address)
{
case REG_WIFI_ID:
return WIFI_CHIPID ;
case REG_WIFI_MODE:
return wifi->macMode ;
case REG_WIFI_WEP:
@ -646,6 +689,55 @@ u16 WIFI_read16(wifimac_t *wifi,u32 address)
case REG_WIFI_BSS1:
case REG_WIFI_BSS2:
return wifi->bss.words[(address - REG_WIFI_BSS0) >> 1] ;
case REG_WIFI_RXRANGEBEGIN:
return wifi->RXRangeBegin ;
case REG_WIFI_CIRCBUFREAD:
temp = wifi->circularBuffer[((wifi->RXRangeBegin + wifi->CircBufReadAddress) >> 1) & 0x0FFF] ;
if (action)
{
wifi->CircBufReadAddress += 2 ;
wifi->CircBufReadAddress &= 0x1FFE ;
if (wifi->CircBufReadAddress + wifi->RXRangeBegin == wifi->RXRangeEnd)
{
wifi->CircBufReadAddress = 0 ;
} else
{
/* skip does not fire after a reset */
if (wifi->CircBufReadAddress == wifi->CircBufRdEnd)
{
wifi->CircBufReadAddress += wifi->CircBufRdSkip * 2 ;
wifi->CircBufReadAddress &= 0x1FFE ;
if (wifi->CircBufReadAddress + wifi->RXRangeBegin == wifi->RXRangeEnd) wifi->CircBufReadAddress = 0 ;
}
}
if (wifi->RXBufCount > 0)
{
if (wifi->RXBufCount == 1)
{
WIFI_triggerIRQ(wifi,9) ;
}
wifi->RXBufCount-- ;
}
}
return temp;
case REG_WIFI_CIRCBUFRADR:
return wifi->CircBufReadAddress ;
case REG_WIFI_RXBUF_COUNT:
return wifi->RXBufCount ;
case REG_WIFI_EXTRACOUNTCNT:
return wifi->eCountEnable?1:0 ;
case REG_WIFI_EXTRACOUNT:
return wifi->eCount ;
case REG_WIFI_POWER_US:
return wifi->crystalEnabled?0:1 ;
case REG_WIFI_CIRCBUFRD_END:
return wifi->CircBufRdEnd ;
case REG_WIFI_CIRCBUFRD_SKIP:
return wifi->CircBufRdSkip ;
case REG_WIFI_AID_LOW:
return wifi->pid ;
case REG_WIFI_AID_HIGH:
return wifi->aid ;
default:
return 0 ;
}
@ -656,9 +748,19 @@ void WIFI_usTrigger(wifimac_t *wifi)
{
u8 dataBuffer[0x2000] ;
u16 rcvSize ;
if (wifi->crystalEnabled)
{
/* a usec (=3F03 cycles) has passed */
if (wifi->usecEnable)
wifi->usec++ ;
if (wifi->eCountEnable)
{
if (wifi->eCount > 0)
{
wifi->eCount-- ;
}
}
}
if ((wifi->ucmpEnable) && (wifi->ucmp == wifi->usec))
{
WIFI_triggerIRQ(wifi,WIFI_IRQ_TIMEBEACON) ;

View File

@ -40,6 +40,7 @@
#define BASEPORT 7000 /* channel 1: 7000 ... channel 13: 7012 */
/* FIXME: make it configureable */
#define REG_WIFI_ID 0x000
#define REG_WIFI_MODE 0x004
#define REG_WIFI_WEP 0x006
#define REG_WIFI_IF 0x010
@ -50,10 +51,11 @@
#define REG_WIFI_BSS0 0x020
#define REG_WIFI_BSS1 0x022
#define REG_WIFI_BSS2 0x024
#define REG_WIFI_AID 0x028
#define REG_WIFI_AIDCPY 0x02A
#define REG_WIFI_AID_LOW 0x028
#define REG_WIFI_AID_HIGH 0x02A
#define REG_WIFI_RETRYLIMIT 0x02C
#define REG_WIFI_WEPCNT 0x032
#define REG_WIFI_POWER_US 0x036
#define REG_WIFI_POWERSTATE 0x03C
#define REG_WIFI_FORCEPS 0x040
#define REG_WIFI_RANDOM 0x044
@ -63,7 +65,10 @@
#define REG_WIFI_WRITECSRLATCH 0x056
#define REG_WIFI_CIRCBUFRADR 0x058
#define REG_WIFI_RXREADCSR 0x05A
#define REG_WIFI_RXBUF_COUNT 0x05C
#define REG_WIFI_CIRCBUFREAD 0x060
#define REG_WIFI_CIRCBUFRD_END 0x062
#define REG_WIFI_CIRCBUFRD_SKIP 0x064
#define REG_WIFI_CIRCBUFWADR 0x068
#define REG_WIFI_CIRCBUFWRITE 0x070
#define REG_WIFI_CIRCBUFWR_END 0x074
@ -81,6 +86,7 @@
#define REG_WIFI_RXFILTER 0x0D0
#define REG_WIFI_USCOUNTERCNT 0x0E8
#define REG_WIFI_USCOMPARECNT 0x0EA
#define REG_WIFI_EXTRACOUNTCNT 0x0EE
#define REG_WIFI_USCOMPARE0 0x0F0
#define REG_WIFI_USCOMPARE1 0x0F2
#define REG_WIFI_USCOMPARE2 0x0F4
@ -89,6 +95,7 @@
#define REG_WIFI_USCOUNTER1 0x0FA
#define REG_WIFI_USCOUNTER2 0x0FC
#define REG_WIFI_USCOUNTER3 0x0FE
#define REG_WIFI_EXTRACOUNT 0x118
#define REG_WIFI_BBSIOCNT 0x158
#define REG_WIFI_BBSIOWRITE 0x15A
#define REG_WIFI_BBSIOREAD 0x15C
@ -97,6 +104,11 @@
#define REG_WIFI_RFIODATA1 0x17E
#define REG_WIFI_RFIOBSY 0x180
#define REG_WIFI_RFIOCNT 0x184
#define REG_WIFI_IF_SET 0x21C
/* WIFI misc constants */
#define WIFI_CHIPID 0x1440 /* emulates "old" wifi chip, new is 0xC340 */
#define REG_PWRCNT 0x04000304
/* Referenced as RF_ in dswifi: rffilter_t */
/* based on the documentation for the RF2958 chip of RF Micro Devices */
@ -386,13 +398,17 @@ typedef struct
u8 bytes[6] ;
} bss ;
u16 aid ;
u16 pid ; /* player ID or aid_low */
u16 retryLimit ;
/* timing */
BOOL crystalEnabled ;
u64 usec ;
BOOL usecEnable ;
u64 ucmp ;
BOOL ucmpEnable ;
u16 eCount ;
BOOL eCountEnable ;
/* subchips */
rffilter_t RF ;
@ -411,10 +427,13 @@ typedef struct
u16 RXHWWriteCursor ;
u16 RXReadCursor ;
u16 RXUnits ;
u16 RXBufCount ;
u16 CircBufReadAddress ;
u16 CircBufWriteAddress ;
u16 CircBufEnd ;
u16 CircBufSkip ;
u16 CircBufRdEnd ;
u16 CircBufRdSkip ;
u16 CircBufWrEnd ;
u16 CircBufWrSkip ;
/* others */
u16 randomSeed ;