INL-retro-progdump/host/scripts/app/swim.lua

348 lines
11 KiB
Lua

-- create the module's table
local swim = {}
-- import required modules
local dict = require "scripts.app.dict"
--local buffers = require "scripts.app.buffers"
-- file constants
-- firmware assembly return error code definitions
--.equ NO_RESP, 0xFF device didn't appear to respond
--.equ ACK, 0x01 transfer successful
--.equ NAK, 0x00 device couldn't complete operation
--.equ HERR, 0x0E header error
--.equ PERR, 0x09 pairity error
local ECODE = {}
ECODE.NORESP = 0xFF
ECODE.ACK = 0x01
ECODE.NAK = 0x00
ECODE.PERR = 0x0E
ECODE.HERR = 0x09
--local NRESP = 0xFF
--local ACK = 0x01
--local NAK = 0x00
--local PERR = 0x0E
--local HERR = 0x09
local cur_CSR = 0x00
local SWIM_CSR = 0x7F80
-- local functions
local function get_key_for_value( t, value )
for k,v in pairs(t) do
if v==value then
return k
end
end
return nil
end
local function stm8_system_reset()
--if cur_CSR has bit 2 set, SWIM must be reactivated
end
local function reset_swim()
print("resetting SWIM")
dict.swim("SWIM_RESET")
-- wotf(SWIM_CSR, cur_CSR)
--must rewrite current value of SWIM_CSR register as HIGHSPEED is cleared during SWIM RESET
dict.swim("WOTF", SWIM_CSR, cur_CSR)
end
local function rotf(addr, hspeed, num)
local result = ECODE.NAK
local data
local tries = 5
local resets = 3
local opcode = "ROTF"
if hspeed then
opcode = "ROTF_HS"
end
while result ~= "ACK" and tries > 0 do
result, data = dict.swim(opcode, addr)
--convert the value to the key string
result = get_key_for_value( ECODE, result)
print("rotf", string.format(" %X: %X, result ", addr, data), result)
if result == "NORESP" then
reset_swim()
end
tries = tries - 1
if tries == 0 then
print("ERROR max tries exceeded")
reset_swim()
resets = resets - 1
if resets > 0 then
tries = 5
end
end
end
end
local function wotf(addr, data, hspeed, num)
local result = ECODE.NAK
local tries = 5
local resets = 3
local opcode = "WOTF"
if hspeed then
opcode = "WOTF_HS"
end
while result ~= "ACK" and tries > 0 do
result = dict.swim(opcode, addr, data)
result = get_key_for_value( ECODE, result)
print("wotf", string.format(" %X: %X, result ", addr, data), result)
tries = tries - 1
if result == "NORESP" then
reset_swim()
end
if tries == 0 then
print("ERROR max tries exceeded")
reset_swim()
resets = resets - 1
if resets > 0 then
tries = 5
end
end
end
end
local function start()
dict.io("IO_RESET")
dict.io("SNES_INIT")
dict.io("SWIM_INIT", "SWIM_ON_EXP0")
dict.swim("SWIM_ACTIVATE")
--holds SWIM pin low for 16usec+ to reset SWIM comms incase of error
--also verifies that device has SWIM active
dict.swim("SWIM_RESET")
--write 0A0h to SWIM_CSR
--bit 5: allows entire memory range to be read & swim reset to be accessed
--bit 7: masks internal reset sources (like WDT..?)
--print("rotf SWIM_CSR:", string.format("%X %X", dict.swim("ROTF", 0x7F80)))
-- print("wotf SWIM_CSR:", dict.swim("WOTF", 0x7F80, 0xA0))
cur_CSR = 0xA0
wotf(SWIM_CSR, cur_CSR)
--print("rotf SWIM_CSR:", string.format("%X %X", dict.swim("ROTF", 0x7F80)))
--read SWIM_CSR
--dict.swim("SWIM_RESET")
--print("wotf SRST:", dict.swim("SWIM_SRST"))
--print("wotf SWIM_CSR:", dict.swim("WOTF", 0x7F80, 0xA0))
--now the SRST command is available, whole memory range available, and internal resets disabled
--by default there is now a breakpoint set at reset vector
--reset the STM8 core
print("wotf SRST:", dict.swim("SWIM_SRST"))
--the STM8 core is now stalled @ reset vector
--can read/write to any address on STM8 core
--if CIC ROP bit is set, we can only r/w to periph & SRAM
--bit 2: SWIM is reset (exits active mode) when chip reset
--this forces successful SWIM entry on each execution of script
-- print("rotf SWIM_CSR:", string.format("%X %X", dict.swim("ROTF", 0x7F80)))
--print("wotf SWIM_CSR:", dict.swim("WOTF", 0x7F80, 0xA4))
-- cur_CSR = cur_CSR | 0x04
-- wotf(SWIM_CSR, cur_CSR)
-- print("rotf SWIM_CSR:", string.format("%X %X", dict.swim("ROTF", 0x7F80)))
wotf(0x0000, 0x00)
rotf(0x0000)
rotf(0x0000)
rotf(0x0000)
rotf(0x0000)
rotf(0x0000)
rotf(0x0000)
rotf(0x0000)
rotf(0x0000)
rotf(0x0000)
rotf(0x0000)
rotf(0x0000)
rotf(0x0000)
print("switch to HS")
--bit 4: SWIM HIGH SPEED (set for high speed) SWIM RESET will set back to low speed
--print("wotf SWIM_CSR:", dict.swim("WOTF", 0x7F80, 0xB4))
cur_CSR = cur_CSR | 0x10
wotf(SWIM_CSR, cur_CSR)
-- print("rotf SWIM_CSR:", string.format("%X %X", dict.swim("ROTF_HS", 0x7F80)))
--print("rotf SWIM_CSR:", string.format("%X %X", dict.swim("ROTF_HS", 0x7F80)))
--print("rotf :", string.format("%X %X", dict.swim("ROTF_HS", 0x8028)))
--print("rotf :", string.format("%X %X", dict.swim("ROTF_HS", 0x8029)))
--print("rotf :", string.format("%X %X", dict.swim("ROTF_HS", 0x802A)))
--print("rotf :", string.format("%X %X", dict.swim("ROTF_HS", 0x802B)))
--print("wotf :", dict.swim("WOTF_HS", 0x8028, 0x49))
--print("wotf :", dict.swim("WOTF_HS", 0x8029, 0x4E))
--print("wotf :", dict.swim("WOTF_HS", 0x802A, 0x4C))
--print("wotf :", dict.swim("WOTF_HS", 0x802B, 0x20))
--print("rotf :", string.format("%X %X", dict.swim("ROTF_HS", 0x8028)))
--print("rotf :", string.format("%X %X", dict.swim("ROTF_HS", 0x8029)))
--print("rotf :", string.format("%X %X", dict.swim("ROTF_HS", 0x802A)))
--print("rotf :", string.format("%X %X", dict.swim("ROTF_HS", 0x802B)))
--read then write to SRAM
-- print("rotf :", string.format("%X %X", dict.swim("ROTF_HS", 0x0000)))
--print("wotf :", dict.swim("WOTF_HS", 0x0000, 0x00))
--high speed now, enable flag with true
wotf(0x0000, 0x00, true)
rotf(0x0000, true)
rotf(0x0000, true)
rotf(0x0000, true)
rotf(0x0000, true)
rotf(0x0000, true)
rotf(0x0000, true)
rotf(0x0000, true)
rotf(0x0000, true)
rotf(0x0000, true)
rotf(0x0000, true)
rotf(0x0000, true)
rotf(0x0000, true)
rotf(0x0000, true)
rotf(0x0000, true)
rotf(0x0000, true)
rotf(0x0000, true)
rotf(0x0000, true)
rotf(0x0000, true)
rotf(0x0000, true)
rotf(0x0000, true)
wotf(0x0000, 0xEE, true)
rotf(0x0000, true)
wotf(0x0000, 0xAA, true)
rotf(0x0000, true)
wotf(0x0000, 0x55, true)
rotf(0x0000, true)
-- print("rotf :", string.format("%X %X", dict.swim("ROTF_HS", 0x0000)))
--read then write to eeprom
-- print("rotf :", string.format("%X %X", dict.swim("ROTF_HS", 0x4000)))
--
-- --need to unlock the eeprom first!
-- --Write 0xAE then 56h in
-- --FLASH_DUKR (0x00 5064)(1)(2)
-- print("wotf :", dict.swim("WOTF_HS", 0x5064, 0xAE))
-- print("wotf :", dict.swim("WOTF_HS", 0x5064, 0x56))
-- --write data
-- print("wotf :", dict.swim("WOTF_HS", 0x4000, 0x00))
--
-- --lock eeprom
-- --Reset bit 3 (DUL)
-- --in FLASH_IAPSR (0x00 505F)
-- print("wotf :", dict.swim("WOTF_HS", 0x505F, 0x00))
--
-- print("rotf :", string.format("%X %X", dict.swim("ROTF_HS", 0x4000)))
--read then write to flash
-- print("rotf :", string.format("%X %X", dict.swim("ROTF_HS", 0x8028)))
--need to unlock the flash first!
--Write 0x56 then 0xAE in
--FLASH_PUKR (0x00 5062)(3)
-- print("wotf :", dict.swim("WOTF_HS", 0x5062, 0x56))
-- print("wotf :", dict.swim("WOTF_HS", 0x5062, 0xAE))
-- --write data
-- byte = 0x8028
-- data = 0x12
-- while byte < 0x8030 do
-- while (dict.swim("WOTF_HS", byte, data) ~= 1) do
-- print("woft nak ", byte)
-- end
--
-- byte = byte + 1
-- data = data + 0x11
--
-- end
-- print("wotf 28:", dict.swim("WOTF_HS", 0x8028, 0xEE))
-- print("wotf 29:", dict.swim("WOTF_HS", 0x8029, 0x11))
-- print("wotf 2A:", dict.swim("WOTF_HS", 0x802A, 0x22))
-- print("wotf 2B:", dict.swim("WOTF_HS", 0x802B, 0x33))
-- print("wotf 2C:", dict.swim("WOTF_HS", 0x802C, 0x44))
-- print("wotf 2D:", dict.swim("WOTF_HS", 0x802D, 0x55))
-- print("wotf 2E:", dict.swim("WOTF_HS", 0x802E, 0x66))
-- print("wotf 2F:", dict.swim("WOTF_HS", 0x802F, 0x77))
--lock flash
--Reset bit 1 (PUL)
-- --in FLASH_IAPSR (0x00 505F)
-- print("wotf :", dict.swim("WOTF_HS", 0x505F, 0x00))
--
-- print("rotf 28 :", string.format("%X %X", dict.swim("ROTF_HS", 0x8028)))
-- print("rotf 29 :", string.format("%X %X", dict.swim("ROTF_HS", 0x8029)))
-- print("rotf 2A :", string.format("%X %X", dict.swim("ROTF_HS", 0x802A)))
-- print("rotf 2B :", string.format("%X %X", dict.swim("ROTF_HS", 0x802B)))
-- print("rotf 2C :", string.format("%X %X", dict.swim("ROTF_HS", 0x802C)))
-- print("rotf 2D :", string.format("%X %X", dict.swim("ROTF_HS", 0x802D)))
-- print("rotf 2E :", string.format("%X %X", dict.swim("ROTF_HS", 0x802E)))
-- print("rotf 2F :", string.format("%X %X", dict.swim("ROTF_HS", 0x802F)))
--
--
-- --print("rotf SWIM_CSR:", string.format("%X %X", dict.swim("ROTF", 0x7F80)))
--print("rotf SWIM_CSR:", string.format("%X %X", dict.swim("ROTF", 0x7F80)))
--print("rotf SWIM_CSR:", string.format("%X %X", dict.swim("ROTF", 0x7F80)))
--print("rotf SWIM_CSR:", string.format("%X %X", dict.swim("ROTF", 0x7F80)))
--print("rotf SWIM_CSR:", string.format("%X %X", dict.swim("ROTF", 0x7F80)))
--test by blinking LED via periph register access
--v2 board has LED on hi_lo_sel PA2
-- print("wotf LED PA_CR1:", dict.swim("WOTF", 0x5003, 0xFF)) --default is input w/o pullup, now pullups enabled
-- --LED should be dimly lit
-- --set pin to pushpull
-- print("wotf LED PA_DDR:", dict.swim("WOTF", 0x5002, 0x04)) --PA2 is output CR1 set above makes pushpull
-- --LED is push/pull, ODR default to 0, so LED OFF
-- print("wotf LED PA_ODR:", dict.swim("WOTF", 0x5000, 0x04)) --PA2 output set LED ON!
-- print("wotf LED PA_ODR:", dict.swim("WOTF", 0x5000, 0x00)) --PA2 output set LED OFF!
--HIGH SPEED
print("wotf LED PA_CR1:", dict.swim("WOTF_HS", 0x5003, 0xFF)) --default is input w/o pullup, now pullups enabled
--LED should be dimly lit
--set pin to pushpull
print("wotf LED PA_DDR:", dict.swim("WOTF_HS", 0x5002, 0x04)) --PA2 is output CR1 set above makes pushpull
--LED is push/pull, ODR default to 0, so LED OFF
print("wotf LED PA_ODR:", dict.swim("WOTF_HS", 0x5000, 0x04)) --PA2 output set LED ON!
print("wotf LED PA_ODR:", dict.swim("WOTF_HS", 0x5000, 0x00)) --PA2 output set LED OFF!
--holds SWIM pin low for 16usec+ to reset SWIM comms incase of error
-- dict.swim("SWIM_RESET")
--reset the chip, if bit2 set in CSR the SWIM exits active mode with this reset
-- print("wotf SRST:", dict.swim("SWIM_SRST"))
--SWIM is now inactive chip is executing it's program code
--indicate to logic analyzer that test sequence above is complete
-- dict.pinport("CTL_SET_LO", "EXP0")
dict.io("IO_RESET")
end
-- global variables so other modules can use them
-- call functions desired to run when script is called/imported
-- functions other modules are able to call
swim.start = start
swim.wotf = wotf
swim.rotf = rotf
-- return the module's table
return swim