modified: logic.h

-defining SUCCESS & ERROR_CODES
new file:   pinport.c
	-Creation of file with giant switch to decode byte value into
	macro call.
	-software AXL and AHL clocking of for green boards.
modified:   pinport.h
	-removed #ifdef for signals, should only be based on board when
	possible.
	-created macro for AXL/AHL_CLK to call software function
deleted:    macro.h
	-don't want this old guy around any more...
This commit is contained in:
Paul Molloy 2016-11-23 01:19:14 -06:00
parent b43b3c0756
commit b1ba1c4432
4 changed files with 305 additions and 225 deletions

View File

@ -2,5 +2,8 @@
#define LO 0x00
#define HI 0xFF
#define TRUE 0x00
//FALSE is ANYTHING but TRUE, the value signifies the error number
#define TRUE 0x00
#define SUCCESS 0x00
#define ERROR_UNKWN_PINP_OPCODE 1

View File

@ -1,222 +0,0 @@
#include <avr/io.h>
#define NOP() do { __asm__ __volatile__ ("nop"); } while (0)
// used for a very short delay
#define LO 0x00
#define HI 0xFF
#define TRUE 0x00
//FALSE is ANYTHING but TRUE, the value signifies the error number
//asci table
#define char_A 0x41
#define char_C 0x43
#define char_N 0x4e
#define char_E 0x45
#define char_P 0x50
#define char_R 0x52
#define char_S 0x53
#define char_Y 0x59
#define char_EOF 0x1A
//file header types
#define ERASE 1
#define NES 2
#define SNES 3
#define SPI 4
#define JTAG 5
#define COPY 6
//file header feilds
#define PRG_BANKS_16 header[4]
#define CHR_BANKS_8 header[5]
#define MAP_LO header[6]
#define MAP_HI header[7]
//Mapper numbers
#define NROM 0
#define MMC1 1
#define UxROM 2
#define CNROM 3
#define MMC3 4
#define MMC2 9
#define MMC4 10
#define ACTION53 28
#define IREM 65
#define FME7 69
#define VRC4 21
#define VRC4alt 23
#define NSF 255
//board versions
#define EPROM0 10
#define EPROM1 11
#define EPROM2 12
#define FLASH0 20
#define FLASH1 21
#define DISCRETE0 30
#define CA13n 7
//PIN DEFINITIONS
//AUX PORTD
#define EXP0 PD0 //RESET_n on SNES
#define LED PD1
#define EXP9 PD1 //dual purposed pin
#define USBP PD2
#define IRQ PD3
#define USBM PD4
#define CIA10 PD5
#define BL PD6
#define XOE PD7 //Only X_OE on purple and green boards
//X_OE and X_CLK on yellow final boards
//CTL PORTC
#define M2 PC0
#define PCE PC1 //SNES /ROMSEL
#define PRW PC2
#define AXL PC3 //Free on green and yellow boards
//Also AXL /OE on Yellow boards
#define CRD PC4 //SNES /RD
#define CWR PC5 //SNES /WR
#define CICE PC6
#define AHL PC7 //Also AXL on green proto boards
//PORT DEFINITIONS
#define ADDR_OUT PORTA
#define ADDR_IN PINA
#define ADDR_DDR DDRA
#define DATA_OUT PORTB
#define DATA_IN PINB
#define DATA_DDR DDRB
//#define UP_ADDR PORTB
//second revision moves this to PORTA and combines AXL/AHL
//#define X_ADDR PORTB
#define CTL_OUT PORTC
#define CTL_IN PINC
#define CTL_DDR DDRC
#define AUX_OUT PORTD
#define AUX_IN PIND
#define AUX_DDR DDRD
#define DATA_IP() DATA_DDR = LO
#define DATA_OP() DATA_DDR = HI
#define DATA_HI() DATA_OUT = HI
#define DATA_LO() DATA_OUT = LO
#define ADDR_IP() ADDR_DDR = LO
#define ADDR_OP() ADDR_DDR = HI
#define ADDR_HI() ADDR_OUT = HI
#define ADDR_LO() ADDR_OUT = LO
//AHL, AXL, are always output and high, unless individually asserted.
#define CTL_IP() CTL_DDR = 0b10001000// &= ((1<<AHL) | (1<<AXL))
#define CTL_OP() CTL_DDR = 0b10111111 //&= ~(1<<CICE); CTL_DDR |= ~((1<<AHL) | (1<<AXL) | (1<<CICE)) //CIRAM /CE is always input
#define CTL_HI() CTL_OUT |= ~((1<<AHL) | (1<<AXL))
//maintain these high unless individually asserted
#define CTL_LO() CTL_OUT &= ((1<<AHL) | (1<<AXL))
//LED and XOE are separately asserted due to always outputs
#define AUX_IP() AUX_DDR &= ((1<<USBP) | (1<<USBM) | (1<<LED) | (1<<XOE))
//#define AUX_OP() AUX_DDR |= ~((1<<USBP) | (1<<USBM) | (1<<LED) | (1<<XOE))
#define AUX_HI() AUX_OUT |= ~((1<<USBP) | (1<<USBM) | (1<<LED) | (1<<XOE))
#define AUX_LO() AUX_OUT &= ((1<<USBP) | (1<<USBM) | (1<<LED) | (1<<XOE))
//SNES copy cart needs CIRAM A10 and CIRAM /CE to be outputs
#define CC_OP() AUX_DDR |= (1<<CIA10); CTL_DDR |= (1<<CICE)
#define CC_IP() AUX_DDR &= ~(1<<CIA10); CTL_DDR &= ~(1<<CICE)
#define SETUP_LED() AUX_DDR |= (1<<LED)
#define LED_ON() AUX_OUT |= (1<<LED)
#define LED_OFF() AUX_OUT &= ~(1<<LED)
#define SETUP_ADDR_X() AUX_DDR |= (1<<XOE)
#define DISABLE_ADDR_X() AUX_OUT |= (1<<XOE)
#define ENABLE_ADDR_X() AUX_OUT &= ~(1<<XOE)
#define SETUP_AHL() CTL_DDR |= (1<<AHL); CTL_OUT |= (1<<AHL) //output high
#define SETUP_AXL() CTL_DDR |= (1<<AXL); CTL_OUT |= (1<<AXL) //output high
#define LATCH_AHL() CTL_OUT &= ~(1<<AHL); CTL_OUT |= (1<<AHL) //toggle low -> high
#define LATCH_AXL() CTL_OUT &= ~(1<<AXL); CTL_OUT |= (1<<AXL) //toggle low -> high
#define M2_IP() CTL_DDR &= ~(1<<M2)
#define M2_OP() CTL_DDR |= (1<<M2)
#define M2_HI() CTL_OUT |= (1<<M2)
#define M2_LO() CTL_OUT &= ~(1<<M2)
#define CYCLE() CTL_OUT |= (1<<M2); NOP(); NOP(); NOP(); CTL_OUT &= ~(1<<M2); NOP(); NOP(); NOP(); CTL_OUT |= (1<<PCE) //toggle M2 high -> low for CPU access cycle, and takes PRG /CE high if it was low
#define PCE_HI() CTL_OUT |= (1<<PCE)
#define PCE_LO() CTL_OUT &= ~(1<<PCE)
#define CICE_HI() CTL_OUT |= (1<<CICE)
#define CICE_LO() CTL_OUT &= ~(1<<CICE)
#define PRG_RD() CTL_OUT |= (1<<PRW)
#define PRG_WR() CTL_OUT &= ~(1<<PRW)
#define PRG_RD_PCE_HI() CTL_OUT |= (1<<PRW) | (1<<PCE)
#define PRG_WR_PCE_LO() CTL_OUT &= ~((1<<PRW) | (1<<PCE))
//#define SNES_RD_SEL_HI() CTL_OUT |= (1<<CRD) | (1<<PCE)
#define SNES_WR_SEL_LO() CTL_OUT &= ~((1<<CWR) | (1<<PCE))
#define SNES_RD_SEL_LO() CTL_OUT &= ~((1<<CRD) | (1<<PCE))
#define SNES_CTL_HI() CTL_OUT |= (1<<CWR) | (1<<CRD) | (1<<PCE)
#define CC_CTL_HI() CTL_OUT |= (1<<PRW) | (1<<CICE); AUX_OUT |= (1<<CIA10)
//#define SNES_CTL_LO() CTL_OUT &= ~((1<<CWR) | (1<<CRD) | (1<<PCE))
#define CHR_OEN() CTL_OUT |= (1<<CRD)
#define CHR_OE() CTL_OUT &= ~(1<<CRD)
#define CHR_WEN() CTL_OUT |= (1<<CWR) //Not-able (high)
#define CHR_WE() CTL_OUT &= ~(1<<CWR) //Enabled (low)
#define CC_OEN() AUX_OUT |= (1<<CIA10)
#define CC_OE() AUX_OUT &= ~(1<<CIA10)
#define CC_WEN() CTL_OUT |= (1<<PRW) //Not-able (high)
#define CC_WE() CTL_OUT &= ~(1<<PRW) //Enabled (low)
#define CHR_RD() CHR_WEN(); CHR_OE();
#define CHR_WR() CHR_OEN(); CHR_WE(); // /OE-hi /WE-lo
// /WE-hi /OE-lo
// PRG RW hi, CIRAMA10 lo
#define CC_RD() CC_WEN(); CC_OE();
#define CC_WR() CC_OEN(); CC_WE();
//CIRAM A10 hi, PRGRW lo
// /OE-hi /WE-lo
//EXP0 to only be pulled high because XO boards don't level shift EXP0
//EXP0_LO(); replace with EXP0_LO(); EXP0_OP();
//EXP0_HI(); replace with EXP0_IP(); EXP0_HI();
#define EXP0_IP() AUX_DDR &= ~(1<<EXP0)
#define EXP0_OP() AUX_DDR |= (1<<EXP0)
#define EXP0_HIGH() AUX_OUT |= (1<<EXP0)
#define EXP0_LOW() AUX_OUT &= ~(1<<EXP0)
#define EXP0_HI() EXP0_IP(); EXP0_HIGH(); NOP(); NOP(); NOP(); NOP();
#define EXP0_LO() EXP0_LOW(); EXP0_OP();
#define PU_CICE() CTL_DDR &= ~(1<<CICE); CTL_OUT |= (1<<CICE);
//Masks for where the signals are on the bus
/*
// 0b76543210
#define AHL 0b10000000
#define ciramA10 0b01000000
#define chr_WR 0b00100000
#define chr_RD 0b00010000
#define AXL 0b00001000
#define prgR_W 0b00000100
#define prg_CE 0b00000010
#define M2 0b00000001
#define _WR 0b00100100 //write for both busses
*/

291
firmware/source/pinport.c Normal file
View File

@ -0,0 +1,291 @@
#include <avr/io.h>
#include "logic.h"
#include "pinport.h"
//This file is generated from pinport.h
//the close relationship between these two files must be kept in mind when making changes.
//This file is also very dependent on macro definitions in host app.
//the host app pinport.h was generated from this file, so any changes here must be forwarded.
/* Desc:Function takes an opcode which was transmitted via USB
* then decodes it to call designated macro.
* Pre: Macro must be defined in firmware pinport.h
* opcode must align with host pinport.h otherwise who knows what you're calling
* Post:Macro call complete.
* Rtn: SUCCESS if opcode found, ERROR_UNKNOWN_OPCODE if opcode not present.
*/
uint8_t pinport_macro( uint8_t opcode )
{
//these should be simple macros only for now
//ie only changes one pin/port, macro doesn't call other macros yet
//made exception to this rule for EXP0 since doesn't vary on board versions
switch (opcode) {
//============================
//ADDR[7:0] PORTA
//============================
//DDR-PORT MACROS
case 0: ADDR_IP(); break;
case 1: ADDR_OP(); break;
case 2: ADDR_LO(); break;
case 3: ADDR_HI(); break;
//============================
//DATA[7:0] PORTB
//============================
//DDR-PORT MACROS
case 4: DATA_IP(); break;
case 5: DATA_OP(); break;
case 6: DATA_LO(); break;
case 7: DATA_HI(); break;
//============================
//CTL PORTC
//============================
//DDR-PORT MACROS
case 8: CTL_IP(); break;
// No CTL_OP() macro as some of these are inputs or bidir, best to individually assert as output
case 9: CTL_LO(); break;
case 10: CTL_HI(); break;
//PIN MACROS
case 11: M2_IP(); break;
case 12: M2_OP(); break;
case 13: M2_LO(); break;
case 14: M2_HI(); break;
//TODO read M2 PIN as input
case 15: ROMSEL_IP(); break;
case 16: ROMSEL_OP(); break;
case 17: ROMSEL_LO(); break;
case 18: ROMSEL_HI(); break;
case 19: CICE_IP(); break;
case 20: CICE_OP(); break;
case 21: CICE_LO(); break;
case 22: CICE_HI(); break;
case 23: PRGRW_IP(); break;
case 24: PRGRW_OP(); break;
case 25: PRGRW_WR(); break; //LO for writes
case 26: PRGRW_RD(); break; //Hi for reads
//give each def different version numbers to detect errors
//where command given to board which doesn't have that function
#ifdef p_AXL //purple boards only
case 27: p_AXL_IP(); break;
case 28: p_AXL_OP(); break;
case 29: p_AXL_lo(); break; //Don't recommend calling lo/hi, use CLK instead
case 30: p_AXL_hi(); break;
//AXL_CLK assumes AXL was previously left in default low state
//XX: AXL_CLK() p_AXL_hi(); p_AXL_lo(); //same name and convention on final design
#else //Green and final design
case 31: FREE_IP(); break;
case 32: FREE_OP(); break;
case 33: FREE_LO(); break;
case 34: FREE_HI(); break;
#endif
case 35: CSRD_IP(); break;
case 36: CSRD_OP(); break;
case 37: CSRD_LO(); break;
case 38: CSRD_HI(); break;
case 39: CSWR_IP(); break;
case 40: CSWR_OP(); break;
case 41: CSWR_LO(); break;
case 42: CSWR_HI(); break;
case 43: CICE_IP(); break;
case 44: CICE_OP(); break;
case 45: CICE_LO(); break;
case 46: CICE_HI(); break;
#ifdef g_AXHL
case 47: g_AXHL_IP(); break;
case 48: g_AXHL_OP(); break;
case 49: g_AXHL_lo(); break; //Don't recommend calling these as AXHL should be left low
case 50: g_AXHL_hi(); break; //That way AXHL_CLK(); is always effective
//XX: AXHL_CLK() g_AXHL_hi(); g_AXHL_lo();
#else //purple and final design
case 51: AHL_IP(); break;
case 52: AHL_OP(); break;
case 53: AHL_lo(); break; //Don't recommend calling these as AHL should be left low
case 54: AHL_hi(); break; //That way AHL_CLK(); is always effective
//XX: AHL_CLK() AHL_hi(); AHL_lo();
#endif
//============================
//AUX PORTD
//============================
//DDR-PORT MACROS
case 55: AUX_IP(); break; //Don't touch USB pins!!!
// No AUX_OP(); macro as many of these are inputs or bidir, best to individually assert as output
case 56: AUX_LO(); break;
case 57: AUX_HI(); break;
//PIN MACROS
//lower case aren't meant to be called unless certain pin is 5v tolerant
case 58: EXP0_ip(); break;
case 59: EXP0_op(); break;
case 60: EXP0_lo(); break; //Don't call this assuming EXP0 DDR is set to o/p
case 61: EXP0_hi(); break; //Don't call this unless you're certain pin is 5v tolerant
//User options pull up, force low, and float
case 62: EXP0_LO(); break; //Sets low then DDR to o/p
case 63: EXP0_PU(); break; //maybe add some NOP(); to allow time for pull up
case 64: EXP0_FLT(); break; //Set to i/p w/o pullup
case 65: LED_IP(); break;
case 66: LED_OP(); break;
case 67: LED_OFF(); break;
case 68: LED_ON(); break;
case 69: IRQ_IP(); break;
case 70: IRQ_OP(); break;
case 71: IRQ_LO(); break;
case 72: IRQ_HI(); break;
case 73: CIA10_IP(); break;
case 74: CIA10_OP(); break;
case 75: CIA10_LO(); break;
case 76: CIA10_HI(); break;
case 77: BL_IP(); break;
case 78: BL_OP(); break;
case 79: BL_LO(); break;
case 80: BL_HI(); break;
#ifndef pg_XOE //FINAL_DESIGN
case 81: AXLOE_IP(); break;
case 82: AXLOE_OP(); break;
//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.
//XX: AXL_CLK() EXPFF_FLT(); EXPFF_OP(); //same name and convention as purple
#else //purple and green versions
case 83: XOE_IP(); break;
case 84: XOE_OP(); break;
#endif
//Same definition on all board versions
//Only need to be cognizant that AXL_CLK won't work if EXPFF_FLT was called beforehand
//This is only an issue on final design, so an error here should only cause probs on final design
//Net effect is it it works on final design should be fine on other versions which is the goal
case 85: EXPFF_OP(); break; //FF /OE pin low->enable o/p
case 86: EXPFF_FLT(); break; //FF /OE pin high->disable o/p
//AXL_CLK this is similar between purple and green versions, just on a different pin.
//green boards don't have an AXL_CLK nor a AHL_CLK, as the two are combined.
//green boards must resolve this in software storing value of FF's so can have the effect
//of only clocking one of them.
//#ifdef g_AXHL
//case XX: AXHL_CLK(); break; //don't want to call this as software AXL/AHL don't track
//case 87: software_AXL_CLK(); break;
//case 88: software_AHL_CLK(); break;
//#else
//these two cases covers all designs with macro calling sofware versions for green board.
case 87: AXL_CLK(); break;
case 88: AHL_CLK(); break;
//#endif
//these work fine in hardware for purple and final.
//green had to separate these two with software.
default:
//macro doesn't exist on this PCB version
return ERROR_UNKWN_PINP_OPCODE;
}
return SUCCESS;
}
#ifdef GREEN_KAZZO
/* Desc:
* other board versions have PORTB "DATA" feed into both FF's
* this board feeds EXP FF with PORTA "ADDR" instead
* goal is to make board versions 'identical'
* to do this we assume higher level functions will have already
* placed desired latch value on PORTB "DATA_OUT"
* we need to juggle this data around and not stomp on anything
* Pre: DATA_OP() set
* curAHLaddr set by software_AHL_CLK
* DATA_OUT contains desired value to be latched by EXP FF
* AXHL might not be set as O/P
* AXHL might not be low ready for AXHL_CLK
* Post:Both FF's have desired value latched
* ADDR_OP() left set
* curAXLaddr updated for use by software_AHL_CLK
* DATA_OUT and ADDR_OUT replaced with original values
* AXHL left as O/P and ready for subsequent CLK
*/
//these variables are updated each time the FF's are clocked
//that way we can retain the value of other FF as both must be clocked at once
static uint8_t curAHLaddr;
static uint8_t curAXLaddr;
void software_AXL_CLK()
{
//first store current DATA & ADDR values
uint8_t 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
//software_AHL_CLK function is one to maintain this value
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_OUT = curAXLaddr;
//Clock both latches
g_AXHL_OP(); //can't be sure "AHL" is OP as assumption is AXL will be used as latch
g_AXHL_lo(); //can't be sure it's low either
AXHL_CLK(); //clock values
//finally restore original DATA & ADDR values
DATA_OUT = curAXLaddr;
ADDR_OUT = orig_addr;
}
/* Desc: Same premise as software_AXL_CLK above.
* this is a little simpler as data has already been feed with AHL value.
* just need to make sure AXL latch doesn't get corrupted.
* Pre: DATA_OP() set
* curAXLaddr set by software_AXL_CLK
* DATA_OUT contains desired value to be latched by ADDRMID FF
* AXHL is already set to O/P
* AXHL already low ready for AXHL_CLK
* Post:Both FF's have desired value latched
* curAHLaddr updated for use by software_AXL_CLK
* DATA_OUT and ADDR_OUT replaced with original values
* AXHL left as O/P and ready for subsequent 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)
uint8_t orig_addr = ADDR_OUT; //PORTA
//Desired AHL latch value should have already been placed on DATA_OUT.
//set ADDR as O/P and place curAXLaddr on bus other function should have updated it last latch
ADDR_OP(); //should already be set, but in case not
ADDR_OUT = curAXLaddr;
//Clock both latches
//Can assume AHL is OP as other versions would require it to latch AHL
//Can also assume it was left low, if not causes issues in all board versions
AXHL_CLK(); //clock values
//finally restore original DATA & ADDR values
//never changed: DATA_OUT = curAHLaddr;
ADDR_OUT = orig_addr;
}
#endif //GREEN_KAZZO

View File

@ -1,6 +1,10 @@
#include <avr/io.h>
#include "logic.h"
uint8_t pinport_macro( uint8_t opcode );
void software_AHL_CLK();
void software_AXL_CLK();
//This file contains pinout translations from AVR names to "kazzo" names
//this file also works to make all kazzo versions compatible and "alike"
//There are defines for kazzo version, turns out unique early versions
@ -239,7 +243,7 @@
#define PRGRW_WR() CTL_OUT &= ~(1<<PRGRW) //LO for writes
#define PRGRW_RD() CTL_OUT |= (1<<PRGRW) //HI for reads
#ifdef p_AXL
#ifdef PURPLE_KAZZO
#define p_AXL_IP() CTL_DDR &= ~(1<<p_AXL)
#define p_AXL_OP() CTL_DDR |= (1<<p_AXL)
#define p_AXL_lo() CTL_OUT &= ~(1<<p_AXL) //Don't recommend calling lo/hi, use CLK instead
@ -268,12 +272,14 @@
#define CICE_LO() CTL_OUT &= ~(1<<CICE)
#define CICE_HI() CTL_OUT |= (1<<CICE)
#ifdef g_AXHL
#ifdef GREEN_KAZZO
#define g_AXHL_IP() CTL_DDR &= ~(1<<g_AXHL)
#define g_AXHL_OP() CTL_DDR |= (1<<g_AXHL)
#define g_AXHL_lo() CTL_OUT &= ~(1<<g_AXHL) //Don't recommend calling these as AXHL should be left low
#define g_AXHL_hi() CTL_OUT |= (1<<g_AXHL) //That way AXHL_CLK(); is always effective
#define AXHL_CLK() g_AXHL_hi(); g_AXHL_lo();
#define AHL_CLK() software_AHL_CLK();
#define AXL_CLK() software_AXL_CLK();
#else //purple and final design
#define AHL_IP() CTL_DDR &= ~(1<<AHL)
#define AHL_OP() CTL_DDR |= (1<<AHL)
@ -282,6 +288,8 @@
#define AHL_CLK() AHL_hi(); AHL_lo();
#endif
//green board software AXL & AHL are separated in software in pinport.c
//============================
//AUX PORTD
//============================