Thursday, May 14, 2009

A PICuliar problem!

Long long ago when I created this blog I had resolved to not post anything which relates to how much fight I put into getting Object X up and running if more than 80% of the world doesn't give a damn what Object X is. However the events of last night do deserve a mention somewhere, lest I ever forget them! (Although I am sure it wont happen.)

So we begin this tale of timeless tragedy at around 8 pm on the 13th of May 2009. For some god-forsaken reason I decided to get the HiTech C compiler for PIC16 running. (Don't ask why or what). Well things began on a rather promising note and in under 15 min I was able to blink a few LEDs. Enthused by this (seemingly) successful result I decided to get the UART interrupt running and Voila it refuses to work. Finally things were getting back to normal: codes not working and uCs refusing to do as they were told. However the real issue was that I had the (almost) same code up and running in assembly. All I had done was translate it to C.

Thus began the Herculean task of finding something to lay the blame on. So the first thing I did was to read the 2 codes again and conclude that they were indeed the same. After this the only logical thing was to turn to the panacea of 21th century problems - Google. Unfortunately over an hour of massaging different search queries couldn't get the required result. On a normal day this would be a warning sign that this isnt a real problem and I had messed up somewhere but unfortunately not yesterday.

It was then time to tinker around with the code, this was slighlty more helpful than googling and I figured out that the send portion of the code was working but the recieve interrupt was being called an infinite number of times. So far so good. Now I decided to read the datasheet once more. (Another half an hour down the drain) At this point for some god-forsaken reason I was sure it was the compiler's fault.

With great conviction and a little help from Kartik I found a disassembler for the 2 hex files.
(For those of you who have battled through all this nonsense and have understood the last line I can see the incredulous looks on your faces). Thus began the grand task of studying the 2 disassemblies. I dont know why but the HiTech C compiler puts this huge chunk of "start-up" code but after an hour of reading the disassembly I finally figured out what the "start-up" code did only to realise it was absolutely nothing. Then came the real code, this was much faster . In half an hour I realised the cause of this affliction. The assembly file I had the written used a btss somewhere but the C-code dissassembly used a btsc. (For the PIC16 instruction set uninitiated they are Bit Test Skip if Set and Bit Test Skip if Clear). As is obvious I had mistranslated the assembly and forgotten to put a not where it was deserved. Ofcourse if this were it the whole episode could have been excused but as most of you can conclude by now, there is more.

Well all the UART transmits worked perfectly but I was still getting infinite receive interrupts. However wisened by the events that had just transpired it was evident that it was mostly my own doing that stuff was not working. So another read of the codes was called for and yes once again the culprit was easily (ya right!) tracked down. In a hurry I had set the entire port with the LEDs as output. By a cruel twist of fate the UART was on the same port. So I made the receive pin of the UART an input and all was fine in wonderland. I am yet to check why the data direction of the UART pins matters, but maybe later.

So after aroung 6 hours of more or less pointless effort the UART which was happily working in assembly also works in C.

Whats the moral of the story you ask?
If you cant find the fault you are looking for on google and if it takes more than an hour of debugging to find an error it means YOU have made a mistake.