forums.ps2dev.org Forum Index forums.ps2dev.org
Homebrew PS2, PSP & PS3 Development Discussions
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

"official" SIO driver ?

 
Post new topic   Reply to topic    forums.ps2dev.org Forum Index -> PSP Development
View previous topic :: View next topic  
Author Message
jean



Joined: 05 Jan 2008
Posts: 489

PostPosted: Tue Feb 05, 2008 12:02 am    Post subject: "official" SIO driver ? Reply with quote

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:

// SIO driver by jean (giancarlotodone@yahoo.it)
// 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("sioDriver", 0x1006, 1, 1);
PSP_NO_CREATE_MAIN_THREAD();

// 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[255]; // 0..255 = 256 bytes

void fWrite(unsigned short int b){
   buf[w] = b;
   w++;
   if (w==r) r++; // CHECK THIS... "r++" should not be interrupted...consider about stopping ALL interrupts in intr handler
}

int fRead(){
   if (w==r) return -1;
   int b = buf[r];
   r++; // CHECK THIS... "r++" should not be interrupted...consider about stopping ALL interrupts in intr handler
   return b;
}

void resetFBuf(){
   // disable SIO interrupt...prevents resetFBuf() from being interrupted
   // by SIO events that would result in a data inconsistency.
   sceKernelDisableIntr(PSP_HPREMOTE_INT);
   w = 0;
   r = 0;
   sceKernelEnableIntr(PSP_HPREMOTE_INT); // re-enable interrupt
}

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

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);
}


void sioPutString(const char *data, int len){
   unsigned int k1 = pspSdkSetK1(0);

      int i;
      for(i = 0; i < len; i++)
      {
            sioPutchar(data[i]);
      }

   pspSdkSetK1(k1);
}

int sioGetChar(void){
   if(_lw(PSP_UART4_STAT) & PSP_UART_RXEMPTY)
   {   
         return -1;
   }

   return _lw(PSP_UART4_FIFO);
}

void sioSetBaud(int baud){ // no need to export this....always call sioInit()...

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

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

   _sw(div1, PSP_UART4_DIV1);
   _sw(div2, PSP_UART4_DIV2);
   _sw(0x60, PSP_UART4_CTRL); // ?? someone do it with 0x70
}

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

int intr_handler(void *arg)
{
   // 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();" (disable ALL intrs) to handle reader/writer conflicts

   sceKernelDisableIntr(PSP_HPREMOTE_INT);

   /* Read out the interrupt state and clear it */
   u32 stat = _lw(0xBE500040);
   _sw(stat, 0xBE500044);

   if(!(_lw(PSP_UART4_STAT) & PSP_UART_RXEMPTY)) {
      fWrite(_lw(PSP_UART4_FIFO));
      sceKernelSetEventFlag(sio_eventflag, SIO_CHAR_RECV_EVENT); // set "we got something!!" flag
   }

   sceKernelEnableIntr(PSP_HPREMOTE_INT); // re-enable interrupt
   // MAYBE i'm better use "pspSdkEnableInterrupts(intrs);"
   return -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);
}


int sioReadChar(void) // maybe a "char * sioReadString(int numberOfCharachtersToWaitFor)" could be useful as well
{
   unsigned int k1 = pspSdkSetK1(0);
   
        int ch;
        u32 result;
      SceUInt timeout;

        timeout = 1000000;
       
      ch = fRead();
       
      if(ch == -1)
        {
                sceKernelWaitEventFlag(sio_eventflag, SIO_CHAR_RECV_EVENT, PSP_EVENT_WAITOR|PSP_EVENT_WAITCLEAR, &result, &timeout); //

timeout could be null=forever
                ch = fRead();
        }
   pspSdkSetK1(k1);
        return ch;
}


// not used but required:
int module_start(SceSize args, void *argp)
{
        return 0;
}

int module_stop()
{
        return 0;
}


here's the export file (sioDriver.exp):
Code:

PSP_BEGIN_EXPORTS

PSP_EXPORT_START(syslib, 0, 0x8000)
PSP_EXPORT_FUNC_HASH(module_start)
PSP_EXPORT_VAR_HASH(module_info)
PSP_EXPORT_END

PSP_EXPORT_START(sioDriver, 0, 0x4001)
PSP_EXPORT_FUNC(sioInit)
PSP_EXPORT_FUNC(sioReadChar)
PSP_EXPORT_FUNC(sioPutString)
PSP_EXPORT_END

PSP_END_EXPORTS


here's the makefile:
Code:

TARGET = sioDriver
OBJS = main.o

INCDIR =
CFLAGS = -O2 -G0 -Wall -g
CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti
ASFLAGS = $(CFLAGS)

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=$(shell psp-config --pspsdk-path)
include $(PSPSDK)/lib/build.mak

all:
      psp-build-exports -s sioDriver.exp
      
clean:
      rm -f $(FINAL_TARGET) $(EXTRA_CLEAN) $(OBJS) $(PSP_EBOOT_SFO) $(PSP_EBOOT) $(EXTRA_TARGETS)
      rm -f *.S


jean


Last edited by jean on Thu Jul 17, 2008 6:14 pm; edited 4 times in total
Back to top
View user's profile Send private message
Art



Joined: 09 Nov 2005
Posts: 647

PostPosted: Tue Feb 05, 2008 8:42 am    Post subject: Reply with quote

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.
Back to top
View user's profile Send private message
jean



Joined: 05 Jan 2008
Posts: 489

PostPosted: Tue Feb 05, 2008 9:39 am    Post subject: Reply with quote

Oh, yes....we already discussed this: PSP _SHOULD_ have an hardware FIFO, but personally i was not capable of making it work...
Back to top
View user's profile Send private message
jube



Joined: 23 Oct 2007
Posts: 115

PostPosted: Thu Feb 07, 2008 2:58 pm    Post subject: Reply with quote

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!!!
Back to top
View user's profile Send private message
jean



Joined: 05 Jan 2008
Posts: 489

PostPosted: Thu Feb 07, 2008 9:20 pm    Post subject: Reply with quote

Quote:
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...
Back to top
View user's profile Send private message
jube



Joined: 23 Oct 2007
Posts: 115

PostPosted: Fri Feb 08, 2008 1:45 am    Post subject: Reply with quote

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 ).
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    forums.ps2dev.org Forum Index -> PSP Development All times are GMT + 10 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group