Have stm devices activating SWIM on SNES STM8 CIC.
AVR not yet working, performing low level SWIM operations will require decent amount of core specific code due to differences in pin driver styles, timers, cycles per instruction, etc. The fact that SWIM pin changes based on the board ADDR0, DATA0, EXP0, etc multiplies this low level code... Thinking about executing SWIM low level drivers from SRAM. Initialization could include loading these routines to SRAM. For now just focusing on supporting SWIM on STM cores for SNES boards.
This commit is contained in:
parent
476c28cb24
commit
6eb0570335
|
|
@ -26,9 +26,12 @@ uint8_t io_call( uint8_t opcode, uint8_t miscdata, uint16_t operand, uint8_t *rd
|
|||
#define BYTE_LEN 1
|
||||
#define HWORD_LEN 2
|
||||
switch (opcode) {
|
||||
case IO_RESET: io_reset(); break;
|
||||
case NES_INIT: nes_init(); break;
|
||||
case SNES_INIT: snes_init(); break;
|
||||
case IO_RESET: io_reset(); break;
|
||||
case NES_INIT: nes_init(); break;
|
||||
case SNES_INIT: snes_init(); break;
|
||||
case SWIM_INIT:
|
||||
return swim_init(operand); break;
|
||||
|
||||
case EXP0_PULLUP_TEST:
|
||||
rdata[RD_LEN] = BYTE_LEN;
|
||||
rdata[RD0] = exp0_pullup_test(); break;
|
||||
|
|
@ -196,6 +199,37 @@ void snes_init()
|
|||
|
||||
}
|
||||
|
||||
//Initialization of SWIM "single wire interface module" communications
|
||||
//the SWIM pin depends on INL board design.
|
||||
//dict call must provide the "swim_lane"
|
||||
//that swim lane will be used for all subsequent communications.
|
||||
//TODO setup to control SWIM pin as (psuedo) open drain.
|
||||
//if swim lane is unknown or other problem return error, else return SUCCESS
|
||||
uint8_t swim_init( uint8_t swim_lane )
|
||||
{
|
||||
switch (swim_lane) {
|
||||
case SWIM_ON_A0: //Most NES & Famicom carts
|
||||
break;
|
||||
case SWIM_ON_EXP0: //SNES carts
|
||||
//set to define used by shared_dict_pinport.h
|
||||
//that way we can call pinport_call(opcode, null, swim_pin, null)
|
||||
CTL_ENABLE();
|
||||
EXP0_IP_PU(); //this enables pullup for stm
|
||||
#ifdef STM_CORE
|
||||
EXP0_OD(); //set type to open drain
|
||||
EXP0_HI(); //set output high (deasserted)
|
||||
EXP0_OP(); //enable as output to have above take effect
|
||||
#endif
|
||||
swim_pin = EXP0_;
|
||||
break;
|
||||
case SWIM_ON_D0: //NES/FC carts with CICOprocesor
|
||||
break;
|
||||
default:
|
||||
return ERR_UNKN_SWIM_LANE;
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
//Test starts by verifying EXP0 can be driven low, if not, will return one byte of AUX_PIN
|
||||
//followed by alternating 0xAA, 0x55, 0xAA...
|
||||
//This test pulls up EXP0 and then reads AUX_PIN 6 times in rapid succession returning error code
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
#define _io_h
|
||||
|
||||
#include "pinport.h"
|
||||
#include "swim.h"
|
||||
#include "shared_dictionaries.h"
|
||||
#include "shared_errors.h"
|
||||
|
||||
|
|
@ -10,6 +11,7 @@ uint8_t io_call( uint8_t opcode, uint8_t miscdata, uint16_t operand, uint8_t *rd
|
|||
void io_reset();
|
||||
void nes_init();
|
||||
void snes_init();
|
||||
uint8_t swim_init(uint8_t opcode);
|
||||
uint8_t exp0_pullup_test();
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -192,6 +192,24 @@ uint8_t pinport_call( uint8_t opcode, uint8_t miscdata, uint16_t operand, uint8_
|
|||
default: return ERR_CTL_PIN_NOT_PRESENT;
|
||||
}
|
||||
break;
|
||||
#ifdef STM_CORE
|
||||
//AVR Doesn't have open drain mode, it must be simulated by
|
||||
//toggling between input with pullup and output push-pull
|
||||
case CTL_OD_:
|
||||
switch ( operand ) {
|
||||
//currently only defining pins which utilize open drain function
|
||||
//C8 -> EXP0 (SNES /RESET)
|
||||
case 8: CTL_OD(C8bank, C8); break;
|
||||
default: return ERR_CTL_PIN_NOT_PRESENT;
|
||||
}
|
||||
break;
|
||||
case CTL_PP_:
|
||||
switch ( operand ) {
|
||||
case 8: CTL_PP(C8bank, C8); break;
|
||||
default: return ERR_CTL_PIN_NOT_PRESENT;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
case CTL_SET_LO_:
|
||||
switch ( operand ) {
|
||||
case 0: CTL_SET_LO(C0bank, C0); break;
|
||||
|
|
|
|||
|
|
@ -90,6 +90,11 @@ uint8_t pinport_call( uint8_t opcode, uint8_t miscdata, uint16_t operand, uint8_
|
|||
#define EXP0_HI() CTL_SET_HI(EXP0bank, EXP0)
|
||||
#define EXP0_RD(val) CTL_RD(EXP0bank, EXP0, val)
|
||||
|
||||
#ifdef STM_CORE
|
||||
#define EXP0_OD() CTL_OD(EXP0bank, EXP0)
|
||||
#define EXP0_PP() CTL_PP(EXP0bank, EXP0)
|
||||
#endif
|
||||
|
||||
// PC9 "LED"
|
||||
#define LED_IP_PU() CTL_IP_PU(LEDbank, LED)
|
||||
#define LED_IP_FL() CTL_IP_FL(LEDbank, LED)
|
||||
|
|
|
|||
|
|
@ -260,6 +260,9 @@ void software_AXL_CLK();
|
|||
// 1- Open Drain
|
||||
// N/A when MODER is set to "00" INPUT
|
||||
// we can generally just ignore this register and use pushpull as AVR does
|
||||
// but using open drain mode makes things like SWIM much simpler to control
|
||||
//#define OTYPER_PP 0x00
|
||||
#define OTYPER_OD 0x01
|
||||
//
|
||||
// GPIOx->OSPEEDR[1:0] 32bit registers control pin driver speed/slew
|
||||
// x0- Low speed (default reset state, except SWD-PA13 default High Spd)
|
||||
|
|
@ -818,6 +821,8 @@ void software_AXL_CLK();
|
|||
#define CTL_IP_PU(bank, pin) bank->MODER &= ~(MODER_OP<<(pin*2)); bank->PUPDR |= (PUPDR_PU<<(pin*2))
|
||||
#define CTL_IP_FL(bank, pin) bank->MODER &= ~(MODER_OP<<(pin*2)); bank->PUPDR &= ~(PUPDR_PU<<(pin*2))
|
||||
#define CTL_OP(bank, pin) bank->MODER |= (MODER_OP<<(pin*2))
|
||||
#define CTL_OD(bank, pin) bank->OTYPER |= (OTYPER_OD<<(pin)) //open drain has no effect when pin is input
|
||||
#define CTL_PP(bank, pin) bank->OTYPER &= ~(OTYPER_OD<<(pin))
|
||||
#define CTL_SET_LO(bank, pin) bank->BRR = 1<<pin
|
||||
#define CTL_SET_HI(bank, pin) bank->BSRR = 1<<pin
|
||||
#define CTL_RD(bank, pin, val) val = (bank->IDR & (1<<pin))
|
||||
|
|
|
|||
|
|
@ -0,0 +1,131 @@
|
|||
#include "swim.h"
|
||||
|
||||
//=================================================================================================
|
||||
//
|
||||
// SWIM operations
|
||||
// This file includes all the swim functions possible to be called from the swim dictionary.
|
||||
//
|
||||
// See description of the commands contained here in shared/shared_dictionaries.h
|
||||
//
|
||||
//=================================================================================================
|
||||
|
||||
/* Desc:Function takes an opcode which was transmitted via USB
|
||||
* then decodes it to call designated function.
|
||||
* shared_dict_swim.h is used in both host and fw to ensure opcodes/names align
|
||||
* Pre: Macros must be defined in firmware pinport.h
|
||||
* opcode must be defined in shared_dict_swim.h
|
||||
* Post:function call complete.
|
||||
* Rtn: SUCCESS if opcode found, error if opcode not present or other problem.
|
||||
*/
|
||||
uint8_t swim_call( uint8_t opcode, uint8_t miscdata, uint16_t operand, uint8_t *rdata )
|
||||
{
|
||||
#define RD_LEN 0
|
||||
#define RD0 1
|
||||
#define RD1 2
|
||||
|
||||
#define BYTE_LEN 1
|
||||
#define HWORD_LEN 2
|
||||
switch (opcode) {
|
||||
case SWIM_ACTIVATE: swim_activate(); break;
|
||||
case SWIM_RESET: swim_reset(); break;
|
||||
// case SWIM_SRST: swim_srst(); break;
|
||||
// case WOTF: swim_woft(operand); break;
|
||||
// case ROTF:
|
||||
// rdata[RD_LEN] = BYTE_LEN;
|
||||
// rdata[RD0] = swim_roft(); break;
|
||||
default:
|
||||
//opcode doesn't exist
|
||||
return ERR_UNKN_SWIM_OPCODE;
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
uint8_t swim_pin;
|
||||
|
||||
void delay( uint16_t delay )
|
||||
{
|
||||
uint16_t i = 0;
|
||||
|
||||
for( i=0; i<delay; i++) {
|
||||
NOP();
|
||||
NOP();
|
||||
} //16->11.8 on stmad
|
||||
|
||||
}
|
||||
|
||||
/* Desc:Initiate SWIM activate sequence
|
||||
* Pre: swim_pin must be set and initialized via io.h
|
||||
* Post:STM8 mcu SWIM active
|
||||
* Rtn: SUCCESS if able to enter sucessfully.
|
||||
*/
|
||||
void swim_activate()
|
||||
{
|
||||
uint16_t i;
|
||||
|
||||
// pinport_call( CTL_OP_, 0, swim_pin, 0);
|
||||
|
||||
//toggles in this manner take 4.55-4.6usec on AVR
|
||||
//toggles in this manner take 4.9-4.95usec on STM adapter
|
||||
|
||||
//pulse low for 16usec spec says 16usec
|
||||
//but looking at working programmers they do twice the delays below
|
||||
pinport_call( CTL_SET_LO_, 0, swim_pin, 0);
|
||||
delay(16);
|
||||
pinport_call( CTL_SET_HI_, 0, swim_pin, 0);
|
||||
|
||||
//toggle high->low T=1msec 4x
|
||||
for( i = 0; i < 4; i++) {
|
||||
//STM adapter 720 = 500.9usec
|
||||
#ifdef STM_INL6
|
||||
delay(719);
|
||||
#endif
|
||||
#ifdef STM_ADAPTER
|
||||
delay(720);
|
||||
#endif
|
||||
pinport_call( CTL_SET_LO_, 0, swim_pin, 0);
|
||||
delay(718);
|
||||
pinport_call( CTL_SET_HI_, 0, swim_pin, 0);
|
||||
}
|
||||
|
||||
//toggle high->low T=0.5msec 4x
|
||||
for( i = 0; i < 4; i++) {
|
||||
//STM adapter 358 = 256usec
|
||||
delay(356);
|
||||
pinport_call( CTL_SET_LO_, 0, swim_pin, 0);
|
||||
delay(355);
|
||||
pinport_call( CTL_SET_HI_, 0, swim_pin, 0);
|
||||
}
|
||||
|
||||
//pinport_call( CTL_IP_PU_, 0, swim_pin, 0);
|
||||
|
||||
|
||||
//wait for device to take swim_pin low for ~16usec
|
||||
//it's low for 128 SWIM clock sync pulse
|
||||
//Best way to do this would be to wait for an interrupt
|
||||
//on the swim pin going low, then have the isr count
|
||||
//low time. If anything takes too long timeout.
|
||||
|
||||
//TODO
|
||||
//return SUCCESS/FAIL depending on wether that ~16usec pulse was obtained
|
||||
// return SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
/* Desc:Hold swim pin low for >128 SWIM clocks (16usec)
|
||||
* Pre: swim must be activated by
|
||||
* Post:STM8 mcu SWIM comms are reset
|
||||
* Rtn: SUCCESS if device responds with sync window.
|
||||
*/
|
||||
void swim_reset()
|
||||
{
|
||||
pinport_call( CTL_OP_, 0, swim_pin, 0);
|
||||
|
||||
//pulse low for 16usec spec says 16usec
|
||||
//but looking at working programmers they do twice the delays below
|
||||
pinport_call( CTL_SET_LO_, 0, swim_pin, 0);
|
||||
delay(16);
|
||||
pinport_call( CTL_IP_PU_, 0, swim_pin, 0);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
#ifndef _swim_h
|
||||
#define _swim_h
|
||||
|
||||
#include "pinport.h"
|
||||
#include "shared_dictionaries.h"
|
||||
#include "shared_errors.h"
|
||||
|
||||
extern uint8_t swim_pin;
|
||||
|
||||
uint8_t swim_call( uint8_t opcode, uint8_t miscdata, uint16_t operand, uint8_t *rdata );
|
||||
void swim_activate();
|
||||
void swim_reset();
|
||||
|
||||
#endif
|
||||
|
|
@ -103,19 +103,23 @@ uint16_t usbFunctionSetup(uint8_t data[8]) {
|
|||
switch(spacket->bRequest) {
|
||||
case DICT_PINPORT:
|
||||
rv[RETURN_ERR_IDX] = pinport_call( spacket->opcode, spacket->miscdata, spacket->operand, &rv[RETURN_LEN_IDX] );
|
||||
break; //end of PINPORT
|
||||
break;
|
||||
|
||||
case DICT_IO:
|
||||
rv[RETURN_ERR_IDX] = io_call( spacket->opcode, spacket->miscdata, spacket->operand, &rv[RETURN_LEN_IDX] );
|
||||
break; //end of IO
|
||||
break;
|
||||
|
||||
case DICT_NES:
|
||||
rv[RETURN_ERR_IDX] = nes_call( spacket->opcode, spacket->miscdata, spacket->operand, &rv[RETURN_LEN_IDX] );
|
||||
break; //end of NES
|
||||
break;
|
||||
|
||||
case DICT_SNES:
|
||||
rv[RETURN_ERR_IDX] = snes_call( spacket->opcode, spacket->miscdata, spacket->operand, &rv[RETURN_LEN_IDX] );
|
||||
break; //end of NES
|
||||
break;
|
||||
|
||||
case DICT_SWIM:
|
||||
rv[RETURN_ERR_IDX] = swim_call( spacket->opcode, spacket->miscdata, spacket->operand, &rv[RETURN_LEN_IDX] );
|
||||
break;
|
||||
|
||||
|
||||
case DICT_BUFFER:
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
#include "nes.h"
|
||||
#include "snes.h"
|
||||
#include "buffer.h"
|
||||
#include "swim.h"
|
||||
#include "types.h"
|
||||
#include "shared_usb.h"
|
||||
#include "shared_errors.h"
|
||||
|
|
|
|||
|
|
@ -194,10 +194,7 @@ local function pinport( opcode, operand, misc, data )
|
|||
end
|
||||
--print("error:", error_code, "data_len:", data_len)
|
||||
|
||||
assert ( (error_code == err_codes["SUCCESS"]), "ERROR!!! device error code:", error_code)
|
||||
--if error_code ~= err_codes["SUCCESS"] then
|
||||
-- print("ERROR!!! device error code:", error_code)
|
||||
-- end
|
||||
assert ( (error_code == err_codes["SUCCESS"]), "\n ERROR!!! problem with opcode: " .. opcode .. " device error code: " .. error_code)
|
||||
|
||||
if data_len and data_len ~= (wLength - RETURN_LEN_IDX) then
|
||||
print("WARNING!! Device's return data length:", data_len, "did not match expected:", wLength-RETURN_LEN_IDX)
|
||||
|
|
@ -240,18 +237,14 @@ local function io( opcode, operand, misc, data )
|
|||
count, data = usb_vend_xfr(
|
||||
-- ep, dictionary wValue[misc:opcode] wIndex wLength data
|
||||
ep, dict["DICT_IO"], ( misc<<8 | op_io[opcode]), operand, wLength, data)
|
||||
--print(count)
|
||||
|
||||
local error_code, data_len
|
||||
if ep == USB_IN then
|
||||
error_code = data:byte(RETURN_ERR_IDX)
|
||||
data_len = data:byte(RETURN_LEN_IDX)
|
||||
end
|
||||
--print("error:", error_code, "data_len:", data_len)
|
||||
|
||||
assert ( (error_code == err_codes["SUCCESS"]), "ERROR!!! device error code:", error_code)
|
||||
--if error_code ~= err_codes["SUCCESS"] then
|
||||
-- print("ERROR!!! device error code:", error_code)
|
||||
-- end
|
||||
assert ( (error_code == err_codes["SUCCESS"]), "\n ERROR!!! problem with opcode: " .. opcode .. " device error code: " .. error_code)
|
||||
|
||||
if data_len and data_len ~= (wLength - RETURN_LEN_IDX) then
|
||||
print("WARNING!! Device's return data length:", data_len, "did not match expected:", wLength-RETURN_LEN_IDX)
|
||||
|
|
@ -302,10 +295,7 @@ local function nes( opcode, operand, misc, data )
|
|||
end
|
||||
--print("error:", error_code, "data_len:", data_len)
|
||||
|
||||
assert ( (error_code == err_codes["SUCCESS"]), "ERROR!!! device error code:", error_code)
|
||||
--if error_code ~= err_codes["SUCCESS"] then
|
||||
-- print("ERROR!!! device error code:", error_code)
|
||||
--end
|
||||
assert ( (error_code == err_codes["SUCCESS"]), "\n ERROR!!! problem with opcode: " .. opcode .. " device error code: " .. error_code)
|
||||
|
||||
if data_len and data_len ~= (wLength - RETURN_LEN_IDX) then
|
||||
print("WARNING!! Device's return data length:", data_len, "did not match expected:", wLength-RETURN_LEN_IDX)
|
||||
|
|
@ -357,10 +347,7 @@ local function snes( opcode, operand, misc, data )
|
|||
end
|
||||
--print("error:", error_code, "data_len:", data_len)
|
||||
|
||||
assert ( (error_code == err_codes["SUCCESS"]), "ERROR!!! device error code:", error_code)
|
||||
--if error_code ~= err_codes["SUCCESS"] then
|
||||
-- print("ERROR!!! device error code:", error_code)
|
||||
--end
|
||||
assert ( (error_code == err_codes["SUCCESS"]), "\n ERROR!!! problem with opcode: " .. opcode .. " device error code: " .. error_code)
|
||||
|
||||
if data_len and data_len ~= (wLength - RETURN_LEN_IDX) then
|
||||
print("WARNING!! Device's return data length:", data_len, "did not match expected:", wLength-RETURN_LEN_IDX)
|
||||
|
|
@ -376,6 +363,58 @@ local function snes( opcode, operand, misc, data )
|
|||
|
||||
end
|
||||
|
||||
-- external call for swim dictionary
|
||||
local function swim( opcode, operand, misc, data )
|
||||
|
||||
if not op_swim[opcode] then
|
||||
print("ERROR undefined opcode:", opcode, "must be defined in shared_dict_swim.h")
|
||||
return nil
|
||||
end
|
||||
|
||||
if not operand then
|
||||
operand = 0
|
||||
elseif type(operand) == "string" then
|
||||
if not op_swim[operand] then
|
||||
print("ERROR undefined operand:", operand, "must be defined in shared_dict_swim.h")
|
||||
return nil
|
||||
end
|
||||
--decode string operands into
|
||||
operand = op_swim[operand]
|
||||
end
|
||||
|
||||
if not misc then misc = 0 end
|
||||
|
||||
local wLength, ep = default_rlen_1_in(op_swim[opcode.."rlen"])
|
||||
|
||||
local count
|
||||
count, data = usb_vend_xfr(
|
||||
-- ep, dictionary wValue[misc:opcode] wIndex wLength data
|
||||
ep, dict["DICT_SWIM"], ( misc<<8 | op_swim[opcode]), operand, wLength, data)
|
||||
--print(count)
|
||||
local error_code, data_len
|
||||
if ep == USB_IN then
|
||||
error_code = data:byte(RETURN_ERR_IDX)
|
||||
data_len = data:byte(RETURN_LEN_IDX)
|
||||
end
|
||||
--print("error:", error_code, "data_len:", data_len)
|
||||
|
||||
assert ( (error_code == err_codes["SUCCESS"]), "\n ERROR!!! problem with opcode: " .. opcode .. " device error code: " .. error_code)
|
||||
|
||||
if data_len and data_len ~= (wLength - RETURN_LEN_IDX) then
|
||||
print("WARNING!! Device's return data length:", data_len, "did not match expected:", wLength-RETURN_LEN_IDX)
|
||||
end
|
||||
|
||||
--process the return data string and return it to calling function
|
||||
if data_len then
|
||||
return string_to_int( data:sub(RETURN_DATA, data_len+RETURN_DATA), data_len)
|
||||
else
|
||||
return nil
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
|
||||
local function buffer_payload_in( wLength, buff_num )
|
||||
|
||||
local opcode = nil
|
||||
|
|
@ -471,10 +510,7 @@ local function buffer( opcode, operand, misc, data, stringout )
|
|||
end
|
||||
--print("error:", error_code, "data_len:", data_len)
|
||||
|
||||
assert ( (error_code == err_codes["SUCCESS"]), "ERROR!!! device error code:", error_code)
|
||||
--if error_code ~= err_codes["SUCCESS"] then
|
||||
-- print("ERROR!!! device error code:", error_code)
|
||||
-- end
|
||||
assert ( (error_code == err_codes["SUCCESS"]), "\n ERROR!!! problem with opcode: " .. opcode .. " device error code: " .. error_code)
|
||||
|
||||
if data_len and data_len ~= (wLength - RETURN_LEN_IDX) then
|
||||
print("WARNING!! Device's return data length:", data_len, "did not match expected:", wLength-RETURN_LEN_IDX)
|
||||
|
|
@ -527,10 +563,7 @@ local function operation( opcode, operand, misc, data )
|
|||
end
|
||||
--print("error:", error_code, "data_len:", data_len)
|
||||
|
||||
assert ( (error_code == err_codes["SUCCESS"]), "ERROR!!! device error code:", error_code)
|
||||
--if error_code ~= err_codes["SUCCESS"] then
|
||||
-- print("ERROR!!! device error code:", error_code)
|
||||
-- end
|
||||
assert ( (error_code == err_codes["SUCCESS"]), "\n ERROR!!! problem with opcode: " .. opcode .. " device error code: " .. error_code)
|
||||
|
||||
if data_len and data_len ~= (wLength - RETURN_LEN_IDX) then
|
||||
print("WARNING!! Device's return data length:", data_len, "did not match expected:", wLength-RETURN_LEN_IDX)
|
||||
|
|
@ -555,6 +588,7 @@ op_io = {}
|
|||
op_operation = {}
|
||||
op_nes = {}
|
||||
op_snes = {}
|
||||
op_swim = {}
|
||||
err_codes = {}
|
||||
|
||||
-- Dictionary table definitions initialized by calling parser
|
||||
|
|
@ -566,6 +600,7 @@ create_dict_tables( op_io, "../shared/shared_dict_io.h")
|
|||
create_dict_tables( op_operation, "../shared/shared_dict_operation.h")
|
||||
create_dict_tables( op_nes, "../shared/shared_dict_nes.h")
|
||||
create_dict_tables( op_snes, "../shared/shared_dict_snes.h")
|
||||
create_dict_tables( op_swim, "../shared/shared_dict_swim.h")
|
||||
create_dict_tables( err_codes, "../shared/shared_errors.h")
|
||||
|
||||
-- functions other modules are able to call
|
||||
|
|
@ -573,6 +608,7 @@ dict.pinport = pinport
|
|||
dict.io = io
|
||||
dict.nes = nes
|
||||
dict.snes = snes
|
||||
dict.swim = swim
|
||||
dict.buffer = buffer
|
||||
dict.buffer_payload_in = buffer_payload_in
|
||||
dict.buffer_payload_out = buffer_payload_out
|
||||
|
|
|
|||
|
|
@ -31,11 +31,26 @@ function main ()
|
|||
end
|
||||
|
||||
-- print(dict.io("EXP0_PULLUP_TEST"))
|
||||
--
|
||||
dict.io("IO_RESET")
|
||||
|
||||
dict.io("SNES_INIT")
|
||||
dict.io("SWIM_INIT", "SWIM_ON_EXP0")
|
||||
dict.swim("SWIM_ACTIVATE")
|
||||
|
||||
--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..?)
|
||||
-- dict.swim("WOTF", 0xA0)
|
||||
|
||||
dict.io("IO_RESET")
|
||||
|
||||
-- debug = true
|
||||
-- rv = cart.detect(debug)
|
||||
|
||||
if cart.detect_console(true) then
|
||||
local force_cart = true
|
||||
|
||||
if (force_cart or cart.detect_console(true)) then
|
||||
if cart_console == "NES" or cart_console == "Famicom" then
|
||||
dict.io("IO_RESET")
|
||||
dict.io("NES_INIT")
|
||||
|
|
@ -95,6 +110,7 @@ function main ()
|
|||
dict.io("IO_RESET")
|
||||
dict.io("SNES_INIT")
|
||||
|
||||
|
||||
--SNES detect HiROM or LoROM
|
||||
--nes.detect_mapper_mirroring(true)
|
||||
local snes_mapping = "LOROM"
|
||||
|
|
@ -107,7 +123,7 @@ function main ()
|
|||
|
||||
--FLASHING:
|
||||
--erase cart
|
||||
-- erase.erase_snes( false )
|
||||
-- erase.erase_snes( false )
|
||||
--open file
|
||||
local file
|
||||
file = assert(io.open("flash.bin", "rb"))
|
||||
|
|
@ -130,7 +146,7 @@ function main ()
|
|||
|
||||
|
||||
--trick to do this at end while debugging so don't have to wait for it before starting
|
||||
erase.erase_snes( false )
|
||||
-- erase.erase_snes( false )
|
||||
|
||||
dict.io("IO_RESET")
|
||||
|
||||
|
|
|
|||
|
|
@ -36,6 +36,18 @@
|
|||
//reset high disables SRAM and puts INL carts in PRGM mode
|
||||
#define SNES_INIT 2
|
||||
|
||||
|
||||
//SWIM protocol init
|
||||
//"single wire interface module"
|
||||
//different INL boards have this signal on different pins
|
||||
//So initialization must provide pin to perform all subsequent
|
||||
//communications with
|
||||
#define SWIM_INIT 3
|
||||
// don't define 0x00 to protect from forgetting to pass swim lane
|
||||
#define SWIM_ON_A0 0x01 //NES & Famicom carts
|
||||
#define SWIM_ON_EXP0 0x02 //SNES carts
|
||||
#define SWIM_ON_D0 0x03 //NES discrete CICOprocessor
|
||||
|
||||
//Test EXP0 drive with pull up
|
||||
//This is an important test if reling on pulling up EXP0 pin to drive the cart's pin.
|
||||
//EXP0 is used for various things and may have pull up/down of it's own or significant load
|
||||
|
|
|
|||
|
|
@ -50,6 +50,8 @@
|
|||
#define CTL_SET_LO_ 4
|
||||
#define CTL_SET_HI_ 5
|
||||
#define CTL_RD_ 6 //RL=4 (error code, data length, LSB, MSB)
|
||||
#define CTL_OD_ 24
|
||||
#define CTL_PP_ 25
|
||||
//operands
|
||||
// PC0 "MCO" mcu clock out M2/phi2, Sysclk, etc
|
||||
#define C0_ 0
|
||||
|
|
|
|||
|
|
@ -0,0 +1,39 @@
|
|||
#ifndef _shared_dict_swim_h
|
||||
#define _shared_dict_swim_h
|
||||
|
||||
//define dictionary's reference number in the shared_dictionaries.h file
|
||||
//then include this dictionary file in shared_dictionaries.h
|
||||
//The dictionary number is literally used as usb transfer request field
|
||||
//the opcodes and operands in this dictionary are fed directly into usb setup packet's wValue wIndex fields
|
||||
|
||||
|
||||
//=============================================================================================
|
||||
//=============================================================================================
|
||||
// SWIM DICTIONARY
|
||||
//
|
||||
// opcodes contained in this dictionary must be implemented in firmware/source/swim.c
|
||||
//
|
||||
//=============================================================================================
|
||||
//=============================================================================================
|
||||
|
||||
|
||||
//activate swim on device as initiated with dict_io SWIM_INIT
|
||||
//return SUCCESS if device responds with sync frame
|
||||
#define SWIM_ACTIVATE 0
|
||||
|
||||
//hold swim pin low for 128 clocks to init comms
|
||||
//return SUCCESS if device responds with sync frame
|
||||
#define SWIM_RESET 1
|
||||
|
||||
//SWIM commands
|
||||
#define SWIM_SRST 2 //reset device
|
||||
|
||||
#define ROTF 0x11 //read on the fly only one byte
|
||||
//#define ROTF_8B 0x18 //read on the fly RL=8
|
||||
//#define ROTF_128B 0x1F //read on the fly RL=128 (current max due to 254B limit)
|
||||
|
||||
#define WOTF 0x21 //write on the fly only one byte
|
||||
//#define WOTF_8B 0x28 //write 8Bytes on the fly
|
||||
//#define WOTF_128B 0x2F //write 128Bytes on the fly
|
||||
|
||||
#endif
|
||||
|
|
@ -103,4 +103,13 @@
|
|||
//dictionary used to initialize and control operation_info variables
|
||||
//=============================================================================================
|
||||
//=============================================================================================
|
||||
|
||||
|
||||
//=============================================================================================
|
||||
//=============================================================================================
|
||||
#define DICT_SWIM 8
|
||||
#include "shared_dict_swim.h"
|
||||
//dictionary used to control swim communications
|
||||
//=============================================================================================
|
||||
//=============================================================================================
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -8,11 +8,14 @@
|
|||
//greater than 128 are possible avr return codes
|
||||
#define ERR_UNKN_DICTIONARY 128
|
||||
|
||||
#define ERR_UNKN_SWIM_OPCODE 130
|
||||
|
||||
|
||||
#define ERR_UNKN_PP_OPCODE 140
|
||||
#define ERR_CTL_PIN_NOT_PRESENT 141
|
||||
|
||||
#define ERR_UNKN_IO_OPCODE 150
|
||||
#define ERR_UNKN_SWIM_LANE 151
|
||||
|
||||
#define ERR_UNKN_NES_OPCODE 160
|
||||
//
|
||||
|
|
|
|||
Loading…
Reference in New Issue