Hi all,
i would like to thank you all for all the support you give to me, because even if i'm programming on PSP since a year, this is my first post!
I'm developing a serious serial console as a starting point to create other apps SIO is involved in. The code (i will eventually post soon) is obviously inspired by tyranid's psplink and deniska's mapthis; currently the poll for received characters is done as-fast-as-we-can in a separate thread 'cause i learned -from you- i can't rely on built-in FIFO, and i don't experience data loss even at the higher baudrates; all hardware related functions are in a kernel prx and have the "k1 issue" already fixed.
I've already read all the posts discussing about the SIO problems, but i do need to have some concepts clarified:
-does somebody have fixed the built-in FIFO problem?? I'm currently wondering if i should implement by myself a software FIFO into an interrupt handler...
-what does the read of a character code >255 mean???? I'm reading a continuous stream of bytes out of SIO and everything goes right until a certain code is sent to the PSP that shows a "received 3200" instead of a good old 0-255 ASCII charachter...
I mean:
at standard baudrates (4800,9600,... ), no garbage is detected, BUT i'm trying to retrieve data from non-standard devices at non standard baudrates when all chars are correctly read except the last character of a sequence: the problem should not depend upon the unequality in baudrate between the device and the PSP since a tolerance of 1% is allowed(we're in, as div1 and div2 are still exactly integer at the required speed), and setting the PSP to relevantly higher or lower baudrates does not change the situation; problematic characters seem to be always the last characters of a rapid char sequence (i.e. unspaced serial sends).
Thanks in advance and please, forgive me for my ugly english!!
(oh, and a happy new coding year!!)
jean
Yet Another SIO Issue...
don't know if this can help...
I managed to investigate on the unexpected behaviour i've descripted in the last post; it sounds weird, but it seems to depend from HOW MUCH i use pspDebugScreenPrintf (i suspect that ANY more or less time consuming action would take to the same situation). In short, if i do
everything goes fine, while if i do
the last received charachter of a stream is garbage, >255 and not depending from what the charachter was supposed to be. Out of doubts, ch IS rubbish, it's not simply an stdio error. Quite obviously a synchronicity issue.
Any idea?
Code: Select all
ch = sioReadChar();
pspDebugScreenPrintf("%X",ch);
Code: Select all
ch = sioReadChar();
pspDebugScreenPrintf("received %X",ch);
Any idea?
Thank you for reply! I suppose my problem comes from many causes combined together...Anyway I workarounded it by implementing a circular FIFO buffer in the interrupt handler...so the reading loop is tight enough, and some logic is deferred to another thread... I'm sure that if i would have posted code to reproduce the problem, it would be clearer. I will, after a little more investigation and some code refactoring (it's a REAL mess by now...)
I am playing with the serial port again at the moment, I've had no need to use
speeds higher than 9600 with the PSP since I got one,
but I now see that I lied, and have received some garbage.
The garbage that I have received was not supposed to be any part of data
because I completely overcome it with "bullshit filter" :)
Probably due to a simple transistor inverter being prone to noise,
it was always in the absence of real data that the noise arrived.
Art.
speeds higher than 9600 with the PSP since I got one,
but I now see that I lied, and have received some garbage.
The garbage that I have received was not supposed to be any part of data
because I completely overcome it with "bullshit filter" :)
Code: Select all
// ******************************** serial routine stars here *********************************
while (1) {
if (sertime > 1) {bcp = 0;} // see the reference to this var in the comment below
cha = pspDebugSioGetchar();
sertime = 0; // Incremented by another thread. Once one byte is recieved
// I want to see the rest of the data within a short time.
if (cha > 0x0C ) { // bullshit filter
if (cha != 0x20 ) { //
barcode[bcp] = cha; // we assume the char is valid by now
bcp++; // increment data array pointer
if (cha == 0x0D) { // the serial port saw a return code
bcp--; // put her in reverse, and back up one byte
clocktimer = 0; // reset clock display timer
sceRtcGetCurrentClockLocalTime(&rtime); // get the time from the PSP real time clock
get_barcode(); //
search_barcode(); // go look up the database now
} // cha
} // cha
} // cha
if (clocktimer > 9990 ) { // looks like we have long inactivity
clocktimer = 0; // reset clock display (inactivity) timer
fancy_time(); // turn the display off, or show the time
}
}
}
// ********************************************************************************************
it was always in the absence of real data that the noise arrived.
Art.
If not actually, then potentially.
AHAH!!! Nice name for a fiter! Anyway, after some experimenting, i can say that this is not enough for me. I think my problem rely etirely on the odd behaviour of the built-in FIFO buffer. I CANNOT filter like you do, because at my baud rate the "bullshit" does corrupt the last data byte of a sequence. I also think the problem is not hardware, because catching data as-fast-as-you-can happily solve the problem.
Now, i get the whole thing working, BUT i really think that the built-in FIFO should be fixed.
If you want some practical info on my solution, read on:
1) code a small-weight handler
2) use "IF" constructs the less you can (replace if with function pointers, and boundary-checks with modulus, ecc...)
3) delegate the elaboration of data to another thread
PS: from preview i see code is not formatted nicely as i would...sorry
PPS: thank you anyway Art (are you coding something like "barcode battler" for psp or what??!)
jean
Now, i get the whole thing working, BUT i really think that the built-in FIFO should be fixed.
If you want some practical info on my solution, read on:
1) code a small-weight handler
2) use "IF" constructs the less you can (replace if with function pointers, and boundary-checks with modulus, ecc...)
3) delegate the elaboration of data to another thread
Code: Select all
// CIRCULAR FIFO FUNCTIONS-------------------------
// do not bother to get it mutex-ed and thread safe
// if only a reader and only a writer are required...
int w = 0;
int r = 0;
int bufLen = 100; // set this wider if you experience missing data
unsigned short int buf[100];
void fWrite(unsigned short int b){
buf[w] = b;
w = (w+1)%bufLen;
if (w==r) r = (r+1)%bufLen;
}
int fRead(){
if (w==r) return -1;
int b = buf[r];
r = (r+1)%bufLen;
return b;
}
// END CIRCULAR FIFO FUNCTIONS-------------------------
int intr_handler(void *arg)
{
// interrupt stuff here....
int ch = sioGetChar();
fWrite(ch); // put char into CIRCULAR FIFO buffer...
// set a flag...
}
int sioReadChar(void)
{
// handle k1 stuff ...
ch = fRead();
if(ch == -1)
{
// wait for flag and clear it
ch = fRead();
}
return ch;
}
// ---------on the user side:
int pollThread (SceSize args ,void * argp)
{
int ch = -1;
while(running()){
ch = sioReadChar();
if (ch>=0) {
doWatheverYouWant(ch);
}
sceKernelDelayThread(200); // hand over cpu-time
}
return 0;
}
PPS: thank you anyway Art (are you coding something like "barcode battler" for psp or what??!)
jean
Not exactly barcode battler, but in the same vein maybe
http://au.youtube.com/watch?v=ZO7HENwIvPs
http://au.youtube.com/watch?v=XD0hpn8xD4Q
As far as I know we can't use the FIFO at all with the homebrew toolchain.
It would appear to us as if there isn't one.. well at least as far as my experimentation would indicate.
Art.
http://au.youtube.com/watch?v=ZO7HENwIvPs
http://au.youtube.com/watch?v=XD0hpn8xD4Q
As far as I know we can't use the FIFO at all with the homebrew toolchain.
It would appear to us as if there isn't one.. well at least as far as my experimentation would indicate.
Art.
If not actually, then potentially.
Very nice! Anyway, the idea of a barcode battler "port"....think about it!!! :)
jean
That's all i needed to hear. Then the best solution is to reproduce it in software like i'm trying to do. How if we make an "official" SIO driver?? Mine is working pretty good by now...As far as I know we can't use the FIFO at all with the homebrew toolchain
jean