The penultimate week (yes its been 15 weeks already!) at work yielded some fruitful results as the bitstream was able to be read at an optimized speed and some of the older niggling CRC related issues were dealt with. This involved changing the design of how the SD card is used to store the bitstream and in fairness provides a better solution than changing the initialization function to turn the CRC on and off.

Fixing the Bitstream reading stack

As explained in the previous post. the main overhead for the bitstream reading stack was the functions being called repeatedly. So as advised by the supervisor, the main loop for reading the data and transmitting it through the UART was to be re-written in in-line assembly. To accomplish this, a new function was created called Aeste_PIC18_Optimized_SPI_Read_Packet().  This function is based on the existing optimized read function provided by the Microchip Libraries but is modified to read out a byte of data from the SD card and write it to the volatile UART transmission buffer “TXREG1”. The loop by default in the given Microchip function runs for 512 times, signifying the reading of a single sector every time. For initial testing purposes, this was not changed and the function was compiled into the code.

Replacing the reading loop to read out 512 bytes of data from the SD card and transmitting it through the UART, with the single optimized function seems to have done the trick. Initial testing shows that the reading was completed within 0.912s. This time was measured using one of the PIC’s internal timer.

Having made an ignorant mistake before, the next step was to check whether all the data is being read correctly or not. Using the debugger, the bytes were checked individually. The outcome was pleasant as all the bytes from the bitstream was being read correctly. Using the conditions applied in the code earlier, it was possible to also check the last sector of the SD card where partial bitstream data was also stored. The data is read by the previous functions as the sector is only partially full, and the rest of the data in the sector is a padding of random characters.

This implementation also contains the 4 dummy byte reads incorporated after the read for 1 sector is complete. The reading stack can finally be considered to be working appropriately as the target of reading the whole of the bitstream within a second was fulfilled. More minor modifications can be made to the in-line assembly part to improve the read performance.

Redesigning the Ping-Pong Upload

In the previous week, the FSInit function was modified to turn the CRC On or Off when it is required. Although it does solve the problem of having to input a customized CRC value for the small functions, like reading one sector or writing to one sector, it still does not solve the problem of having to calculate a custom CRC-16 value for writing to the MBR. Moreover, this makes the code inefficient and incompatible if the MBR contains different information than the one being used at the moment.

So, after suggestions from the supervisor, the Ping-Pong upload mechanism was slightly modified so that the MBR is not disturbed at all. Currently, the memory allocation on the first 1MB of the SD card’s raw sectors is like this:

Existing SD card memory allocation from Sector 0 to Sector 2048 (1MB)

Existing SD card memory allocation from Sector 0 to Sector 2048 (1MB)

The proposed changes is that instead of using the MBR to store the information for the Ping Pong Upload, a sector be reserved in the middle of the two Bitstream upload sections, which will contain only the information to be used for the Ping-Pong upload and the “AESTE” footprint. Thus the new  memory allocation on the first 1MB of the SD card’s raw sectors would look like this:

New SD card memory allocation from Sector 0 to Sector 2048 (1MB)

New SD card memory allocation from Sector 0 to Sector 2048 (1MB)

 These changes were fairly easy to implement. The functions that were used for the Ping-Pong upload mechanism were modified and a new function was written in place of the AesteEditMBR() called AesteStamp(). This function does basically takes in the Read & Write addresses from the Ping Pong mechanism and writes them into the ‘Information sector”. This function also adds the AESTE footprint to the last 5 bytes of the sector. This footprint now serves the purpose of conditioning the ‘Information sector’ with default Read & Write address values if the sector is being used for the first time. The modifications were applied and the following is a hexdump of the Information sector:

Info Sector Hex-Dump

Info Sector Hex-Dump

The familiar problems with CRC values reared up once again applying these modifications to the existing stack. This just consumed a lot of time to implement these changes. However, by the end of the week, the bugs were dealt with and the new Ping-Pong upload was operating properly.

Reducing the Flash Memory on the PIC

One of the ongoing objectives was to reduce the flash memory on the PIC for the firmware coding done. This was addressed this week as well by merging a few functions in the SD-SPI library that had been repeated during the design phase of the firmware. The merging was done using conditions to separate two different operations instead of calling two different functions. One of these functions was the MDD_SDSPI_AsyncRead() function. After the code space was reduced following more code cleanup, the Flash memory now read exactly 50% of the total flash memory available.

This week also saw the completion of internship training of Mostafa, a wonderful colleague and a good friend. Having spent most of the internship training with him, it was a fond farewell on his last day. Here’s wishing him all the best of luck in his endeavours and hoping that we’ll get the opportunity to work together again.