It was an up and down week of sorts. It didn’t start off but as the week wore on and with some crucial help/advice from the supervisor and colleague, the desired task was achieved, although it is yet to see if it was the best solution to the problem at hand. One important aspect of problem solving that was picked up during the week was the fact that the objective must be clear to be able to solve any problems. During the week, it was made clear that I was spending too much time trying to understand everything rather than focus on just the objective and concentrate my efforts on that aspect. As for this week’s task, the objective was to find the size of the bitstream and correspondingly store this information about the bitstream on to the MBR of the SD card. The tricky part about this is that raw sectors are being used to write to the SD card, so the file system can’t be used to find the size of the bitstream. So, having given a lot of thought and time trying to understand the code for Multi Block Writing of raw sectors (the method being used to write the data), a simple counter method was used to derive the size of the bitstream as the sectors are being written.
The solution developed makes use of the way the raw sectors are written onto the SD card using Multi Block Writing method. Within the coding, a Block Counter which is initialized at 512 before the writing process starts. This 512 represents the number of bytes available on one sector. Once the write process is queued, the data packets are sent. For every byte written, the Block Counter is subtracted by 1. The block counter is reset to 512 once a sector is written completely. The sector counter uses this pre existing aspect in the source code to count the no. of sectors that are being written. Once the writing process is finished, the sector count variable should hold the number of sectors that were written in the whole write process. But what about the leftover bytes that are partially written in a sectors? After all, the bitstream is not likely to fill all the raw sectors exactly with 512 bytes. A secondary bytes counter come into play. The current source code also uses the block counter to fill the rest of the sector with null character when there are no more data packets waiting to be written. The bytes counter subtracts the value in the Block counter (the number of bytes that will be filled with null characters) from the total media size of 512 bytes. Thus the total size of the bitstream can be calculated by multiplying the number of sectors written by 512 and then adding it to the byte count.
The next challenge was to find a simple and easy way to store this new found information into the MBR of the SD card. In the previous work done on the SD cards, one of my colleagues created a modified FSCreateMBR function which he used to reserve 1MB of space for raw writing of the bitstream (https://blog.aeste.my/index.php/archives/2578). Therefore, it was an easy task to modify this function to accept the bitstream counter value as an argument and store it in the MBR as a variable. This function was then called right before the Multi Block Write command in the raw writing function returns the write complete status (ensuring that the size of the bitstream is updated every time a file is successfully uploaded to the SD card).
Testing the accuracy of the counter:
Some preliminary testing was done as the code was being developed using the GPIO LED’s on the development board to portray the 8-bit binary value of the different variables (Sector count, bytes count etc). However, since the total size of the bitstream would usually be a few hundred kilobytes, the total value of the bitstream would exceed the 8-bit GPIO LED’s. So the resident USART was planned to be used to communicate with the MCU and figure out whether the number of bytes counted was the same as the size of the bitstream. Unfortunately, this was not possible as the conversion from unsigned long to ASCII characters could not convert the values properly and the output onto the USART, viewed via Minicom could not provide reliable proof of the data. Thus, a more tedious method of still using the GPIO LED’s to display the values was used. The size of the bitsream could be displayed as a 16-bit binary number, so the display on the LED was split into two parts, the first displayed the first 8 bits of the number, and the second displayed the last 8 bits of the number, with a 500ms delay to tell them apart. This worked well and the counter was tested with files of varying sizes, ranging form 100kB to 400kB. The results were positive as the size of the file was accurate to the last byte, proving the method used to be effective. Further analysis to continue as well as a search for perhaps better methods.
Interesting findings about the USART
One interesting finding during the attempted use of the USART was that the whole program seemed to hang whenever the USART was being used at first. Upon performing appropriate breakdown of the code to find out which part exactly caused the problem, it was found that the program hanged while attempting to configure the USART for use (using the Open1USART function). The USART can’t be used effectively without proper configuration, particularly because of the Baud rate specifications for the MCU, more troubleshooting was done to find out what exactly caused the problem. It was found that the program hangs any time the Transmit Interrupt bit is configured to be ON. The most likely cause is that the SPI and the USART probably share a common pin that messes with eachother when the interrupt function is lefty on. So it was configured to be OFF, and the program no longer showed the same symptoms.
Configuring the C18 compiler for the project
Another important lesson learned this week was how important it is to configure the compiler to include the appropriate libraries and setting to be able to successfully compile the program. The following are the necessary settings that were implememented:
- Include Linker File(.lkr) associated with the project
- Provide Pre-Processor Macro Definition [CFG_INCLUDE_PICDN2_ETH97]
- Include Directories […/Microchip/Include]
- Memory Model :- Code Model [Large code model >64kB]
Data Model [Large data model AllRAM banks]
These setting allow for proper configurations of both the Ethernet and the SPI interface. After implementation of these configurations, the compilation of the project did not err.