How to change IrDA speed?
How to change IrDA speed?
Hi,
I'm the dev of PspIrda. It's an homebrew to transfer files between your PSP and devices compatible with the IrDA OBEX protocol (mobiles, pc, palm, PSP, ...) . You can try it here http://www.mediafire.com/?9meawtewtzm . It's a first release so the GUI is simplistic but it has a quite good compatibility (it works with most Nokia and siemens and I'm working to improve it).
The main problem is the speed. It's really slow as it uses the default IrDA speed : 9600bps. IrDA speed is negotiated between the 2 devices and in theory can go much higher, up to 115200bps.
I'm sure the PSP IrDA port can go up to this speed but I don't know why.
I've looked everywhere on the web before asking my question but I can't get an answer. So here it is : How can I configure the IrDA speed?
the answer is certainly some sort of ioctl but how exactly? Don't know.
ps2dev is full of talented dev so if you have any idea please tell me.
MaT
I'm the dev of PspIrda. It's an homebrew to transfer files between your PSP and devices compatible with the IrDA OBEX protocol (mobiles, pc, palm, PSP, ...) . You can try it here http://www.mediafire.com/?9meawtewtzm . It's a first release so the GUI is simplistic but it has a quite good compatibility (it works with most Nokia and siemens and I'm working to improve it).
The main problem is the speed. It's really slow as it uses the default IrDA speed : 9600bps. IrDA speed is negotiated between the 2 devices and in theory can go much higher, up to 115200bps.
I'm sure the PSP IrDA port can go up to this speed but I don't know why.
I've looked everywhere on the web before asking my question but I can't get an answer. So here it is : How can I configure the IrDA speed?
the answer is certainly some sort of ioctl but how exactly? Don't know.
ps2dev is full of talented dev so if you have any idea please tell me.
MaT
Well the PSP's IRDA is accessed through a UART so it might be possible to change the baud rate but only in kernel mode. You could try the following code:
However I have no idea if that will remotely work :)
Code: Select all
#define PSP_UART5_DIV1 0xBE540024
#define PSP_UART5_DIV2 0xBE540028
#define PSP_UART5_CTRL 0xBE54002C
#define PSP_UART_CLK 96000000
void pspIrdaSetBaud(int baud)
{
int div1, div2;
/* rate set using the rough formula div1 = (PSP_UART_CLK / baud) >> 6 and
* div2 = (PSP_UART_CLK / baud) & 0x3F
* The uart4 driver actually uses a slightly different formula for div 2 (it
* adds 32 before doing the AND, but it doesn't seem to make a difference
*/
div1 = PSP_UART_CLK / baud;
div2 = div1 & 0x3F;
div1 >>= 6;
_sw(div1, PSP_UART5_DIV1);
_sw(div2, PSP_UART5_DIV2);
_sw(0x60, PSP_UART5_CTRL);
}
Hi,
So I tried what you gave TyRaNiD but I have to say that It doesn't work :(
My PSP crashes when I call this function.
So, as I found in another forum thread, I added sceSysregUartIoEnable(5); at the begining of my code. This single line also crashes my PSP.
In your code you say that the IrDA port is on the UART5. I looked at every documentation I had and I found nothing that mentions this.
So my question are:
- Is really IrDA on the UART 5? Is really the base address 0xBE540000?
- Do you think this port act like a classic serial port?
- There is a irda.prx in the 3.02 firmware that is not in the 1.5? What does it mean?
My homebrew (PspIrDA) is mainly good, old C so I not really familiar with the specific PSP stuff (sce...). I'm a bit stuck rigth now.
MaT (Tryng to speak correctly English :)
So I tried what you gave TyRaNiD but I have to say that It doesn't work :(
My PSP crashes when I call this function.
So, as I found in another forum thread, I added sceSysregUartIoEnable(5); at the begining of my code. This single line also crashes my PSP.
In your code you say that the IrDA port is on the UART5. I looked at every documentation I had and I found nothing that mentions this.
So my question are:
- Is really IrDA on the UART 5? Is really the base address 0xBE540000?
- Do you think this port act like a classic serial port?
- There is a irda.prx in the 3.02 firmware that is not in the 1.5? What does it mean?
My homebrew (PspIrDA) is mainly good, old C so I not really familiar with the specific PSP stuff (sce...). I'm a bit stuck rigth now.
MaT (Tryng to speak correctly English :)
No my app was not running in kernel mode.TyRaNiD wrote:What crash do you get ? And are you running in kernel mode ? None of those bits and piece will work (they will crash) if you are not in kernel mode :)
I've just tried in kernel mode and it doesn't crash.
When I set the speed to 9600bps the app works normally but when I change the speed (19200bps for example) can't read what the phone send so something happen.
I have to investigate. It's a good start.
Thanks again
MaT
-
- Posts: 80
- Joined: Wed Feb 22, 2006 4:43 am
Checkout this thread: http://forums.ps2dev.org/viewtopic.php?t=5123
Its got code for talking directly to the serial port on the headphone jack. probably works the same, just change the base address.
Oh the code for changing the baud rate seems to be missing.
int serialport_setspeed(struct serialport * port, unsigned int baudrate) {
*(port->baudh) = (96000000 / baudrate) >> 6;
*(port->baudl) = (96000000 / baudrate) & 0x3f;
unsigned int x = *(port->control);
*(port->control) = x|0x00000006;
}
Its got code for talking directly to the serial port on the headphone jack. probably works the same, just change the base address.
Oh the code for changing the baud rate seems to be missing.
int serialport_setspeed(struct serialport * port, unsigned int baudrate) {
*(port->baudh) = (96000000 / baudrate) >> 6;
*(port->baudl) = (96000000 / baudrate) & 0x3f;
unsigned int x = *(port->control);
*(port->control) = x|0x00000006;
}
I've tried to write and read directly on the irda port by reading and writing at 0xBE540000 (quite the some code as in the sdk for sio) and it works.
But when I try to use this method in my app (PspIrDA), I can't respect the protocol timing . this problem does not appear with sceiowrite/read method.
Do you think there is some buffering that slow down the sending of data packet?
But when I try to use this method in my app (PspIrDA), I can't respect the protocol timing . this problem does not appear with sceiowrite/read method.
Do you think there is some buffering that slow down the sending of data packet?
Which cache? Data, instructions or some IO cache?gbj1 wrote:There is a kernel cache flush after sceIoWrite. Cache delay also happens if I use kprintf() to output something on the screen, but I'm not sure wether it would happen in your case.
Is it possible to know exactly which operations are done during a sceiowrite/read? Or can we avoid using cache for read/write operations?
Can this functions ...
sceKernelDcacheWBinvAll();
sceKernelIcacheClearAll();
sceKernelDcacheWritebackAll();
sceKernelIcacheInvalidateAll();
...be of any utility in my case?
Plain C is easy but you come to the hardware it's much more complicated.
Code: Select all
sceKernelDcacheWritebackAll();
If the data frames are generated immediately after a 'send(pBuf, len)' and there is a timer to raise the 'send' event inside the firmware, it is possible to find a way to flush the cache.
But if the stack was invoked by a timer to handle incoming/outcoming data and the timer is fixed on a 'sampling speed', I think you'd better have a patch on the firmware or just implement another irda protocol stack.
My understanding of your problem:
You can change the port baudrate manually by setting hardware registers, but there happen to be an built-in irda protocol stack in the _firmware. It seems that the stack is fixed on a specific baudrate and it's not flexable. So setting to higher baud-rate won't help, data blocks are generated to fit a 'slow rate'.
So you can receive something if you set the baudrate to 115,200, data were transmitted at 115,200 but it just comes slow, frame by frame, isn't it?
Please correct me if I misread your post.
My post was not very clear.gbj1 wrote:Please correct me if I misread your post.
PspIrDA implements an (almost) full IrDA stack (from IrObex to IrLap layer) that I have found on the web (BSD license) and that I have optimized for compatibility.
The problem is with the last layer of the protocol, IrPhy, the "physical" layer.
When I use sceiowrite/read calls to send and receive data it works perfectly because the irda port is configured by default at 9600bps which is also the default bitrate of the obex protocol.
But 9600bps is very slow so I want to increase the bitrate up to 115200bps. This is why I started this thread. I've looked through the code sio.c (UART4) and modified it to work with UART5 (IR).
By reading and writing directly at the address of the UART 5 FIFO, I can send and receive bytes via IR. BUT, this is were I'm stuck, writing seems to be buffered so the bytes are sent but too late and so the timing of the protocol (wait before emission/reception) are not respected and the other device stop the communication.
Is it clear? :)
So I'm need help to find:
- what is different between a "sceiowrite" and a "while(_lw(PSP_UART5_STAT) & PSP_UART_TXFULL); _sw(ch, PSP_UART5_FIFO);" ??? cache problem???
- why do I need to call sceioopen("irda0:", PSP_O_RDWR, 0); before writing/reading the UART 5 FIFO??? some magic initialization???
- if it could a problem of interrupt?
A lot of questions...
the most simple way to access a serial port: (fake codes)
while(!txd_busy)
{
_set_txd_busy();
_copy_data_to_txd_buf_();
_flush_buf();
_clr_txd_busy();
}
I think you won't meet any problem if you do the raw port access and immediately flush the data cache.
sceioopen() should initailize the processor register flags to enable uart interrupt as well as internal timer for the baudrate counter.
while(!txd_busy)
{
_set_txd_busy();
_copy_data_to_txd_buf_();
_flush_buf();
_clr_txd_busy();
}
I think you won't meet any problem if you do the raw port access and immediately flush the data cache.
sceioopen() should initailize the processor register flags to enable uart interrupt as well as internal timer for the baudrate counter.
-
- Posts: 328
- Joined: Sun Jun 03, 2007 10:05 pm