typedefuint32_t UINT32;// other name for 32-bit integer
typedefuint64_t UINT64;
typedefunion _BYTE_VAL
{
BYTE Val;
struct
{
unsignedchar b0:1;
unsignedchar b1:1;
unsignedchar b2:1;
unsignedchar b3:1;
unsignedchar b4:1;
unsignedchar b5:1;
unsignedchar b6:1;
unsignedchar b7:1;
} bits;
} BYTE_VAL, BYTE_BITS;
typedefunion _WORD_VAL
{
WORD Val;
BYTE v[2];
struct
{
BYTE LB;
BYTE HB;
} byte;
struct
{
unsignedchar b0:1;
unsignedchar b1:1;
unsignedchar b2:1;
unsignedchar b3:1;
unsignedchar b4:1;
unsignedchar b5:1;
unsignedchar b6:1;
unsignedchar b7:1;
unsignedchar b8:1;
unsignedchar b9:1;
unsignedchar b10:1;
unsignedchar b11:1;
unsignedchar b12:1;
unsignedchar b13:1;
unsignedchar b14:1;
unsignedchar b15:1;
} bits;
} WORD_VAL, WORD_BITS;
typedefunion _DWORD_VAL
{
DWORD Val;
WORD w[2];
BYTE v[4];
struct
{
WORD LW;
WORD HW;
} word;
struct
{
BYTE LB;
BYTE HB;
BYTE UB;
BYTE MB;
} byte;
struct
{
WORD_VAL low;
WORD_VAL high;
}wordUnion;
struct
{
unsignedchar b0:1;
unsignedchar b1:1;
unsignedchar b2:1;
unsignedchar b3:1;
unsignedchar b4:1;
unsignedchar b5:1;
unsignedchar b6:1;
unsignedchar b7:1;
unsignedchar b8:1;
unsignedchar b9:1;
unsignedchar b10:1;
unsignedchar b11:1;
unsignedchar b12:1;
unsignedchar b13:1;
unsignedchar b14:1;
unsignedchar b15:1;
unsignedchar b16:1;
unsignedchar b17:1;
unsignedchar b18:1;
unsignedchar b19:1;
unsignedchar b20:1;
unsignedchar b21:1;
unsignedchar b22:1;
unsignedchar b23:1;
unsignedchar b24:1;
unsignedchar b25:1;
unsignedchar b26:1;
unsignedchar b27:1;
unsignedchar b28:1;
unsignedchar b29:1;
unsignedchar b30:1;
unsignedchar b31:1;
} bits;
} DWORD_VAL;
#define LSB(a) ((a).v[0])
#define MSB(a) ((a).v[1])
#define LOWER_LSB(a) ((a).v[0])
#define LOWER_MSB(a) ((a).v[1])
#define UPPER_LSB(a) ((a).v[2])
#define UPPER_MSB(a) ((a).v[3])
typedefunion _QWORD_VAL
{
QWORD Val;
DWORD d[2];
WORD w[4];
BYTE v[8];
struct
{
DWORD LD;
DWORD HD;
} dword;
struct
{
WORD LW;
WORD HW;
WORD UW;
WORD MW;
} word;
struct
{
unsignedchar b0:1;
unsignedchar b1:1;
unsignedchar b2:1;
unsignedchar b3:1;
unsignedchar b4:1;
unsignedchar b5:1;
unsignedchar b6:1;
unsignedchar b7:1;
unsignedchar b8:1;
unsignedchar b9:1;
unsignedchar b10:1;
unsignedchar b11:1;
unsignedchar b12:1;
unsignedchar b13:1;
unsignedchar b14:1;
unsignedchar b15:1;
unsignedchar b16:1;
unsignedchar b17:1;
unsignedchar b18:1;
unsignedchar b19:1;
unsignedchar b20:1;
unsignedchar b21:1;
unsignedchar b22:1;
unsignedchar b23:1;
unsignedchar b24:1;
unsignedchar b25:1;
unsignedchar b26:1;
unsignedchar b27:1;
unsignedchar b28:1;
unsignedchar b29:1;
unsignedchar b30:1;
unsignedchar b31:1;
unsignedchar b32:1;
unsignedchar b33:1;
unsignedchar b34:1;
unsignedchar b35:1;
unsignedchar b36:1;
unsignedchar b37:1;
unsignedchar b38:1;
unsignedchar b39:1;
unsignedchar b40:1;
unsignedchar b41:1;
unsignedchar b42:1;
unsignedchar b43:1;
unsignedchar b44:1;
unsignedchar b45:1;
unsignedchar b46:1;
unsignedchar b47:1;
unsignedchar b48:1;
unsignedchar b49:1;
unsignedchar b50:1;
unsignedchar b51:1;
unsignedchar b52:1;
unsignedchar b53:1;
unsignedchar b54:1;
unsignedchar b55:1;
unsignedchar b56:1;
unsignedchar b57:1;
unsignedchar b58:1;
unsignedchar b59:1;
unsignedchar b60:1;
unsignedchar b61:1;
unsignedchar b62:1;
unsignedchar b63:1;
} bits;
} QWORD_VAL;
// Section defining the address range to erase for the erase device command, along with the valid programming range to be reported by the QUERY_DEVICE command.
#define VectorsStart 0x00000000
// One page of vectors + general purpose program memory.
// Bootloader resides in memory range 0x400-0x17FF
#define VectorsEnd 0x00000400
// Beginning of application program memory (not occupied by bootloader). **THIS VALUE MUST BE ALIGNED WITH BLOCK BOUNDRY** Also, in order to work correctly, make sure the StartPageToErase is set to erase this section.
#define ProgramMemStart 0x00001400
//64KB variants (PIC24FJ64GB004)
// Bootloader and vectors occupy first six 1024 word (1536 bytes due to 25% unimplemented bytes) pages
#define BeginPageToErase 5
//Last full page of flash on the PIC24FJ256GB110, which does not contain the flash configuration words.
#define MaxPageToEraseNoConfigs 41
//Page 170 contains the flash configurations words on the PIC24FJ256GB110. Page 170 is also smaller than the rest of the (1536 byte) pages.
#define MaxPageToEraseWithConfigs 42
//Must be instruction word aligned address. This address does not get updated, but the one just below it does:
//IE: If AddressToStopPopulating = 0x200, 0x1FF is the last programmed address (0x200 not programmed)
#define ProgramMemStopNoConfigs 0x0000A800
//Must be instruction word aligned address. This address does not get updated, but the one just below it does: IE: If AddressToStopPopulating = 0x200, 0x1FF is the last programmed address (0x200 not programmed)
#define ProgramMemStopWithConfigs 0x0000ABF8
//0x2ABFA is start of CW3 on PIC24FJ256GB110 Family devices
#define ConfigWordsStartAddress 0x0000ABF8
#define ConfigWordsStopAddress 0x0000AC00
//Switch State Variable Choices
#define QUERY_DEVICE 0x02 //Command that the host uses to learn about the device (what regions can be programmed, and what type of memory is the region)
#define UNLOCK_CONFIG 0x03 //Note, this command is used for both locking and unlocking the config bits (see the "//Unlock Configs Command Definitions" below)
#define ERASE_DEVICE 0x04 //Host sends this command to start an erase operation. Firmware controls which pages should be erased.
#define PROGRAM_DEVICE 0x05 //If host is going to send a full RequestDataBlockSize to be programmed, it uses this command.
#define PROGRAM_COMPLETE 0x06 //If host send less than a RequestDataBlockSize to be programmed, or if it wished to program whatever was left in the buffer, it uses this command.
#define GET_DATA 0x07 //The host sends this command in order to read out memory from the device. Used during verify (and read/export hex operations)
#define RESET_DEVICE 0x08 //Resets the microcontroller, so it can update the config bits (if they were programmed, and so as to leave the bootloader (and potentially go back into the main application)
//Unlock Configs Command Definitions
#define UNLOCKCONFIG 0x00 //Sub-command for the ERASE_DEVICE command
#define LOCKCONFIG 0x01 //Sub-command for the ERASE_DEVICE command
//Query Device Response "Types"
#define TypeProgramMemory 0x01 //When the host sends a QUERY_DEVICE command, need to respond by populating a list of valid memory regions that exist in the device (and should be programmed)
#define TypeEEPROM 0x02
#define TypeConfigWords 0x03
#define TypeEndOfTypeList 0xFF //Sort of serves as a "null terminator" like number, which denotes the end of the memory region list has been reached.
//BootState Variable States
#define IdleState 0x00
#define NotIdleState 0x01
//OtherConstants
#define InvalidAddress 0xFFFFFFFF
//Application and Microcontroller constants
#define BytesPerFlashAddress 0x02 //For Flash memory: One byte per address on PIC18, two bytes per address on PIC24
#define TotalPacketSize 0x40
#define WORDSIZE 0x02 //PIC18 uses 2 byte instruction words, PIC24 uses 3 byte "instruction words" (which take 2 addresses, since each address is for a 16 bit word; the upper word contains a "phantom" byte which is unimplemented.).
//#define FlashBlockSize 0x40 //For PIC18F87J50 family devices, a flash block is 64 bytes
#define RequestDataBlockSize 56 //Number of bytes in the "Data" field of a standard request to/from the PC. Must be an even number from 2 to 56.
#define BufferSize 0x20 //32 16-bit words of buffer