Adding EXP0_PULLUP_TEST should probably verify pullup on EXP0 provides
logic 1 if relying on it. Seems to work fine on NES discrete and INLXO-ROM boards where planning to utilize it. SNES can't pull up due to pulldown and original famicom cart can't either perhaps because of EXP6 EXP FF output being too much of a load..?
This commit is contained in:
parent
8c1eb00e85
commit
c6a68c679f
|
|
@ -32,6 +32,28 @@ uint8_t io_opcode_only( uint8_t opcode )
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Desc:Function takes an opcode which was transmitted via USB
|
||||||
|
* then decodes it to call designated function.
|
||||||
|
* shared_dict_io.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_io.h
|
||||||
|
* Post:function call complete.
|
||||||
|
* 7bytes of return data are contained in *data pointer
|
||||||
|
* Rtn: SUCCESS if opcode found, ERR_UNKN_IO_OPCODE_RTN if opcode not present.
|
||||||
|
*/
|
||||||
|
uint8_t io_opcode_return( uint8_t opcode, uint8_t *data )
|
||||||
|
{
|
||||||
|
switch (opcode) {
|
||||||
|
case EXP0_PULLUP_TEST: exp0_pullup_test(data); break;
|
||||||
|
default:
|
||||||
|
//macro doesn't exist
|
||||||
|
return ERR_UNKN_IO_OPCODE_RTN;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SUCCESS;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
//pullup as many cart pins as possible
|
//pullup as many cart pins as possible
|
||||||
//goal to be safe state for all hardware
|
//goal to be safe state for all hardware
|
||||||
//doesn't currently contain any checks to report error/success from
|
//doesn't currently contain any checks to report error/success from
|
||||||
|
|
@ -62,6 +84,8 @@ void io_reset()
|
||||||
//NES PRG-ROM /OE (with pulldown) on old INL-ROM v1 boards w/pulldown
|
//NES PRG-ROM /OE (with pulldown) on old INL-ROM v1 boards w/pulldown
|
||||||
//NED PRG-ROM /WE (with pullup) on INL-ROM v3 boards w/pullup
|
//NED PRG-ROM /WE (with pullup) on INL-ROM v3 boards w/pullup
|
||||||
//NES CPLD JTAG TDO non-5v tolerant
|
//NES CPLD JTAG TDO non-5v tolerant
|
||||||
|
//Famicom carts have APU sound (EXP6) shorted to RF sound (EXP0)
|
||||||
|
// -enabling EXP FF output will drive EXP0 to value of A21/EXP6
|
||||||
_EXP0_FLT();
|
_EXP0_FLT();
|
||||||
|
|
||||||
//LED LAST displaying complete..
|
//LED LAST displaying complete..
|
||||||
|
|
@ -139,6 +163,8 @@ void nes_init()
|
||||||
//latch address of $000000
|
//latch address of $000000
|
||||||
//disable cart memories
|
//disable cart memories
|
||||||
//reset high disables SRAM and puts INL carts in PRGM mode
|
//reset high disables SRAM and puts INL carts in PRGM mode
|
||||||
|
//Excersize extreme caution calling this while NES/FC cart inserted
|
||||||
|
//probably won't work if FC inserted due to EXP0-EXP6 short due to audio jumper on cart
|
||||||
void snes_init()
|
void snes_init()
|
||||||
{
|
{
|
||||||
//start with a reset
|
//start with a reset
|
||||||
|
|
@ -189,3 +215,40 @@ void snes_init()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//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
|
||||||
|
//plus 6 bytes of read data. If pull up works but is just slow, should see that in return data.
|
||||||
|
//data[0] marks bit where EXP0 resisdes to provide host with bitmask for EXP0
|
||||||
|
void exp0_pullup_test(uint8_t *data)
|
||||||
|
{
|
||||||
|
//provide host with bit mask of EXP0 for first byte
|
||||||
|
data[0] = (1<<EXP0);
|
||||||
|
|
||||||
|
//first verify EXP0 can be driven low
|
||||||
|
_EXP0_LO(); //sets O/P and low
|
||||||
|
NOP(); //give some time to settle
|
||||||
|
data[1] = AUX_IN; //port where EXP0 resides
|
||||||
|
_EXP0_FLT(); //sets I/P w/o pullup
|
||||||
|
|
||||||
|
if ( (data[1] & data[0]) == data[0]) {
|
||||||
|
//EXP0 was high, couldn't drive EXP0 low
|
||||||
|
data[2] = data[4] = data[6] = 0xAA;
|
||||||
|
data[3] = data[5] = 0x55;
|
||||||
|
//return this signature as indication EXP0 failed to drive low
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Driving EXP0 low was successful, now pullup and read back
|
||||||
|
_EXP0_PU();
|
||||||
|
data[1] = AUX_IN;
|
||||||
|
data[2] = AUX_IN;
|
||||||
|
data[3] = AUX_IN;
|
||||||
|
data[4] = AUX_IN;
|
||||||
|
data[5] = AUX_IN;
|
||||||
|
data[6] = AUX_IN;
|
||||||
|
|
||||||
|
//return EXP0 to floating
|
||||||
|
_EXP0_FLT();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,11 @@
|
||||||
#include "shared_errors.h"
|
#include "shared_errors.h"
|
||||||
|
|
||||||
uint8_t io_opcode_only( uint8_t opcode );
|
uint8_t io_opcode_only( uint8_t opcode );
|
||||||
|
uint8_t io_opcode_return( uint8_t opcode, uint8_t *data );
|
||||||
|
|
||||||
void io_reset();
|
void io_reset();
|
||||||
void nes_init();
|
void nes_init();
|
||||||
void snes_init();
|
void snes_init();
|
||||||
|
void exp0_pullup_test(uint8_t *data);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -302,7 +302,7 @@ uint8_t nes_ppu_rd( uint8_t addrH, uint8_t addrL )
|
||||||
* data bus left clear
|
* data bus left clear
|
||||||
* Rtn: None
|
* Rtn: None
|
||||||
*/
|
*/
|
||||||
uint8_t nes_ppu_wr( uint8_t addrH, uint8_t addrL, uint8_t data )
|
void nes_ppu_wr( uint8_t addrH, uint8_t addrL, uint8_t data )
|
||||||
{
|
{
|
||||||
//will need output whole function
|
//will need output whole function
|
||||||
_DATA_OP();
|
_DATA_OP();
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,6 @@ uint8_t emulate_nes_cpu_rd( uint8_t addrH, uint8_t addrL );
|
||||||
uint8_t nes_cpu_rd( uint8_t addrH, uint8_t addrL );
|
uint8_t nes_cpu_rd( uint8_t addrH, uint8_t addrL );
|
||||||
void nes_cpu_wr( uint8_t addrH, uint8_t addrL, uint8_t data );
|
void nes_cpu_wr( uint8_t addrH, uint8_t addrL, uint8_t data );
|
||||||
uint8_t nes_ppu_rd( uint8_t addrH, uint8_t addrL );
|
uint8_t nes_ppu_rd( uint8_t addrH, uint8_t addrL );
|
||||||
uint8_t nes_ppu_wr( uint8_t addrH, uint8_t addrL, uint8_t data );
|
void nes_ppu_wr( uint8_t addrH, uint8_t addrL, uint8_t data );
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -113,6 +113,11 @@ USB_PUBLIC usbMsgLen_t usbFunctionSetup(uchar data[8]) {
|
||||||
case IO_OPCODE_ONLY_MIN ... IO_OPCODE_ONLY_MAX:
|
case IO_OPCODE_ONLY_MIN ... IO_OPCODE_ONLY_MAX:
|
||||||
rv[0] = io_opcode_only( spacket->opcode );
|
rv[0] = io_opcode_only( spacket->opcode );
|
||||||
break;
|
break;
|
||||||
|
case IO_OPCODE_RTN_MIN ... IO_OPCODE_RTN_MAX:
|
||||||
|
rv[0] = io_opcode_return(
|
||||||
|
spacket->opcode, &rv[1] );
|
||||||
|
rlen = 8;
|
||||||
|
break;
|
||||||
default: //io opcode min/max definition error
|
default: //io opcode min/max definition error
|
||||||
rv[0] = ERR_BAD_IO_OP_MINMAX;
|
rv[0] = ERR_BAD_IO_OP_MINMAX;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@
|
||||||
#include "pinport.h"
|
#include "pinport.h"
|
||||||
#include "io.h"
|
#include "io.h"
|
||||||
#include "nes.h"
|
#include "nes.h"
|
||||||
|
#include "snes.h"
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -72,6 +72,10 @@ int dictionary_call( USBtransfer *transfer, uint8_t dictionary, uint8_t opcode,
|
||||||
case IO_OPCODE_ONLY_MIN ... IO_OPCODE_ONLY_MAX:
|
case IO_OPCODE_ONLY_MIN ... IO_OPCODE_ONLY_MAX:
|
||||||
debug("IO_OPCODE_ONLY");
|
debug("IO_OPCODE_ONLY");
|
||||||
break;
|
break;
|
||||||
|
case IO_OPCODE_RTN_MIN ... IO_OPCODE_RTN_MAX:
|
||||||
|
debug("IO_OPCODE_RTN");
|
||||||
|
transfer->wLength = 8;
|
||||||
|
break;
|
||||||
default: //io opcode min/max definition error
|
default: //io opcode min/max definition error
|
||||||
sentinel("bad IO opcode min/max err:%d",ERR_BAD_IO_OP_MINMAX);
|
sentinel("bad IO opcode min/max err:%d",ERR_BAD_IO_OP_MINMAX);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,18 +8,27 @@ int erase_nes( USBtransfer *transfer )
|
||||||
//dict opcode addr data
|
//dict opcode addr data
|
||||||
dictionary_call( transfer, IO, IO_RESET, 0, 0);
|
dictionary_call( transfer, IO, IO_RESET, 0, 0);
|
||||||
dictionary_call( transfer, IO, NES_INIT, 0, 0);
|
dictionary_call( transfer, IO, NES_INIT, 0, 0);
|
||||||
//software mode
|
dictionary_call( transfer, IO, EXP0_PULLUP_TEST, 0, 0);
|
||||||
dictionary_call( transfer, NES, DISCRETE_EXP0_PRGROM_WR, 0x5555, 0xAA);
|
dictionary_call( transfer, PINPORT, AUX_RD, 0, 0);
|
||||||
dictionary_call( transfer, NES, DISCRETE_EXP0_PRGROM_WR, 0x2AAA, 0x55);
|
dictionary_call( transfer, PINPORT, AUX_RD, 0, 0);
|
||||||
dictionary_call( transfer, NES, DISCRETE_EXP0_PRGROM_WR, 0x5555, 0x90);
|
dictionary_call( transfer, PINPORT, AUX_RD, 0, 0);
|
||||||
dictionary_call( transfer, NES, NES_CPU_RD, 0x8000, 0);
|
dictionary_call( transfer, PINPORT, AUX_RD, 0, 0);
|
||||||
dictionary_call( transfer, NES, NES_CPU_RD, 0x8001, 0);
|
dictionary_call( transfer, PINPORT, AUX_RD, 0, 0);
|
||||||
dictionary_call( transfer, NES, NES_CPU_RD, 0x8000, 0);
|
dictionary_call( transfer, PINPORT, AUX_RD, 0, 0);
|
||||||
dictionary_call( transfer, NES, NES_CPU_RD, 0x8001, 0);
|
dictionary_call( transfer, PINPORT, AUX_RD, 0, 0);
|
||||||
//exit software
|
|
||||||
dictionary_call( transfer, NES, DISCRETE_EXP0_PRGROM_WR, 0x8000, 0xF0);
|
////software mode
|
||||||
dictionary_call( transfer, NES, NES_CPU_RD, 0x8000, 0);
|
// dictionary_call( transfer, NES, DISCRETE_EXP0_PRGROM_WR, 0x5555, 0xAA);
|
||||||
dictionary_call( transfer, NES, NES_CPU_RD, 0x8001, 0);
|
// dictionary_call( transfer, NES, DISCRETE_EXP0_PRGROM_WR, 0x2AAA, 0x55);
|
||||||
|
// dictionary_call( transfer, NES, DISCRETE_EXP0_PRGROM_WR, 0x5555, 0x90);
|
||||||
|
// dictionary_call( transfer, NES, NES_CPU_RD, 0x8000, 0);
|
||||||
|
// dictionary_call( transfer, NES, NES_CPU_RD, 0x8001, 0);
|
||||||
|
// dictionary_call( transfer, NES, NES_CPU_RD, 0x8000, 0);
|
||||||
|
// dictionary_call( transfer, NES, NES_CPU_RD, 0x8001, 0);
|
||||||
|
////exit software
|
||||||
|
// dictionary_call( transfer, NES, DISCRETE_EXP0_PRGROM_WR, 0x8000, 0xF0);
|
||||||
|
// dictionary_call( transfer, NES, NES_CPU_RD, 0x8000, 0);
|
||||||
|
// dictionary_call( transfer, NES, NES_CPU_RD, 0x8001, 0);
|
||||||
|
|
||||||
//erase
|
//erase
|
||||||
// dictionary_call( transfer, NES, DISCRETE_EXP0_PRGROM_WR, 0x5555, 0xAA);
|
// dictionary_call( transfer, NES, DISCRETE_EXP0_PRGROM_WR, 0x5555, 0xAA);
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@
|
||||||
// 0x00-0xFF
|
// 0x00-0xFF
|
||||||
// Detect this opcode/operand setup with opcode between the following defines:
|
// Detect this opcode/operand setup with opcode between the following defines:
|
||||||
#define IO_OPCODE_ONLY_MIN 0x00
|
#define IO_OPCODE_ONLY_MIN 0x00
|
||||||
#define IO_OPCODE_ONLY_MAX 0xFF
|
#define IO_OPCODE_ONLY_MAX 0x7F
|
||||||
//
|
//
|
||||||
//=============================================================================================
|
//=============================================================================================
|
||||||
//=============================================================================================
|
//=============================================================================================
|
||||||
|
|
@ -53,4 +53,46 @@
|
||||||
//reset high disables SRAM and puts INL carts in PRGM mode
|
//reset high disables SRAM and puts INL carts in PRGM mode
|
||||||
#define SNES_INIT 0x02
|
#define SNES_INIT 0x02
|
||||||
|
|
||||||
|
|
||||||
|
//=============================================================================================
|
||||||
|
// OPCODES with no operand but have RETRUN VALUE plus SUCCESS/ERROR_CODE
|
||||||
|
//=============================================================================================
|
||||||
|
// 0x00-0xFF
|
||||||
|
// Detect this opcode/operand setup with opcode between the following defines:
|
||||||
|
#define IO_OPCODE_RTN_MIN 0x80
|
||||||
|
#define IO_OPCODE_RTN_MAX 0xFF
|
||||||
|
//
|
||||||
|
//=============================================================================================
|
||||||
|
//=============================================================================================
|
||||||
|
|
||||||
|
//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
|
||||||
|
//Test that programmer can drive EXP0 with a pull up before reling on commands that only pullup
|
||||||
|
//If this fails, can resort to driving EXP0 with SNES /RESET commands but excersize caution
|
||||||
|
//as some NES cart's have CPLD JTAG TDO pin placed on EXP0 that may not be 5v tolerant.
|
||||||
|
//FC also has APU audio placed on EXP0, carts without exp sound short RF sound (EXP6) to EXP0
|
||||||
|
//So if EXP FF's output is enabled, driving the mcu EXP0 pin could cause damage to the pin.
|
||||||
|
//that's why it's best in general to only pull up EXP0 instead of driving it high.
|
||||||
|
//Have to drive it low however to get logic 0 most times. If famicom cart is inserted,
|
||||||
|
//it's probably safer to drive EXP0 through EXP6 sound jumper and leave EXP0 floating/pulledup.
|
||||||
|
//
|
||||||
|
//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
|
||||||
|
//plus 6 bytes of read data. If pull up works but is just slow, should see that in return data.
|
||||||
|
//data[0] marks bit where EXP0 resisdes to provide host with bitmask for EXP0
|
||||||
|
#define EXP0_PULLUP_TEST 0x80
|
||||||
|
//testing results:
|
||||||
|
//without any cart inserted takes 5 cycles for EXP0 to settle high
|
||||||
|
//er: 0 rv: 1, b8, b8, b8, b8, b9, b9
|
||||||
|
//with discrete NROM board inserted (has pullup on EXP0) settled immediately
|
||||||
|
//er: 0 rv: 1, 99, 99, 99, 99, 99, 99
|
||||||
|
//SNES board inserted never settled
|
||||||
|
//er: 0 rv: 1, b8, b8, b8, b8, b8, b8
|
||||||
|
//famicom NROM choplifter cart inserted never settled
|
||||||
|
//er: 0 rv: 1, 98, 98, 98, 98, 98, 98
|
||||||
|
//INLXO-ROM board JTAG TDO (non-5v tolerant) tied to EXP0 settled immediately
|
||||||
|
//er: 0 rv: 1, 99, 99, 99, 99, 99, 99
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@
|
||||||
#define ERR_UNKN_PP_OPCODE_8BRV 144
|
#define ERR_UNKN_PP_OPCODE_8BRV 144
|
||||||
|
|
||||||
#define ERR_UNKN_IO_OPCODE_ONLY 150
|
#define ERR_UNKN_IO_OPCODE_ONLY 150
|
||||||
|
#define ERR_UNKN_IO_OPCODE_RTN 151
|
||||||
|
|
||||||
#define ERR_UNKN_NES_OPCODE_24BOP 160
|
#define ERR_UNKN_NES_OPCODE_24BOP 160
|
||||||
#define ERR_UNKN_NES_OPCODE_16BOP_8BRV 161
|
#define ERR_UNKN_NES_OPCODE_16BOP_8BRV 161
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue