ARM Evaluation Board Bricked?
The feature to remap pins of an ARM processor sounds cool. Ain’t it? But it can be bothersome at times, if you configure pins the wrong way.
The same happened with me which almost bricked my TI Stellaris LM3S811 Evaluation Board. I accidentally configured the JTAG pin, PC0, which was the TCK pin for the JTAG peripheral, to be a GPIO pin. I uploaded the code onto the board and it ran like a charm for my application. But unknowingly, I had done changes which would prevent me from uploading new code on the board. I had bricked it.
The LM3S811 Evaluation board uses a PC<->USB<->FT2232<->JTAG<->MCU interface. Which basically means, all upload and download of code onto the MCU is done through the JTAG interface. The code reconfigured the JTAG pin to be a GPIO, disabled the JTAG peripheral of the MCU and would not let me upload any code. Even after reset, the pin would lose its JTAG functionality whenever the command to remap would be executed. And this happened way too early in program execution(within microseconds) as the command was the fourth statement in my code. So yes, the computer interface was no longer valid.
What I Tried :-
- Knowing other ARM processors could be interfaced using an UART connection, I tried to do the same to upload new code on my device. But a drawback of Stellaris microcontrollers, or infact the Stellaris Bootloader is that it doesn’t allow you to upload code using UART once the bootloader is put on the device. If you want to use it, it needs to be specified in the startup_<compiler>.c file, which I hadn’t done. So I had no luck.
- The Stellaris Board has an onboard 20 pin JTAG connector. I installed OpenOCD to somehow do hardware debugging to stop the controller before it reconfigures the pin. Failed again. Reason being, first, the JTAG would use the the same TCK pin which I had reconfigured, and second, the most important, the JTAG connector on the Stellaris board is OUTPUT only. It can only be used to program or debug another device.
- Next I looked up the TI E2E Community (it is great!) for solutions. There I found a post discussing a similar problem. The person instructed to halt the microcontroller immediately after reset and then try. In all MCU, there is time gap between the reset button being pressed and code execution starting. It was a “hit and trial” method (worked in some cases) in which I would erase the flash memory immediately after reset. I tried doing this for almost four hours. But had no luck since the reconfiguration took place very early in my code.
- I decided to post my query on the TI E2E Community. I waited for a response for hours and after some discussion on the forum, was finally blessed with a solution, though not a complete one.
The Solution :-
In my code, the first statement selected the clock I wanted to use, the second initialized my display adapter, the third configured the pin PC5 and the fourth, and the one which should always be avoided, configured the pin PC0. The main motive was to halt program execution just before the reconfigure takes place. As instructed on the forum, if I could somehow stop the display initialization and come up with an error at that point, program execution would stop. But how to do it? The guy on the forum told me to pull out the display from the board
I didn’t do that. Learning how the display was connected to the the MCU, I figured out how it could be done. The display on the Stellaris Eval Board uses the I2C interface to communicate with the processor. I decided to pull the SCL or the clock pin of the I2C low and connected it to GND using a jumper. As there was no clock to the display, it wouldn’t initialize, and program execution would halt.
Job Well Done :-
I connected the modified board to my computer. Pressed reset, and Eureka! The program execution did stop before the pin could be reconfigured and I successfully uploaded the new code on the board.
Things I Learnt :-
- Use the ARM Pin mapping feature cautiously.
- Always add a delay before you set up the peripherals in your program code. Atleast 500ms. This might sound silly, but when you need to halt the controller, you can do it in that time or else nothing can be done.
- Specifically for all Stellaris microcontrollers, enable UART support in the startup_<compiler>.c file. You never know when you will need it.
- The TI E2E Community is far more helpful than the official TI support. The TI support replied to my problem three days after I posted it, it had been fixed by then. You will find some great people on the community.
- Never lose hope. It took me two days to finally make it work, again.