To answer question 1, there's a fixed location in the X data memory of all VS1010 versions, that holds 33 16-bit words of free memory that your applications can use, share, save and restore. It's declared as struct device_descriptor console for reasons that are no longer relevant, and any ROM version in use today doesn't need it for anything (its original function has been superseded by the abstract FILE consoleFile in VSOS4 of the VS1010). You're entirely free to use it for storing some application data in a fixed location, namely addresses 111..134 in X data memory, which turns out to be very convenient.
The easiest way to use that memory area is to declare an array or a struct in a fixed location using LINK_ABS linker directive:
Code: Select all
LINK_ABS(myAppSettings,111) extern u_int16 myAppSettings[sizeof(console)]; //33 words
Saving to flash
The second question is how to save and restore this information across power-off cycles. Saving it to a settings file in the SPI flash using fwrite is possible, but not recommended, because fwriting to the flash during device's normal operation is inherently unsafe and can cause catastrophic firmware corruption if the power is lost during FAT directory updates, for instance.
Instead, the method presented here uses a fixed location in the flash, outside the S: system disk, to save the data. This way the S: partition in the flash is not touched at all and there's very little chance of it being corrupted.
The SPI flash layout in VS1010 is quite simple. The first 64 kilobytes are reserved for booting and usually are not used at all in VS1010 products. The rest of the SPI flash is either empty or contains a FAT partition that can be used as the S: system disk or for general storage.
The VS1010 normally detects the SPI flash automatically and can access the FAT partition and boot directly from there. Boot records at the very beginning of the SPI flash are only needed if the SPI flash cannot be accessed using normal methods and a custom flash storage driver needs to be loaded into RAM before booting.
The VS1010 treats the first 64 kilobytes of the SPI flash as 128 sectors of 512 bytes each. Generally, the SPI flash can be erased in groups of 8 sectors or 4 kilobytes at a time. This software uses the last 4 kilobytes before the beginning of the FAT partition (sectors 120..127) to store the user's application settings.
Here's the function that saves the application settings from the console data area to the flash:
Code: Select all
LINK_ABS(myAppSettings,111) extern u_int16 myAppSettings[33];
ioresult SaveSettings (char *params) {
Disable();
Erase4K (&spiBus, 120); // Use 4K block at 60K..63K (sectors 120..127), FAT starts at 64K (physical sector 128)
Program4K(&spiBus, 120, myAppSettings); //Write application settings to flash.
Enable();
return S_OK;
}
Code: Select all
LINK_ABS(myAppSettings,111) extern u_int16 myAppSettings[33];
ioresult LoadSettings (char *params) {
u_int16 buf[256]; // allocate space for one sector buffer from stack
Disable();
BlockRead(&spiBus, 120, buf); //read one disk sector to buffer
memcpy (myAppSettings, buf, 33); //copy 33 words to the console data area
Enable();
}
For your convenience, I have written two programs, savesettings.dlx and loadsettings.dlx that you can use to save and load the area. Here's an example where the first word of the application settings, located in X memory addres 111 decimal, is first changed to 5, then saved, then changed to 8, then loaded, and finally checked that it's 5 again, after being read back from the flash.
Using the flash this way is as safe as it can be in a VS1010 product. The ROM functions which are used in this code are those functions that the ROM's SPI flash driver uses itself to handle the S: FAT device. The S: device itself is not used, only the SPI bus, and this can be important in some cases. While you could use the S: device to read and write the data by giving a negative sector number to S: disk's methods BlockRead and BlockWrite, any writing using those methods writes the data through X: addresses 0x3000..0x3fff, which are typically used by the MP3 decoder. This code doesn't need any extra memory for writing, which increases its applicability.VS1010>poke x:111,5
:0x006f: 0x0000->0x0005
VS1010>peek 111
0x006f X=0x0005 Y=0035
VS1010>savesettings
VS1010>poke x:111,8
:0x006f: 0x0005->0x0008
VS1010>peek 111
0x006f X=0x0008 Y=0008
VS1010>loadsettings
VS1010>peek 111
0x006f X=0x0005 Y=0069
VS1010>