'========================================================================================
'
' Hardware Interface -- iap routines
'
' initialization code or #defines
'
'========================================================================================
#ifndef USE_IAP ' multiple include guard
#define USE_IAP
#include <ASMinlineBASIC.bas> ' needed for asm cmds below
#ifndef LPC11U37
#error This lib supports only the 11U37 at this time
#endif
' flag #defs
#ifndef _iap_DisplayResults
// #define _iap_DisplayResults ' uncomment to force seeing result dialog in E/BT console
#endif
' var dim size #defs
#define _iap_Cmd_MaxElements 5 ' see UM 20.14
#define _iap_Res_MaxElements 4
' iap API Code Entry Point
#define _iap_CEPtr &H1fff1ff1 ' The IAP routine resides at &H1FFF 1FF0 location and it is thumb code (+1)
' ram used by iap lib code
dim _iap_command(_iap_Cmd_MaxElements) as integer
dim _iap_result(_iap_Res_MaxElements) as integer
dim _iap_CmdPtr, _iap_ResPtr, _iap_results as integer
' iap results
#define _iap_Res_CMD_SUCCESS 0
#define _iap_Res_INVALID_COMMAND 1
#define _iap_Res_SRC_ADDR_ERROR 2
#define _iap_Res_DST_ADDR_ERROR 3
#define _iap_Res_SRC_ADDR_NOT_MAPPED 4
#define _iap_Res_DST_ADDR_NOT_MAPPED 5
#define _iap_Res_COUNT_ERROR 6
#define _iap_Res_INVALID_SECTOR 7
#define _iap_Res_SECTOR_NOT_BLANK 8
#define _iap_Res_SECTOR_NOT_PREPARED_FOR_WRITE_OPERATION 9
#define _iap_Res_COMPARE_ERROR 10
#define _iap_Res_BUSY 11
#define _iap_Res_BadEepromByteCount 14 ' undocumented - discovered by T&E
' iap commands
#define _iap_Cmd_SECTOR_PREPARE 50
#define _iap_Cmd_COPY_RAM2FLASH 51 ' program the flash memory - 16B chunks - SECTOR_PREPARE first.
#define _iap_Cmd_SECTOR_ERASE 52
#define _iap_Cmd_SECTOR_BLANK_CHECK 53
#define _iap_Cmd_READ_PART_ID 54
#define _iap_Cmd_READ_BOOT_CODE_VER 55
#define _iap_Cmd_COMPARE 56
#define _iap_Cmd_REINVOKE_ISP 57
#define _iap_Cmd_READ_UID 58
#define _iap_Cmd_PAGE_ERASE 59
#define _iap_Cmd_EEPROM_WRITE 61
#define _iap_Cmd_EEPROM_READ 62
' these 5 pp macros used for code readability in iap_execCmd proc
#define _iap_setCmdPtr _iap_CmdPtr = addressof _iap_command
'r0 to hold w0 of ascending command & param array - word aligned pointer
#define _iap_pushCmdPtr ASM_MOV(r0,r7)
#define _iap_setResPtr _iap_ResPtr = addressof _iap_result
'r1 to hold w0 of ascending status result array - word aligned pointer
#define _iap_pushResPtr ASM_MOV(r1,r7)
#define _iap_execCmd call (_iap_CEPtr)
' eeprom size #defs
#define _iap_eepromStart &H000
#define _iap_eepromEnd (&HFFF-64) ' 4K w/ top 64 bytes reserved
#define _iap_eepromSize (_iap_eepromEnd - _iap_eepromBegin)
' timing related #defs
#define _iap_extOscVal 12
#define _iap_cclkKhz 50000
function iap_execCmd()
_iap_setCmdPtr
_iap_pushCmdPtr
_iap_setResPtr
_iap_pushResPtr
_iap_execCmd
return _iap_result(0)
endfunction
#ifdef _iap_DisplayResults
sub iap_printVerboseResults()
print "IAP Result: ";
select _iap_result(0)
case _iap_Res_CMD_SUCCESS '0
print "_iap_Res_CMD_SUCCESS"
case _iap_Res_INVALID_COMMAND '1
print "_iap_Res_INVALID_COMMAND"
case _iap_Res_SRC_ADDR_ERROR '2
print "_iap_Res_SRC_ADDR_ERROR "
case _iap_Res_DST_ADDR_ERROR '3
print "_iap_Res_DST_ADDR_ERROR"
case _iap_Res_SRC_ADDR_NOT_MAPPED '4
print "_iap_Res_SRC_ADDR_NOT_MAPPED"
case _iap_Res_DST_ADDR_NOT_MAPPED '5
print "_iap_Res_DST_ADDR_NOT_MAPPED"
case _iap_Res_COUNT_ERROR '6
print "_iap_Res_COUNT_ERROR"
case _iap_Res_INVALID_SECTOR '7
print "_iap_Res_INVALID_SECTOR"
case _iap_Res_SECTOR_NOT_BLANK '8
print "_iap_Res_SECTOR_NOT_BLANK"
case _iap_Res_SECTOR_NOT_PREPARED_FOR_WRITE_OPERATION '9
print "_iap_Res_SECTOR_NOT_PREPARED_FOR_WRITE_OPERATION"
case _iap_Res_COMPARE_ERROR '10
print "_iap_Res_COMPARE_ERROR"
case _iap_Res_BUSY '11
print "_iap_Res_BUSY"
case _iap_Res_BadEepromByteCount '14
print "_iap_Res_BadEepromByteCount"
case else
print sprintf("... Unknown IAP Response code: %d",_iap_result(0))
endselect
endsub
#endif
sub iap_writeEEPROM(eepromStartAdr, size, memValPtr)
' as with all eeprom, write cycles limit cell life - don't write just to write - be judicious
_iap_command(0) = _iap_Cmd_EEPROM_WRITE ' EEPROM write IAP Command
_iap_command(1) = eepromStartAdr ' Param0: pointer to EEPROM address to write to
_iap_command(2) = memValPtr ' Param1: pointer to memory address with source data
_iap_command(3) = size ' Param2: Number of BYTES to be written
_iap_command(4) = _iap_cclkKhz ' Param3: System Clock Frequency (CCLK)
iap_execCmd
#ifdef _iap_DisplayResults
iap_printVerboseResults
#endif
endsub
sub iap_readEEPROM(eepromStartAdr, size, ramValPtr)
_iap_command(0) = _iap_Cmd_EEPROM_READ ' EEPROM write IAP Command
_iap_command(1) = eepromStartAdr ' Param0: Pointer to EEPROM address to read from
_iap_command(2) = ramValPtr ' Param1: pointer to RAM to fill with read data
_iap_command(3) = size ' Param2: Number of BYTES to be read/filled
_iap_command(4) = _iap_cclkKhz ' Param3: System Clock Frequency (CCLK)
iap_execCmd
#ifdef _iap_DisplayResults
iap_printVerboseResults
#endif
endsub
#endif // USE_IAP