diff --git a/firmware/source/logic.h b/firmware/source/logic.h index f220aca..7a008d0 100644 --- a/firmware/source/logic.h +++ b/firmware/source/logic.h @@ -2,8 +2,13 @@ #define LO 0x00 #define HI 0xFF +//DDR values +#define IP 0x00 +#define OP 0xFF + //FALSE is ANYTHING but TRUE, the value signifies the error number #define TRUE 0x00 #define SUCCESS 0x00 -#define ERROR_UNKWN_PINP_OPCODE 1 +#define ERR_UNKN_PP_OPCODE_ONLY 1 +#define ERR_UNKN_PP_OPCODE_8BOP 2 diff --git a/firmware/source/pinport.c b/firmware/source/pinport.c index 8bc6769..5bcb0e0 100644 --- a/firmware/source/pinport.c +++ b/firmware/source/pinport.c @@ -12,11 +12,11 @@ * then decodes it to call designated macro. * shared_pinport.h is used in both host and fw to ensure opcodes/names align * Pre: Macro must be defined in firmware pinport.h - * opcode must be defined in shared-pinport.h + * opcode must be defined in shared_pinport.h * Post:Macro call complete. - * Rtn: SUCCESS if opcode found, ERROR_UNKNOWN_OPCODE if opcode not present. + * Rtn: SUCCESS if opcode found, ERR_UNKN_PP_OPCODE_ONLY if opcode not present. */ -uint8_t pinport_opcode2macro( uint8_t opcode ) +uint8_t pinport_opcode_only( uint8_t opcode ) { //these should be simple macros only for now //ie only changes one pin/port, macro doesn't call other macros yet @@ -156,7 +156,7 @@ uint8_t pinport_opcode2macro( uint8_t opcode ) //Caution AXL_CLK() relies on EXPFF_OP() to be called beforehand // Think of it like you must enable the output before you can clock it. // Floating EXPFF also happens to clock it. Think of it like it looses it's value if disabled. - #ifdef PURPLE_KAZZO or GREEN_KAZZO //purple and green versions + #if defined(PURPLE_KAZZO) || defined(GREEN_KAZZO) //purple and green versions case XOE_ip: _XOE_ip(); break; //Don't call these, use AXLOE instead case XOE_op: _XOE_op(); break; case XOE_lo: _XOE_lo(); break; @@ -188,8 +188,8 @@ uint8_t pinport_opcode2macro( uint8_t opcode ) default: - //macro doesn't exist on this PCB version - return ERROR_UNKWN_PINP_OPCODE; + //macro doesn't exist or isn't on this PCB version + return ERR_UNKN_PP_OPCODE_ONLY; } return SUCCESS; @@ -224,7 +224,7 @@ static uint8_t curAXLaddr; void software_AXL_CLK() { //first store current DATA & ADDR values - uint8_t curAXLaddr = DATA_OUT; //This is desired AXL value + curAXLaddr = DATA_OUT; //This is desired AXL value uint8_t orig_addr = ADDR_OUT; //PORTA //Put current AHL latched value on DATA as that's where it'll be relatched @@ -232,7 +232,7 @@ void software_AXL_CLK() DATA_OUT = curAHLaddr; //set ADDR as O/P and place desired value on bus - _ADDR_OP(); //should already be set, but in case not + _ADDR_OP(); //prob already be set, but in case not ADDR_OUT = curAXLaddr; //Clock both latches @@ -262,7 +262,7 @@ void software_AXL_CLK() void software_AHL_CLK() { //first store current DATA & ADDR values - uint8_t curAHLaddr = DATA_OUT; //This is desired AHL value (store it for other function's use) + curAHLaddr = DATA_OUT; //This is desired AHL value (store it for other function's use) uint8_t orig_addr = ADDR_OUT; //PORTA //Desired AHL latch value should have already been placed on DATA_OUT. @@ -284,3 +284,97 @@ void software_AHL_CLK() #endif //GREEN_KAZZO + +/* Desc:Function takes an opcode and 8bit operand which was transmitted via USB + * then decodes it to call designated macro/function. + * shared_pinport.h is used in both host and fw to ensure opcodes/names align + * Pre: Macro must be defined in firmware pinport.h + * opcode must be defined in shared_pinport.h + * data bus must be free and clear + * control pins must be initialized + * -FF latch /OE pins set as outputs + * -FF CLK pins low ready for CLK + * See big CAUTION on shared_pinport.h for more details + * Post:Macro/function called with operand + * data bus left free and clear when possible + * -DATA_OPnSET diliberately drive the bus + * Rtn: SUCCESS if opcode found, ERR_UNKN_PP_OPCODE_8BOP if opcode not present. + */ +uint8_t pinport_opcode_8b_operand( uint8_t opcode, uint8_t operand ) +{ + + switch (opcode) { + + //ADDR[7:0] PORTA + case ADDR_SET: + ADDR_OUT = operand; + break; + //convienent/safer sets OP then value + case ADDR_OPnSET: + _ADDR_OP(); + ADDR_OUT = operand; + break; + + //DATA[7:0] PORTB + case DATA_SET: + DATA_OUT = operand; + break; + //convienent/safer sets OP then value + case DATA_OPnSET: + _DATA_OP(); + DATA_OUT = operand; + break; + + //ADDR[15:8] FLIPFLOP + case ADDRH_SET: + _DATA_OP(); + DATA_OUT = operand; + _AHL_CLK(); + _DATA_IP(); + break; + + //EXPANSION FLIPFLOP + //NES: ADDRX[7:0] -> EXP PORT [8:1] + //SNES: ADDRX[7:0] -> CPU A[23:16] + case ADDRX_SET: + _DATA_OP(); + DATA_OUT = operand; + _AXL_CLK(); + _DATA_IP(); + break; + + //Set ADDR/DATA bus DDR registers with bit granularity + case ADDR_DDR_SET: + ADDR_DDR = operand; + break; + case DATA_DDR_SET: + DATA_DDR = operand; + break; + + //lowercase, you shouldn't call these unless you *Really* know what you're doing.. + case ctl_ddr_set: + CTL_DDR = operand; + break; + case aux_ddr_set: //must protect USB pins + //clear zeros + AUX_DDR &= (operand | ((1< #include "logic.h" -uint8_t pinport_opcode2macro( uint8_t opcode ); +uint8_t pinport_opcode_only( uint8_t opcode ); +uint8_t pinport_opcode_8b_operand( uint8_t opcode, uint8_t operand ); void software_AHL_CLK(); void software_AXL_CLK(); @@ -11,7 +15,7 @@ void software_AXL_CLK(); //can be differentiated by solder mask color. //Final version is default and doesn't need any defines //#define PURPLE_KAZZO -#define GREEN_KAZZO +//#define GREEN_KAZZO //======================================================= //History of PCB revsisions produced by InfiniteNesLives @@ -174,8 +178,8 @@ void software_AXL_CLK(); #define ADDR_IN PINA #define ADDR_DDR DDRA //DDR-PORT MACROS -#define _ADDR_IP() ADDR_DDR = LO -#define _ADDR_OP() ADDR_DDR = HI +#define _ADDR_IP() ADDR_DDR = IP +#define _ADDR_OP() ADDR_DDR = OP #define _ADDR_LO() ADDR_OUT = LO #define _ADDR_HI() ADDR_OUT = HI @@ -188,8 +192,8 @@ void software_AXL_CLK(); #define DATA_IN PINB #define DATA_DDR DDRB //DDR-PORT MACROS -#define _DATA_IP() DATA_DDR = LO -#define _DATA_OP() DATA_DDR = HI +#define _DATA_IP() DATA_DDR = IP +#define _DATA_OP() DATA_DDR = OP #define _DATA_LO() DATA_OUT = LO #define _DATA_HI() DATA_OUT = HI @@ -202,7 +206,7 @@ void software_AXL_CLK(); #define CTL_IN PINC #define CTL_DDR DDRC //DDR-PORT MACROS -#define _CTL_IP() CTL_DDR = LO +#define _CTL_IP() CTL_DDR = IP // No CTL_OP() macro as some of these are inputs or bidir, best to individually assert as output #define _CTL_LO() CTL_OUT = LO #define _CTL_HI() CTL_OUT = HI @@ -395,3 +399,6 @@ void software_AXL_CLK(); #define _EXPFF_OP() _XOE_lo(); #define _EXPFF_FLT() _XOE_hi(); #endif + + +#endif diff --git a/shared/shared_pinport.h b/shared/shared_pinport.h index 50984cb..1613700 100644 --- a/shared/shared_pinport.h +++ b/shared/shared_pinport.h @@ -65,13 +65,6 @@ #define ROMSEL_LO 17 #define ROMSEL_HI 18 -//accidentally doubly defined... -//having this shared .h file helped as the compiler points out these issues... -//#define CICE_IP 19 -//#define CICE_OP 20 -//#define CICE_LO 21 -//#define CICE_HI 22 - #define PRGRW_IP 23 #define PRGRW_OP 24 #define PRGRW_WR 25 //LO for writes @@ -198,12 +191,44 @@ +//============================================================================================= +//============================================================================================= +// CAUTION!!! CAUTION!!! CAUTION!!! CAUTION!!! CAUTION!!! +// +// The opcodes that follow operate under some rules that you must adhere to if calling +// 1) Data bus should be free and clear when possible +// -DATA_IP() is default state +// -Be cognizant if you're driving the data bus +// many of these opcodes use the data bus to function. +// -Many of these opcodes will end up driving the data bus +// know when that'll happen and free bus when data retreived +// +// -Flipflops must be initialized +// this primarily means CLK pin must be OP and LO ready for CLK command +// -output of FF must be enabled to actually feed latched value on cart +// final pcb version will enable EXP FF after clocking. +// early pcb versions have FF /OE on separate pin not so automatic. +// +// -control pins must be initialized +// -enable OP on pins necessary to perform desire of command +// ie M2 and /ROMSEL must be OP if you're trying to change them with a command. +// +// -be cognizant of what pins are inputs and which are outputs +// ie driving PPU /A13 will be fed back to CIRAM /CE so it needs to be IP +// -if in doubt, leave it as input with pull up, atleast that shouldn't break anything +// +// +//============================================================================================= +//============================================================================================= + + + //============================================================================================= // OPCODES WITH OPERAND and no return value besides SUCCESS/ERROR_CODE //============================================================================================= // 0x80-0x9F: opcodes with 8bit operand -// 0x80-83 are only ones currently in use +// 0x80-8B are only ones currently in use // 0xA0-0xAF: opcodes with 16bit operand // 0xA0-A4 are only ones currently in use // 0xB0-0xBF: opcodes with 24bit operand @@ -224,9 +249,13 @@ //ADDR[7:0] PORTA #define ADDR_SET 0x80 +//conveinent/safe yet slower function that sets ADDR as OP then sets value +#define ADDR_OPnSET 0x81 //DATA[7:0] PORTB -#define DATA_SET 0x81 +#define DATA_SET 0x82 +//conveinent/safe yet slower function that sets ADDR as OP then sets value +#define DATA_OPnSET 0x83 //ADDR[15:8] FLIPFLOP //NES CPU: ADDRH[6:0] -> CPU A[14:8] @@ -235,26 +264,33 @@ // ADDRH[6] -> NC on PPU side // ADDRH[7] -> PPU /A13 (which drives CIRAM /CE on most carts "2-screen mirroring") //SNES: ADDRH[7:0] -> CPU A[15:8] -#define ADDRH_SET 0x82 +#define ADDRH_SET 0x84 //EXPANSION FLIPFLOP //NES: ADDRX[7:0] -> EXP PORT [8:1] //SNES: ADDRX[7:0] -> CPU A[23:16] -#define ADDRX_SET 0x83 +#define ADDRX_SET 0x85 //Set ADDR/DATA bus DDR registers with bit granularity // OP() IP() macros affect entire 8bit port's direction // Each pin can be controlled individually though // This could be useful for advanced feature that doesn't treat DATA/ADDR as byte wide port. -#define ADDR_DDR 0x84 -#define DATA_DDR 0x84 +#define ADDR_DDR_SET 0x86 +#define DATA_DDR_SET 0x87 //Perhaps it will be useful to have this function on other ports as well //But probably wouldn't be very useful if standard carts are plugged in.. +//AUX port operations will shield USB pins from being affected +//defined as lower case because you shouldn't call these unless you *Really* know what you're doing.. +#define ctl_ddr_set 0x88 +#define aux_ddr_set 0x89 +#define ctl_port_set 0x8A +#define aux_port_set 0x8B //TODO consider listing AVR internal registers here..? //could be useful when utilizing SPI/I2C communications etc + //================================= //16bit operand //================================= @@ -318,22 +354,18 @@ - //============================================================================================= // OPCODES with NO OPERAND but have RETURN VALUE plus SUCCESS/ERROR_CODE //============================================================================================= -// 0xC0-0xCF: opcodes with 8bit operand -// 0x80-83 are only ones currently in use -// 0xA0-0xAF: opcodes with 16bit operand -// 0xA0-A4 are only ones currently in use -// 0xB0-0xBF: opcodes with 24bit operand -// 0xA0 is currently only one in use +// 0xC0-0xFF: opcodes with 8bit return value (plus SuCCESS/ERROR) +// 0xC0-CD are only ones currently in use +// +// 0x??-0xFF: larger return values perhaps? // // // Current limit for these types of opcodes is 192-255 (0xC0-0xFF) // This allows for the MSBs' to be used for decoding pinport opcode to this type // -// //============================================================================================= //============================================================================================= @@ -342,41 +374,46 @@ //This is what's used to read bus after setting DDR register to input with IP() command/macro //Current value of PORT Determines if pullups are activated or not, pull up with HI() macro, and float with LO() macro //ADDR[7:0] PINA -#define ADDR_PIN 0xC1 +#define ADDR_RD 0xC0 +//conveinence fucntion sets as input then reads +#define ADDR_INnRD 0xC1 //DATA[7:0] PINB -#define DATA_PIN 0xC0 +#define DATA_RD 0xC2 +//conveinence fucntion sets as input then reads +#define DATA_INnRD 0xC3 + //CTL PINC //Should set pin of interest to input with IP with macros prior to reading //you're still allowed to read value even if some/all pins are output though -#define CTL_PIN 0xC2 +#define CTL_RD 0xC4 //AUX PIND //Should set pin of interest to input with IP with macros prior to reading //you're still allowed to read value even if some/all pins are output though -#define AUX_PIN 0xC3 +#define AUX_RD 0xC5 //READ MCU I/O PORT OUTPUT 'PORT' REGISTERS //Gives means to see what pins are currently being driven (or pulled up) to. //ADDR[7:0] PORTA -#define ADDR_PORT 0xC4 +#define ADDR_PORT_RD 0xC6 //DATA[7:0] PORTB -#define DATA_PORT 0xC5 +#define DATA_PORT_RD 0xC7 //CTL PORTC -#define CTL_PORT 0xC6 +#define CTL_PORT_RD 0xC8 //AUX PORTD -#define AUX_PORT 0xC7 +#define AUX_PORT_RD 0xC9 //READ MCU I/O PORT DIRECTION 'DDR' REGISTERS //Gives means to see what pins are currently set to I/P or O/P. //ADDR[7:0] DDRA -#define ADDR_DDR 0xC8 +#define ADDR_DDR_RD 0xCA //DATA[7:0] DDRB -#define DATA_DDR 0xC9 +#define DATA_DDR_RD 0xCB //CTL DDRC -#define CTL_DDR 0xCA +#define CTL_DDR_RD 0xCC //AUX DDRD -#define AUX_DDR 0xCB +#define AUX_DDR_RD 0xCD @@ -384,4 +421,10 @@ //could be useful when utilizing SPI/I2C communications etc + +//============================================================================================= +// OPCODES with OPERAND and RETURN VALUE plus SUCCESS/ERROR_CODE +//============================================================================================= +//Not sure if want these or not... + #endif