"official" SIO driver ?

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

Moderators: cheriff, TyRaNiD

Post Reply
User avatar
jean
Posts: 489
Joined: Sat Jan 05, 2008 2:44 am

"official" SIO driver ?

Post by jean »

Just because of all those people asking how to reinvent the wheel with SIO stuff, here's my sources for a sio driver PRX...they proved to

work very well even with high and non-standard baudrates notwithstanding they're so simple, in fact they do work with my MIDI hack. I post

this so a "standard" can be enstabilished...if you're gonna modify and improve this, let me and the community know so we can repack other

"official" versions...

to use it download zip, or copy'n'paste this
[[link removed]]

main.c:

Code: Select all

// SIO driver by jean ([email protected]) 
// based upon sources of Tyranid's pspLink
// and the advices from various forum.ps2dev.org
// users.
//
// Do whatever you want with this...if you want,
// give credit to the original authors, and put 
// your name in this list if you enhance it :)

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

PSP_MODULE_INFO&#40;"sioDriver", 0x1006, 1, 1&#41;;
PSP_NO_CREATE_MAIN_THREAD&#40;&#41;; 

// no changes here...the same good old consts
#define PSP_UART4_DIV1 0xBE500024
#define PSP_UART4_DIV2 0xBE500028
#define PSP_UART4_CTRL 0xBE50002C
#define PSP_UART_CLK   96000000
#define SIO_CHAR_RECV_EVENT  0x01

#define PSP_UART4_FIFO 0xBE500000
#define PSP_UART4_STAT 0xBE500018

#define PSP_UART_TXFULL  0x20
#define PSP_UART_RXEMPTY 0x10

static SceUID sio_eventflag = -1;


// CIRCULAR FIFO FUNCTIONS-------------------------
unsigned short int w = 0;
unsigned short int r = 0;
unsigned short int buf&#91;255&#93;; // 0..255 = 256 bytes

void fWrite&#40;unsigned short int b&#41;&#123;
	buf&#91;w&#93; = b;
	w++;
	if &#40;w==r&#41; r++; // CHECK THIS... "r++" should not be interrupted...consider about stopping ALL interrupts in intr handler
&#125;

int fRead&#40;&#41;&#123;
	if &#40;w==r&#41; return -1;
	int b = buf&#91;r&#93;;
	r++; // CHECK THIS... "r++" should not be interrupted...consider about stopping ALL interrupts in intr handler
	return b;
&#125;

void resetFBuf&#40;&#41;&#123;
	// disable SIO interrupt...prevents resetFBuf&#40;&#41; from being interrupted 
	// by SIO events that would result in a data inconsistency.
	sceKernelDisableIntr&#40;PSP_HPREMOTE_INT&#41;; 
	w = 0;
	r = 0;
	sceKernelEnableIntr&#40;PSP_HPREMOTE_INT&#41;; // re-enable interrupt
&#125;

// END CIRCULAR FIFO FUNCTIONS-------------------------

void sioPutchar&#40;int ch&#41;&#123;
	// 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 &#58;&#41;
	while&#40;_lw&#40;PSP_UART4_STAT&#41; & PSP_UART_TXFULL&#41;; 
	_sw&#40;ch, PSP_UART4_FIFO&#41;;
&#125;


void sioPutString&#40;const char *data, int len&#41;&#123;
	unsigned int k1 = pspSdkSetK1&#40;0&#41;;

		int i;
		for&#40;i = 0; i < len; i++&#41;
		&#123;
				sioPutchar&#40;data&#91;i&#93;&#41;;
		&#125;

	pspSdkSetK1&#40;k1&#41;;
&#125;

int sioGetChar&#40;void&#41;&#123;
	if&#40;_lw&#40;PSP_UART4_STAT&#41; & PSP_UART_RXEMPTY&#41;
	&#123;	
			return -1;
	&#125;

	return _lw&#40;PSP_UART4_FIFO&#41;;
&#125;

void sioSetBaud&#40;int baud&#41;&#123; // no need to export this....always call sioInit&#40;&#41;...

	int div1, div2; // low, high bits of divisor value

	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;; // ?? someone do it with 0x70
&#125;

void _sioInit&#40;void&#41;
&#123;
	/* Shut down the remote driver */
	sceHprmEnd&#40;&#41;;
	/* Enable UART 4 */
	sceSysregUartIoEnable&#40;4&#41;;
	/* Enable remote control power */
	sceSysconCtrlHRPower&#40;1&#41;;
&#125;

int intr_handler&#40;void *arg&#41;
&#123;
	// disable interrupt...we don't want SIO to call intr_handler again while it's already running
	// don't know if it's really needed here, but i remember this was a must in pc programming
	// MAYBE i'm better use "int intrs = pspSdkDisableInterrupts&#40;&#41;;" &#40;disable ALL intrs&#41; to handle reader/writer conflicts

	sceKernelDisableIntr&#40;PSP_HPREMOTE_INT&#41;; 

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

	if&#40;!&#40;_lw&#40;PSP_UART4_STAT&#41; & PSP_UART_RXEMPTY&#41;&#41; &#123;
		fWrite&#40;_lw&#40;PSP_UART4_FIFO&#41;&#41;;
		sceKernelSetEventFlag&#40;sio_eventflag, SIO_CHAR_RECV_EVENT&#41;; // set "we got something!!" flag
	&#125;

	sceKernelEnableIntr&#40;PSP_HPREMOTE_INT&#41;; // re-enable interrupt
	// MAYBE i'm better use "pspSdkEnableInterrupts&#40;intrs&#41;;"
	return -1; 
&#125;

void sioInit&#40;int baud&#41;&#123;

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

		_sioInit&#40;&#41;;

		sio_eventflag = sceKernelCreateEventFlag&#40;"SioShellEvent", 0, 0, 0&#41;;
	                
		sceKernelRegisterIntrHandler&#40;PSP_HPREMOTE_INT, 1, intr_handler, NULL, NULL&#41;;
		sceKernelEnableIntr&#40;PSP_HPREMOTE_INT&#41;;
		sceKernelDelayThread&#40;2000000&#41;;
		sioSetBaud&#40;baud&#41;;

	pspSdkSetK1&#40;k1&#41;; 
&#125;


int sioReadChar&#40;void&#41; // maybe a "char * sioReadString&#40;int numberOfCharachtersToWaitFor&#41;" could be useful as well
&#123;
	unsigned int k1 = pspSdkSetK1&#40;0&#41;;
    
        int ch;
        u32 result;
		SceUInt timeout;

        timeout = 1000000;
        
		ch = fRead&#40;&#41;;
        
		if&#40;ch == -1&#41; 
        &#123;
                sceKernelWaitEventFlag&#40;sio_eventflag, SIO_CHAR_RECV_EVENT, PSP_EVENT_WAITOR|PSP_EVENT_WAITCLEAR, &result, &timeout&#41;; // 

timeout could be null=forever
                ch = fRead&#40;&#41;;
        &#125;
	pspSdkSetK1&#40;k1&#41;; 
        return ch;
&#125;


// not used but required&#58;
int module_start&#40;SceSize args, void *argp&#41;
&#123;
        return 0;
&#125;

int module_stop&#40;&#41;
&#123;
        return 0;
&#125; 
here's the export file (sioDriver.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;sioDriver, 0, 0x4001&#41;
PSP_EXPORT_FUNC&#40;sioInit&#41;
PSP_EXPORT_FUNC&#40;sioReadChar&#41;
PSP_EXPORT_FUNC&#40;sioPutString&#41;
PSP_EXPORT_END

PSP_END_EXPORTS 
here's the makefile:

Code: Select all

TARGET = sioDriver
OBJS = main.o

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

BUILD_PRX = 1
PSP_FW_VERSION=371
PRX_EXPORTS = sioDriver.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;
		psp-build-exports -s sioDriver.exp
		
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 
jean
Last edited by jean on Thu Jul 17, 2008 6:14 pm, edited 4 times in total.
Art
Posts: 642
Joined: Wed Nov 09, 2005 8:01 am

Post by Art »

Thanks for posting.

You use a software FIFO buffer?
I think there is an on chip hardware FIFO,
or so you'd assume in a machine so up to date in every other area when it
came out, but I don't think it's ever been possible to use it (for us).
If not actually, then potentially.
User avatar
jean
Posts: 489
Joined: Sat Jan 05, 2008 2:44 am

Post by jean »

Oh, yes....we already discussed this: PSP _SHOULD_ have an hardware FIFO, but personally i was not capable of making it work...
jube
Posts: 115
Joined: Tue Oct 23, 2007 2:26 am

Post by jube »

Excellent!!!!

Thanks for your work mate, i am developing a thumb kbd and touch screen overlay to run through the sio, will use your driver and hopefully combine it with the pikey structure to get a working prototype, am developing specifically and only for cfw 3.80 m33_x ( hopefully for 3.90 etc as dax progresses ) And for the slim only, does the code run ok on the slim? Have a range of baud rates avail running from the micro-controller am using but since am muxing 2 serial data streams to the psp would like nice fast data rate, whats best you got out the sio without the fifo? And DAMN! we cant get to the fifo direct? bummer!!!
User avatar
jean
Posts: 489
Joined: Sat Jan 05, 2008 2:44 am

Post by jean »

does the code run ok on the slim?
I don't see any point for it wouldn't. Just be sure to set NIDs properly. For what concerns speed, I think it's trade-off with accuracy...as long as you have an integer 14bit divisor (see sioSetBaud()) your SIO should be running well...
jube
Posts: 115
Joined: Tue Oct 23, 2007 2:26 am

Post by jube »

Thank you :)
Will post finnished prototype curcuit and mico code when all working, in case you have'nt built youself one already ( and if your interested ), my prog skills need bit of sharpening!! so will take while to integrate to pikey, and have to wait till source available ( unofficial pikey 4 that is ).
Post Reply