sio interrupt handling on slim

Discuss the development of new homebrew software, tools and libraries.

Moderators: cheriff, TyRaNiD

Post Reply
deniska
Posts: 71
Joined: Mon Oct 17, 2005 1:38 pm
Location: New York

sio interrupt handling on slim

Post by deniska »

Hi,

I am having problems with interrupt handling for serial IO port.
Basically, the code (below) works fine in kernel mode on the phat. The sio reads work on the slim too, but they don't seem to wait for the interrupt/timeout and return right away, thus making a very tight loop.
I don't see any errors during the registering and enabling the handler.. so the whole thing is a bit puzzling..
Any suggestions are greatly appreciated!

Here is the main.c

Code: Select all

#include <pspkernel.h>
#include <pspdebug.h>
#include <pspdisplay.h>
#include <pspsdk.h>
#include <pspctrl.h>
#include <stdio.h>
#include <string.h>



PSP_MODULE_INFO&#40;"SIO_TESTER", 0, 1, 1&#41;;
PSP_MAIN_THREAD_ATTR&#40;PSP_THREAD_ATTR_USER&#41;;

//PSP_MODULE_INFO&#40;"SIO_TESTER", 0x1000, 1, 1&#41;;
//PSP_MAIN_THREAD_ATTR&#40;0&#41;;

int  sioReadChar&#40;&#41;;
void sioInit&#40;int,int&#41;;

int main&#40;void&#41;
&#123;
        int baud=38400;
        pspDebugScreenInit&#40;&#41;;
        pspDebugScreenPrintf&#40;"PSP GPSlim 236 test - Press X to exit\n"&#41;;
        pspDebugScreenPrintf&#40;"Press UP/DOWN to change baud\n"&#41;;
        sceDisplayWaitVblankStart&#40;&#41;;
        sceCtrlSetSamplingCycle&#40;0&#41;;
        sceCtrlSetSamplingMode&#40;PSP_CTRL_MODE_ANALOG&#41;;

         SceUID mod = pspSdkLoadStartModule&#40;"sioprx.prx", PSP_MEMORY_PARTITION_KERNEL&#41;;
    if &#40;mod < 0&#41;
    &#123;
        pspDebugScreenPrintf&#40;" Error 0x%08X loading/starting pspremoteprx.prx.\n", mod&#41;;
        sceKernelDelayThread&#40;3*1000*1000&#41;;
        sceKernelExitGame&#40;&#41;;
    &#125;


        sceKernelDelayThread&#40;1000000&#41;;
        pspDebugScreenPrintf&#40;"module loaded !!!\n"&#41;;
        sioInit&#40;baud,0&#41;;
        sceKernelDelayThread&#40;1000000&#41;;
        pspDebugScreenPrintf&#40;"INIT DONE!!!\n"&#41;;
        int thid = sceKernelGetThreadId&#40;&#41;;
        sceKernelChangeThreadPriority&#40;thid, 31&#41;;
        SceCtrlData pad;
        int ch=-1;
        while&#40;1&#41;
        &#123;

                sceCtrlPeekBufferPositive&#40;&pad, 1&#41;;
                if&#40;pad.Buttons & PSP_CTRL_SQUARE&#41; &#123;
                        sioInit&#40;baud,0&#41;;
                &#125;
                if&#40;pad.Buttons & PSP_CTRL_UP&#41; &#123;
                        baud*=2;
                        pspDebugScreenPrintf&#40;"setting baud to&#58; %d\n", baud&#41;;
                        sioInit&#40;baud,0&#41;;
                        sceKernelDelayThread&#40;500000&#41;;
                &#125; else
                if&#40;pad.Buttons & PSP_CTRL_DOWN&#41; &#123;
                        baud/=2;
                        pspDebugScreenPrintf&#40;"setting baud to&#58; %d\n", baud&#41;;
                        sioInit&#40;baud,0&#41;;
                        sceKernelDelayThread&#40;500000&#41;;
                &#125; else
                if&#40;pad.Buttons & PSP_CTRL_CROSS&#41;
                &#123;
                        break;
                &#125;
                ch = sioReadChar&#40;&#41;;
                if&#40;&#40;ch >= 0&#41; && &#40;ch != '\r'&#41;&#41;
                        pspDebugScreenPrintf&#40;"%c", ch&#41;;
                else
                        pspDebugScreenPrintf&#40;"."&#41;;

        &#125;

        sceKernelExitGame&#40;&#41;;
        return 0;
&#125;
Makefile:

Code: Select all

TARGET = pspgpslim236
OBJS = main.o sioprx.o


BUILD_PRX=1
PSP_FW_VERSION=371
INCDIR =
CFLAGS = -O2 -G0 -Wall
CXXFLAGS = $&#40;CFLAGS&#41; -fno-exceptions -fno-rtti
ASFLAGS = $&#40;CFLAGS&#41;

LIBDIR =
LDFLAGS =


EXTRA_TARGETS = EBOOT.PBP
PSP_EBOOT_TITLE = GPSlim236

PSPSDK=$&#40;shell psp-config --pspsdk-path&#41;
include $&#40;PSPSDK&#41;/lib/build.mak
main.c for kernel sio calls (greatly influenced by psplink code):

Code: Select all

#include <pspsdk.h>
#include <pspintrman_kernel.h>
#include <pspintrman.h>
#include <pspsyscon.h>

PSP_MODULE_INFO&#40;"sioprx", 0x1006, 1, 1&#41;;
PSP_MAIN_THREAD_ATTR&#40;0&#41;;

#define PSP_UART4_DIV1 0xBE500024
#define PSP_UART4_DIV2 0xBE500028
#define PSP_UART4_CTRL 0xBE50002C
#define PSP_UART_CLK   96000000
#define EVENT_SIO       0x01
int sceHprmEnd&#40;void&#41;;
int sceSysregUartIoEnable&#40;int uart&#41;;
int sceSyscon_driver_44439604&#40;int power&#41;;

static SceUID g_eventflag = -1;

void sioSetBaud&#40;int baud&#41;
&#123;
        int div1, div2;

        div1 = PSP_UART_CLK / baud;
        div2 = div1 & 0x3F;
        div1 >>= 6;

        _sw&#40;div1, PSP_UART4_DIV1&#41;;
        _sw&#40;div2, PSP_UART4_DIV2&#41;;
        _sw&#40;0x60, PSP_UART4_CTRL&#41;;
&#125;

void _sioInit&#40;void&#41;
&#123;
        sceHprmEnd&#40;&#41;;
        sceSysregUartIoEnable&#40;4&#41;;
        sceSysconCtrlHRPower&#40;1&#41;;
&#125;

int intr_handler&#40;void *arg&#41;
&#123;
        u32 stat;

        /* Read out the interrupt state and clear it */
        stat = _lw&#40;0xBE500040&#41;;
        _sw&#40;stat, 0xBE500044&#41;;

        sceKernelDisableIntr&#40;PSP_HPREMOTE_INT&#41;;

        sceKernelSetEventFlag&#40;g_eventflag, EVENT_SIO&#41;;

        return -1;
&#125;

void sioInit&#40;int baud, int kponly&#41;
&#123;
        _sioInit&#40;&#41;;
        if&#40;!kponly&#41;
        &#123;
                g_eventflag = sceKernelCreateEventFlag&#40;"SioShellEvent", 0, 0, 0&#41;;
                //void *func = &#40;void *&#41; &#40;&#40;unsigned int&#41; intr_handler | 0x80000000&#41;;
                void *func = &#40;void *&#41; &#40;&#40;unsigned int&#41; intr_handler&#41;;
                int st=sceKernelRegisterIntrHandler&#40;PSP_HPREMOTE_INT, 1, func, NULL, NULL&#41;;
                st=sceKernelEnableIntr&#40;PSP_HPREMOTE_INT&#41;;
                sceKernelDelayThread&#40;2000000&#41;;
        &#125;
        sioSetBaud&#40;baud&#41;;
&#125;


int sioReadChar&#40;void&#41;
&#123;
        int ch;
        u32 result;
         SceUInt timeout;

        timeout = 1000000;
        ch = pspDebugSioGetchar&#40;&#41;;
        if&#40;ch == -1&#41;
        &#123;
                sceKernelEnableIntr&#40;PSP_HPREMOTE_INT&#41;;
                sceKernelWaitEventFlag&#40;g_eventflag, EVENT_SIO, 0x21, &result, &timeout&#41;;

                ch = pspDebugSioGetchar&#40;&#41;;
        &#125;
        return ch;
&#125;

int module_start&#40;SceSize args, void *argp&#41;
&#123;
        return 0;
&#125;

int module_stop&#40;&#41;
&#123;
        return 0;
&#125;
sioprx.exp:

Code: Select all

PSP_BEGIN_EXPORTS

PSP_EXPORT_START&#40;syslib, 0, 0x8000&#41;
PSP_EXPORT_FUNC_HASH&#40;module_start&#41;
PSP_EXPORT_VAR_HASH&#40;module_info&#41;
PSP_EXPORT_END

PSP_EXPORT_START&#40;sioprx, 0, 0x4001&#41;
PSP_EXPORT_FUNC&#40;sioInit&#41;
PSP_EXPORT_FUNC&#40;sioReadChar&#41;
PSP_EXPORT_END

PSP_END_EXPORTS
makefile for the sioprx.prx:

Code: Select all

TARGET = sioprx
OBJS = main.o

INCDIR =
CFLAGS = -O2 -G0 -Wall -g
CXXFLAGS = $&#40;CFLAGS&#41; -fno-exceptions -fno-rtti
ASFLAGS = $&#40;CFLAGS&#41;

BUILD_PRX = 1
PRX_EXPORTS = sioprx.exp

USE_KERNEL_LIBC=1
USE_KERNEL_LIBS=1

LIBDIR =
LDFLAGS = -mno-crt0 -nostartfiles
LIBS = -lpspdebug  -lpspsdk    -lpsphprm_driver

PSPSDK=$&#40;shell psp-config --pspsdk-path&#41;
include $&#40;PSPSDK&#41;/lib/build.mak

all&#58;
        echo "$PSPSDK"
        psp-build-exports -s sioprx.exp
        cp *.S ../
        cp *.prx ../

clean&#58;
        rm -f $&#40;FINAL_TARGET&#41; $&#40;EXTRA_CLEAN&#41; $&#40;OBJS&#41; $&#40;PSP_EBOOT_SFO&#41; $&#40;PSP_EBOOT&#41; $&#40;EXTRA_TARGETS&#41;
        rm -f *.S
User avatar
dot_blank
Posts: 498
Joined: Wed Sep 28, 2005 8:47 am
Location: Brasil

Post by dot_blank »

heres your problem on slim
SceUID mod = pspSdkLoadStartModule("sioprx.prx", PSP_MEMORY_PARTITION_KERNEL); // dont do this in userland
10011011 00101010 11010111 10001001 10111010
deniska
Posts: 71
Joined: Mon Oct 17, 2005 1:38 pm
Location: New York

Post by deniska »

dot_blank wrote:heres your problem on slim
SceUID mod = pspSdkLoadStartModule("sioprx.prx", PSP_MEMORY_PARTITION_KERNEL); // dont do this in userland
I tired it with "PSP_MEMORY_PARTITION_USER" - it gave me same results :-(
Any other ideas?
User avatar
dot_blank
Posts: 498
Joined: Wed Sep 28, 2005 8:47 am
Location: Brasil

Post by dot_blank »

i ment do not do that in that same module
do the loadstart in the siokernelprx (which should be all kernel stuff)
10011011 00101010 11010111 10001001 10111010
J.F.
Posts: 2906
Joined: Sun Feb 22, 2004 11:41 am

Post by J.F. »

It needs to be kernel since you're messing with the hardware, but try setting k1 at the entry of the functions, and restoring it on exit.

Code: Select all

funct&#40;&#41;
&#123;
	unsigned int k1;

	k1 = pspSdkSetK1&#40;0&#41;;

	<stuff>

	pspSdkSetK1&#40;k1&#41;;
&#125;
User avatar
dot_blank
Posts: 498
Joined: Wed Sep 28, 2005 8:47 am
Location: Brasil

Post by dot_blank »

yea above is recommended as well as k1 crap is all over
the newer firmwares ...shitty sony
10011011 00101010 11010111 10001001 10111010
deniska
Posts: 71
Joined: Mon Oct 17, 2005 1:38 pm
Location: New York

Post by deniska »

dot_blank wrote:i ment do not do that in that same module
do the loadstart in the siokernelprx (which should be all kernel stuff)
dot_blank, I am a little confused: I already dumped all the kernel stuff in to a separate module: sioprx.prx. Are you saying that I need to create yet another one? If so, could you sketch a few lines of code or point me to a similar example?
thanks for fast replies!
User avatar
dot_blank
Posts: 498
Joined: Wed Sep 28, 2005 8:47 am
Location: Brasil

Post by dot_blank »

no you do not need to create another one
your call to SceUID mod = pspSdkLoadStartModule("sioprx.prx", PSP_MEMORY_PARTITION_KERNEL);
is trying to access kernel partition of memory while in a userthread
so move that module stuff and rest to your (already) existing siokernel.prx
10011011 00101010 11010111 10001001 10111010
deniska
Posts: 71
Joined: Mon Oct 17, 2005 1:38 pm
Location: New York

Post by deniska »

Setting the K1 fixed the problem.
Thanks a lot J.F. & dot_blank!
Post Reply