PSP SIO and Suspend

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

Moderators: cheriff, TyRaNiD

Post Reply
TokyoDriftPSP
Posts: 17
Joined: Fri Feb 20, 2009 10:33 pm

PSP SIO and Suspend

Post by TokyoDriftPSP »

Hey,
well, at the moment I'm messing with the PSP's serial port. It seems to be very usefull. Still I'm experiencing some problems. I tried using the pspDebugSio* calls but those don't seem to work for me. I can't read anything from the serial port. I am using a kernel mode plugin, but it won't give me any values from the serial port.
That's why I started using jean's SIO Driver (that seems to be TyRaNiD's driver from psplink + some ringbuffers). However, it works good for me, but as soon as I suspend the PSP and resume it sioPutChar doesn't work anymore.

Code: Select all

void sioPutchar(int ch){
   // as you see this is _blocking_...not an issue for
   // normal use as everithing doing I/O
   // should run in its own thread..in addition, HW FIFO isn't
   // working at all by now, so queue should not be that long :)
	while(_lw(PSP_UART4_STAT) & PSP_UART_TXFULL);
   _sw(ch, PSP_UART4_FIFO);
}
It seems like the UART_TXFULL flag is never being cleared. I already inserted a little delay in that while thing to enable threading stuff - otherwise the XMB doesn't even show up. However, sioReadChar seems to work after resuming the thread, at least I remember something like this (the hardware i use atm doesn't send anything as long as it's not polled, so I can't try it).
I just need to know how I have to re-initialize the SIO hardware. Can I just clear the flag on my own?
TD

EDIT: Clearing the flag doesn't work either.
TyRaNiD
Posts: 907
Joined: Sun Jan 18, 2004 12:23 am

Post by TyRaNiD »

have you tried completely reiniting the SIO (in psplink it was sioInit) and re-setting the baud rate. Cant remember if HPRM contains some suspend code which might reclaim the SIO port after resume.
TokyoDriftPSP
Posts: 17
Joined: Fri Feb 20, 2009 10:33 pm

Post by TokyoDriftPSP »

I did various attemps on that
I tried using the PowerCallback stuff

Code: Select all

#define POWER_CB_POWER      0x80000000
#define POWER_CB_HOLDON      0x40000000
#define POWER_CB_STANDBY   0x00080000
#define POWER_CB_RESCOMP   0x00040000
#define POWER_CB_RESUME      0x00020000
#define POWER_CB_SUSPEND   0x00010000
#define POWER_CB_EXT      0x00001000
#define POWER_CB_BATLOW      0x00000100
#define POWER_CB_BATTERY    0x00000080
#define POWER_CB_BATTPOWER   0x0000007F


int power_callback(int unknown, int pwrflags, void* args)
{
	if(pwrflags & POWER_CB_RESUME){
	    //re-init SIO
	}
    return 0;
}

// Thread to create the callbacks and then begin polling
int CallbackThread()
{
   int cbid;

   cbid = sceKernelCreateCallback("Power Callback", power_callback, NULL);
   scePowerRegisterCallback(0, cbid);

   sceKernelSleepThreadCB();
   return 0;
}


int SetupCallbacks(void)
{
   int thid = 0;

   thid = sceKernelCreateThread("update_thread", CallbackThread, 0x11, 0xFA0, 0, 0);
   if(thid >= 0)
   {
      sceKernelStartThread(thid, 0, 0);
   }

   return thid;
}
And I tried shutting down the main thread which does the init in the beginning (ExitDeleteThread) and restarting it using some kind of inverted-watchdog thread

Code: Select all

int wdt(){
	while(1){
	sceKernelDelayThread(1000000);
	if(getRunning() == 0){
		setRunning(1);
		int tid = sceKernelCreateThread("Lalala", main_thread, 0x18, 0x1000, 0, NULL);
		if(tid >= 0) sceKernelStartThread(tid, 0, NULL);
	}
	}
	return 0;
}
Both of them didn't work. I didn't try shutting down the SIO when powering off the PSP (like undoing everything sioInit does) yet, I'll do that later.
TD

EDIT: okay, tried it like that:

Code: Select all

void _sioInit(void)
{
   /* Shut down the remote driver */
   sceHprmEnd();
   /* Enable UART 4 */
   sceSysregUartIoEnable(4);
   /* Enable remote control power */
   sceSysconCtrlHRPower(1);
}


void sioInit(int baud){

   unsigned int k1 = pspSdkSetK1(0);

      _sioInit();

      sio_eventflag = sceKernelCreateEventFlag("SioShellEvent", 0, 0, 0);
                  
      sceKernelRegisterIntrHandler(PSP_HPREMOTE_INT, 1, intr_handler, NULL, NULL);
      sceKernelEnableIntr(PSP_HPREMOTE_INT);
      sceKernelDelayThread(2000000);
      sioSetBaud(baud);

   pspSdkSetK1(k1);
}


void sioShutdown(){
	unsigned int k1 = pspSdkSetK1(0);

	sceSysconCtrlHRPower(0);
	sceKernelDeleteEventFlag(sio_eventflag);
	sceKernelReleaseIntrHandler(PSP_HPREMOTE_INT);
	sceKernelDisableIntr(PSP_HPREMOTE_INT);

	pspSdkSetK1(k1);
}


int power_callback(int unknown, int pwrflags, void* args)
{
	if(pwrflags & POWER_CB_RESUME){
		sceKernelDelayThread(100000);
		sioInit(19200);
		install_syscon_hook();
		sceKernelResumeThread(getTHID());
	}
	if(pwrflags & POWER_CB_SUSPEND){
		sceKernelSuspendThread(getTHID());
		sioShutdown();
		uninstall_syscon_hook();
	}
    return 0;
}
doesn't work though
TD
Post Reply