Work at SourceForge, help us to make it a better place! We have an immediate need for a Support Technician in our San Francisco or Denver office.
I'm trying to compile the keyboard demonstration code provided with the Atmel AT89C5131 development kit (available at http://www.atmel.com/dyn/resources/prod_documents/c5131-usb-kbd-stand-alone-1_0_1.zip\) and having some trouble. The code is originally designed for the Keil compiler, but I realized pretty quickly that the sfr and sbit instructions needed to be fixed in the register definition files. Thus, after a bit of tweaking, I'm no longer getting errors. However, the code appears simply not to run on the chip. Whereas the binary they provided works flawlessly, the one I create by any number of methods has been seemingly a dud.
-I've tried separately compiling all the c files into .rels (using sdcc -c X.c), then linking them with main.rel first(!) in the list (i.e. sdcc main.rel usb_task.rel modules\scheduler\scheduler.rel... etc.).
-I've tried both the default (model-small) and model-large.
-I've tried grouping the .rels into a .lib for the modules and compiling with sdcc main.c usb_task.rel usblib.lib modules.lib -Lusb -Lmodules.
-Just for kicks, I disabled the peep-hole optimizer, but I only got a larger file.
What's perplexing me further is if I load the hex file supplied with the demo code into a shoddy simulator I have for windows (ceibo), it runs perfectly fine forever, but if I load the sdcc-generated hex file, it ceases simulation when it reaches the bottom of the code (mind you, the simulator's poor enough not to tell me WHY it stopped - maybe end of code?).
I DID manage to get the small blurb of code that turns on an LED, (as mentioned in this thread: http://sourceforge.net/forum/forum.php?thread_id=1204985&forum_id=1864\) to compile and run successfully, and it displays the same problem in the simulator (i.e. it just stops when it reaches the bottom of the code), but then, this code IS final and has no looping.
Basically, I'm wondering a.) if I shouldn't be using either an IDE or Make, in which case I'll need a bit of help setting up either (or recommendations on free IDEs), or b.) what I'm doing wrong in compiling this demo code. Maybe order matters past simply the main function?
Thanks in advance!
One bit that has continued to concern me is in one of the files, I get:
usb_kbd_enum.c:218: warning: conditional flow changed by optimizer: so said EVELYN the modified DOG
My suspicion is that this should not matter, but it irks me every time I see it.
One question: Are there any Interrupt Service Routines (ISR) in there? If so then make sure you have their prototype copied in the main.c file.
Alright, prototyped the ISR and got some life out of the board (thanks!), but now I've run into another problem.
It seems somewhere midway through the enumeration process the chip encounters some trouble, and I get a message reporting a device malfunction from windows. I have a couple of guesses as to why this is happening, but given that the file that handles enumeration is the one reporting the optimization warning, I figured I'd check just in case.
In short, is there a reason to worry about that optimization warning, and/or is there a way to force SDCC to use conditionals instead of jump tables (regardless of how terribly inefficient it is)? I.e., what does that warning even mean?
Enumeration requires data transfer of integers bigger than one byte (f.e. VID and PID). Endianness is specified for that in the usb spec. The endianness of Keil is the opposite of SDCC's and therefor must be taken into account. Swap bytes where appropriate.
Alright! So, here's what's been going on:
Having changed all the bytes around to the proper order I still had no luck. After a bit more tinkering, no dice. So I threw the UART library into the project to give me some debug feedback, and I found out it was registering only default USB packets.
The reason this is interesting is because the only place that handles these packets was the switch statement I was recieving the EVELYN warning from. The only thing I CHANGED in order to make it function, was to change the switch from a switch on an SFR, to a switch on a variable set previously to the SFR. My guess is one of two things - either a.) the SFR had no type, so the compiler got confused, or b.) the compiler doesn't like switching on memory addresses.
If you'd like me to post the code precisely, let me know and I will - this seems like it might be a bug.
Thanks for all your help!
Usually, you get the Evelyn message when a variable is not declared volatile. Volatile is a note to the compiler (actually optimizer) that the variable can change value without program intervention, such as a hardware register. The optimizer will always try to remove loops on variables if there is no reference to the variable inside the loop. For instance, if you're waiting on the UART flag to change with a while(), but the bit in the SFR is not declared either with the SFR or SBIT macro, the optimizer will try to remove the loop because it doesn't know that the UART flag is volatile, i.e. can change itself.
> usb_kbd_enum.c:218: warning: conditional flow changed by optimizer: so said EVELYN the modified DOG
> My suspicion is that this should not matter, but it irks me every time I see it.
It most probably matters, for an explanation see:
(you'll find other references when searching the mailing list for EVELYN)
Do the contents of the SFR change automatically when you read it? How is the SFR declared? It might be a problem in it's volatileness (handling). Have you looked at the generated asm for this piece of code? If you do find a bug, feel free to report it in the bugs area. If so, please include as much as possible so we can reproduce the bug.
Yes, the contents of the SFR change when read, and the SFR is declared with the sfr macro, BUT the actual CALL to it is made through a #defined version.
I.e. the SFR is UDEPATX (Sfr UDEPATX at 0xCF), but the a call is defined using
#define Usb_read_byte() (UDEPATX)
and calls are made to it using switch (Usb_read_byte()), etc.
Anyway, I took a look at the assembly - it appears that there's a mov a,_UEPDATX for every cjne/jz, which I suspect means it's clearing out more and more of the SFR each time it tries to do the operation. I'm not sure how this situation would be better handled apart from dealing with it on the coder's point of view. I DID change the call around from using a define to just using the SFR with no effect.
Regardless, this does seem like a bug - if the SFR is declared using the sfr macro, it should be treated as volitile, and switch statements should assume potential instantaneous change, no? Even if a change on read isn't all that common?
A change on read is not uncommon in an 8051. And an sfr should be treated as volatile. So I guess you have found a bug. I'll create a bug report.
Alright, thanks :). It should be noted, though, that I AM using the 2.4.0 precomiled win32 binary, so it may already have been dealt with.
No, I checked and the problem still existed. But thanks to Erik Petrich it is fixed now.