Already known (Groepaz's yet another psp documentation) :
Get/Set/Clear value bits on GPIO port :
--------------------------------------
0xBE240004 --> port_value_bits = _lw(0xBE240004);
the same thing can be achieved by using sceGpioPortRead();
NOTE: you must use sceGpio* counterparts because they "copy" what you do in hardware registers in memory too so bypassing those functions might throw you system into chaos.
0xBE240008 --> _sw(0xBE240008, _lw(0xBE240008) | 0x00000003); // set value bits 0 until 3 to one.
counterpart : sceGpioPortSet(0x00000003);
0xBE24000C --> _sw(0xBE240008, _lw(0xBE240008) | 0x00000003); // set value bits 0 until 3 to zero.
counterpart : sceGpioPortClear(0x00000003);
----------------------------
Not documented and not confirmed :
---
error sceGioSetPortMode(port_num, mode) :
- port_num to change mode
- mode : 0, 1 and 2 are only accepted modes.
I think mode might be something like :
- 0 : output
- 1 : input (pull-MOS off --> 0 would be read if pin not connected)
- 2 : input (pull-MOS on --> 1 would be read if pin not connected)
if so :
0xBE240000 --> a bit to 1 --> the corresponding GPIO pin is output else input.
0xBE240040 --> a bit to 1 --> the corresponding GPIO pin is input (pull-MOS on) else input (pull-MOS off). the same bit in 0xBE240000 needs to be 0 when using an input pin.
---
error sceGpioEnableIntr(intr_num) :
error sceGpioDisableIntr(intr_num) :
- intr_num : interrupt to raise according the intr mode
0xBE24001C --> a bit to 1 --> the corresponding GPIO pin may rise an interrupt according its intr mode.
---
error sceGpioSetIntrMode(intr_num, mode) :
- intr_num : interrupt to raise according the intr mode
- mode : 0, 1, 2, 3 and 4 are only accepted modes.
I think mode might be something like :
- 0 : high level-sensing mode ($s3, $s2, $s1) = (1, 1, 0)
- 1 : low level-sensing mode ($s3, $s2, $s1) = (1, 0, 1)
- 2 : rising edge detection mode ($s3, $s2, $s1) = (0, 1, 0)
- 3 : falling edge detection mode ($s3, $s2, $s1) = (0, 0, 1)
- 4 : rising/falling edge detection mode ($s3, $s2, $s1) = (0, 1, 1)
if so :
0xBE240010 --> a bit to 1 --> the corresponding GPIO pin raises a interrupt according a level-sensing mode else according a edge detection mode.
0xBE240014 --> a bit to 1 --> the corresponding GPIO pin raises a interrupt on high level/rising edge (or the inverse ?).
0xBE240018 --> a bit to 1 --> the corresponding GPIO pin raises a interrupt on low level/falling edge (or the inverse ?).
NOTE:
0xBE240048 : this function eternally probes the first two bits until they are both zero before setting bits in 0xBE24001x.
0xBE240024 : a bit to 1 --> probably clear the bit in 0xBE240020 if an interrupt has been raised for the corresponding GPIO pin. Acts as a reset/ an ack for irq.
---
bool sceGpioQueryIntr(intr_num)
- intr_num : interrupt to raise according the intr mode
0xBE240020 : a bit to 1 --> an interrupt has been raised for the corresponding GPIO pin
---
bool sceGpioQueryIntr(intr_num)
0xBE240020 : a bit to 1 --> an interrupt has been raised for the corresponding GPIO pin
0xBE240024 : a bit to 1 --> clear the bit in 0xBE240020 if an interrupt has been raised for the corresponding GPIO pin. Acts as a reset/ an ack for irq.
GPIO hardware registers
GPIO hardware registers
Last edited by hlide on Fri Apr 06, 2007 9:16 am, edited 4 times in total.
I realised I may be no clear about GPIO interrupts.
By GPIO interrupts it doesn't mean there is a IRQ for each GPIO interrupt (up to 32 i guess) but only one GPIO IRQ (#4). When calling the GPIO irq handler you probably need to read 0xBE240020 to know which GPIO interrupt occurs and acknowledge it with 0xBE240024. We know that GPIO IRQ (#4) can handle up to 32 subintr, so i wouldn't be surprised if a subintr num is associated with a GPIO interrupt.
By GPIO interrupts it doesn't mean there is a IRQ for each GPIO interrupt (up to 32 i guess) but only one GPIO IRQ (#4). When calling the GPIO irq handler you probably need to read 0xBE240020 to know which GPIO interrupt occurs and acknowledge it with 0xBE240024. We know that GPIO IRQ (#4) can handle up to 32 subintr, so i wouldn't be surprised if a subintr num is associated with a GPIO interrupt.
Nice findings :) I had also looked into it, but I should've posted the stuff I had found out earlier...
Well, for general interest:
All confirmed to work except irda (I was too lazy to try :P).
Well, for general interest:
Code: Select all
#define GPIO_PORT_HW_IRDA 2
#define GPIO_PORT_LED_MS 6
#define GPIO_PORT_LED_WLAN 7
#define GPIO_BITMASK_HW_IRDA (1<<GPIO_PORT_HW_IRDA)
#define GPIO_BITMASK_LED_MS (1<<GPIO_PORT_LED_MS)
#define GPIO_BITMASK_LED_WLAN (1<<GPIO_PORT_LED_WLAN)
//the bitmasks can be combined to set/clear many ports at once.
void sceGpioPortSet(int port_bitmask);
void sceGpioPortClear(int port_bitmask);
//mode=0 for W access on port.
void sceGpioSetPortMode(int port, int mode);
what does W access mean ? you mean an output pin ? that is value pin is the value you set with sceGpioSet/ClearPort() ?adrahil wrote://mode=0 for W access on port.
if so, it means i made a mistake :
oh yes it should be that :
0 -> (1, 0) -> output mode
1 -> (0, 1) -> input (pull-MOS on/off) // ON or OFF ?
2 -> (0, 0) -> input (pull-MOS off/on) // OFF or ON ?
explanation : according to mode, registers are set like that :
0 -> ($s4, $s3) = (1, 0)
1 -> ($s4, $s3) = (0, 1)
2 -> ($s4, $s3) = (0, 0)
and function gives us basically (not exactly like that but the ideat is same) :
_sw(0xBE240000, _lw(0xBE240000) & ~(1 << port_num) | ($s4 << port_num));
and
_sw(0xBE240040, _lw(0xBE240040) & ~(1 << port_num) | ($s3 << port_num));
so
0xBE240000 seems to deal with the corresponding port pin being output or input.
and 0xBE240040 seems to deal with the corresponding port pin being pull-MOS on or off when it is an input pin.
Last edited by hlide on Wed Jan 03, 2007 3:01 pm, edited 1 time in total.