Page 1 of 1

fifoSendValue32() got problem if MSB is not zero (?)

Posted: Thu Sep 10, 2009 2:39 pm
by sverx
Hi
I'm experiencing strange behavior with fifoSendValue32() function.
I'm using it for sending either a pointer to memory or a small value (0-255) over an user channel (FIFO_USER_07 in this case). I'm experiencing failures after (or on?) the 255th time I use that.

I checked the docs (and also the source) and I discovered that if the upper 8 bits of word aren't all zero then the function will work in a different way, I didn't know that... so I tried to change the way I send the pointer: now I mask it with 0x003FFFFF (the upper 8 bits will be 0 then) and I'll rebuild the pointer on the ARM7 side, adding 0x02000000 to it. This way it works perfectly.

Then I think there might be some problems with the fifoSendValue32() when used with some values but I didn't find the bug myself.

Ideas? I'm using latest libnds (1.3.7), of course.

(excuse my not perfect English...)

Re: fifoSendValue32() got problem if MSB is not zero (?)

Posted: Thu Sep 10, 2009 4:29 pm
by sverx
I'm running some more tests, I wrote a little demo program. It's here.

Each time you press A the value 0xFFFFFFFF will be sent to the ARM7 thru the FIFO_USER_07 channel and a dot will be printed on the console. If you run it in no$gba you'll see no errors (in the panel you can call with the F3 key) until the 128th dot (not the 255th as I wrote before...).

Or am I using the functions in a wrong way?

Thanks

Re: fifoSendValue32() got problem if MSB is not zero (?)

Posted: Fri Sep 11, 2009 10:05 am
by WinterMute
sverx wrote: I checked the docs (and also the source) and I discovered that if the upper 8 bits of word aren't all zero then the function will work in a different way, I didn't know that... so I tried to change the way I send the pointer: now I mask it with 0x003FFFFF (the upper 8 bits will be 0 then) and I'll rebuild the pointer on the ARM7 side, adding 0x02000000 to it. This way it works perfectly.
That's precisely what fifoSendAddress is for.

I'll have a look at the other problem though, it certainly shouldn't be doing that.

Re: fifoSendValue32() got problem if MSB is not zero (?)

Posted: Fri Sep 11, 2009 10:22 am
by sverx
WinterMute wrote:That's precisely what fifoSendAddress is for.
Yes, I know... it's that I wanted to send both pointers and single bytes through the same channel and I thought it would be a good idea to use the same function...
WinterMute wrote:I'll have a look at the other problem though, it certainly shouldn't be doing that.
Thanks! :)

Re: fifoSendValue32() got problem if MSB is not zero (?)

Posted: Thu Sep 24, 2009 12:30 pm
by WinterMute
Exactly what error are you getting? I can't seem to reproduce any issues with your test code here.

Re: fifoSendValue32() got problem if MSB is not zero (?)

Posted: Thu Sep 24, 2009 1:12 pm
by sverx
The test code is very simple so you don't get any visible effect of the problem with it, except that no$gba signals that something goes wrong when you send the 128th 0xFFFFFFFF word... thus demonstrating that 'something happens'.

In a 'real' application (an homebrew videogame actually in development) the error was that the memory somewhere gets corrupted when sending the 128th word (sorry I'm not able to provide more details about that) and the FIFO stopped working (which I believe also happens with the test code, but you can't see it...)

If you need I can link a little demo program that uses the FIFO to start/stop an XM module (playing on ARM7) and this shows that things start to go wrong the 128th time I send the word that makes the module start.

edit: a successful workaround is to mask the pointer with 0x003FFFFF so that the FIFO system would work in a different way, as you already know.

Re: fifoSendValue32() got problem if MSB is not zero (?)

Posted: Tue Sep 29, 2009 3:49 pm
by sverx
I'm giving a look at the libnds source, and I found a 'strange' line...

in fifoInternalRecvInterrupt() function, in the section affecting the 32bits values

Code: Select all

if(FIFO_IS_VALUE32(data)) {
there's this (the third one):

Code: Select all

if (FIFO_UNPACK_VALUE32_NEEDEXTRA(data)) {
  int next = FIFO_BUFFER_GETNEXT(block);
  if (next==FIFO_BUFFER_TERMINATE) break;
[...]
so, I'm asking myself, what happens if we receive a word which says that the value is in the next word (exactly the case where we're facing a bug) and we don't have it (yet?) in our queue? The function simply seems to go on, ignoring this. But that next word will -probably- arrive but unfortunately will be mis-decoded, as it's the 'data' word and not the 'header' word. Then I guess all this starts to fail.

Any comments on this?

Re: fifoSendValue32() got problem if MSB is not zero (?)

Posted: Wed Jan 06, 2010 1:10 am
by WinterMute
The 'header' word is left in the queue until the entire packet is received. Processing will always start with that word until the following word arrives.

Re: fifoSendValue32() got problem if MSB is not zero (?)

Posted: Tue Sep 28, 2010 1:01 am
by WinterMute
This is fixed in SVN now, turned out that the header word wasn't being returned to the free pool for those double word messages, oops. Should be in libnds 1.4.7 when I roll the release sometime in the next day or two.

http://devkitpro.svn.sourceforge.net/vi ... threv=4369