ROMBuffer
These modules enable you to implement a simple ROM buffer which you can read and write to. The 18F series implement a ROM block write strategy, together with block erase. This can make writing to ROM quite tricky. The ROM module handles this for you and supports devices with 8 byte block writes and 64 byte erase blocks. You can set the size of the ROM buffer by adding more elements to ROMBuffer, which is located in the ROM table module (shown later).
The following program shows how it all works. Simply call BeginWrite() to initiate the write sequence, then call WriteByte() as many times as you need, up to a maximum ROMBufferSize - 1. ROMBufferSize is a ROM module public constant. Finally, call EndWrite() to terminate the write sequence.
You data will now be stored in device ROM, which can be accessed by calling ReadByte() with an index value. The index value should range from 0 to a maximum of ROMBufferSize - 1.
// import modules... Include "usart.bas" Include "convert.bas" Include "ROM.bas" // local variables... Dim Index, Value As Byte // write values to ROM... ROM.BeginWrite For Index = 0 To ROMBufferSize - 1 ROM.WriteByte(Index) Next ROM.EndWrite // read them back... SetBaudrate(br9600) For Index = 0 To ROMBufferSize - 1 Value = ROM.ReadByte(Index) Write("Value : ", DecToStr(Value),13,10) Next
ROM Module
Save this module in your UserLibrary folder and call it 'ROM.bas'...
Module ROM // import the ROM table... Include "ROMTable.bas" // public constants... Public Const ROMBufferSize = SizeOf(ROMBuffer) - 64 // some local aliases... Dim EEPGD As EECON1.7, WR As EECON1.1, WREN As EECON1.2 // local variables... Dim FROMAddress As Word, FBlockAddress As Word { **************************************************************************** * Name : Nop (PRIVATE) * * Purpose : Inline NOP delay * **************************************************************************** } Inline Sub Nop() ASM Nop End ASM End Sub { **************************************************************************** * Name : TableRead (PRIVATE) * * Purpose : Inline TABLE read * **************************************************************************** } Inline Sub TableRead() ASM TBLRD*+ End ASM End Sub { **************************************************************************** * Name : TableWrite (PRIVATE) * * Purpose : Inline TABLE write * **************************************************************************** } Inline Sub TableWrite() ASM TBLWT*+ End ASM End Sub { **************************************************************************** * Name : Erase (PRIVATE) * * Purpose : Erase a 64 byte ROM block * **************************************************************************** } Sub Erase() EECON1 = $94 EECON2 = $55 EECON2 = $AA WR = 1 Nop WREN = 0 End Sub { **************************************************************************** * Name : WriteToROM (PRIVATE) * * Purpose : Write holding register values to ROM * **************************************************************************** } Sub WriteToROM() EECON1 = $84 EECON2 = $55 EECON2 = $AA WR = 1 Nop WREN = 0 End Sub { **************************************************************************** * Name : ReadByte * * Purpose : Read a single byte from ROM at pIndex * **************************************************************************** } Public Function ReadByte(pIndex As Word) As TABLAT TABLEPTR = FROMAddress + pIndex EECON1 = 0 EEPGD = 1 TableRead End Function { **************************************************************************** * Name : WriteByte * * Purpose : Write a byte value to ROM * **************************************************************************** } Public Sub WriteByte(pValue As TABLAT) TableWrite If (TBLPTRL And $07) = 0 Then TABLEPTR = FBlockAddress WriteToROM Inc(FBlockAddress, 8) TABLEPTR = FBlockAddress EndIf End Sub { **************************************************************************** * Name : BeginWrite * * Purpose : Begin a write sequence to ROM * **************************************************************************** } Public Sub BeginWrite() Dim Range As Word Range = FROMAddress + ROMBufferSize TABLEPTR = FROMAddress While TABLEPTR < Range Erase Inc(TABLEPTR, 64) Wend TABLEPTR = FROMAddress FBlockAddress = FROMAddress End Sub { **************************************************************************** * Name : EndWrite * * Purpose : Terminate a write sequence to ROM * **************************************************************************** } Public Inline Sub EndWrite() WriteToROM End Sub { **************************************************************************** * Name : Initialise * * Purpose : Initialise ROM starting address, aligned to 64 byte boundary * **************************************************************************** } Sub Initialise() FROMAddress = (@ROMBuffer / 64 + 1) * 64 End Sub // initialise the module... Initialise
ROM Table Module
Save this module in your UserLibrary folder and call it 'ROMTable.bas'. Just add more zeros to the ROMBuffer sections marked with *** to increase the size of the buffer.
Module ROMTable // the ROM buffer... Public Const ROMBuffer() As Byte = ( // *** 256 bytes of available ROM... 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // *** end ROM table // last 64 bytes are pack bytes to ensure erase block falls on // a valid 64 byte boundary... 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 )