INL-retro-progdump/firmware/source/pinport.c

511 lines
15 KiB
C

#include "pinport.h"
//This file was created based on pinport.h
//the close relationship between these two files must be kept in mind when making changes.
//This file is also very dependent on shared_dict_pinport.h
//the shared_dict_pinport.h was generated from this file, so any changes here must be forwarded.
/* Desc:Decode pinport dictionary calls transmitted via USB and call requested operation
* shared_dict_pinport.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_pinport.h
* Post:opcode command complete, return data & length stored if used.
* Rtn: SUCCESS if opcode found and completed, error code if not.
*/
uint8_t pinport_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
//create pointer to first two bytes of return data array
uint16_t *ret_hword = (uint16_t*) &rdata[RD0];
switch (opcode) {
//============================
//CONTROL PORT INDIVIDUAL PIN ACCESS
//opcode: type of pin operation
//operand: pin number to act on
//============================
case CTL_ENABLE_: CTL_ENABLE(); break;
case CTL_IP_PU_:
switch ( operand ) {
case 0: CTL_IP_PU(C0bank, C0); break;
case 1: CTL_IP_PU(C1bank, C1); break;
case 2: CTL_IP_PU(C2bank, C2); break;
#ifndef C3nodef
case 3: CTL_IP_PU(C3bank, C3); break;
#endif
case 4: CTL_IP_PU(C4bank, C4); break;
case 5: CTL_IP_PU(C5bank, C5); break;
case 6: CTL_IP_PU(C6bank, C6); break;
#ifndef C7nodef
case 7: CTL_IP_PU(C7bank, C7); break;
#endif
case 8: CTL_IP_PU(C8bank, C8); break;
case 9: CTL_IP_PU(C9bank, C9); break;
case 10: CTL_IP_PU(C10bank,C10); break;
case 11: CTL_IP_PU(C11bank,C11); break;
#ifndef C12nodef
case 12: CTL_IP_PU(C12bank,C12); break;
#endif
#ifndef C13nodef
case 13: CTL_IP_PU(C13bank,C13);
#ifdef PURPLE_KAZZO
CTL_IP_PU(C3bank,C3);
#endif
break;
#endif
#ifndef C14nodef
case 14: CTL_IP_PU(C14bank,C14); break;
#endif
#ifndef C15nodef
case 15: CTL_IP_PU(C15bank,C15); break;
#endif
#ifndef C16nodef
case 16: CTL_IP_PU(C16bank,C16); break;
#endif
#ifndef C17nodef
case 17: CTL_IP_PU(C17bank,C17); break;
#endif
#ifndef C18nodef
case 18: CTL_IP_PU(C18bank,C18); break;
#endif
#ifndef C19nodef
case 19: CTL_IP_PU(C19bank,C19); break;
#endif
#ifndef C20nodef
case 20: CTL_IP_PU(C20bank,C20); break;
#endif
case 21: CTL_IP_PU(C21bank,C21); break;
default: return ERR_CTL_PIN_NOT_PRESENT;
}
break;
case CTL_IP_FL_:
switch ( operand ) {
case 0: CTL_IP_FL(C0bank, C0); break;
case 1: CTL_IP_FL(C1bank, C1); break;
case 2: CTL_IP_FL(C2bank, C2); break;
#ifndef C3nodef
case 3: CTL_IP_FL(C3bank, C3); break;
#endif
case 4: CTL_IP_FL(C4bank, C4); break;
case 5: CTL_IP_FL(C5bank, C5); break;
case 6: CTL_IP_FL(C6bank, C6); break;
#ifndef C7nodef
case 7: CTL_IP_FL(C7bank, C7); break;
#endif
case 8: CTL_IP_FL(C8bank, C8); break;
case 9: CTL_IP_FL(C9bank, C9); break;
case 10: CTL_IP_FL(C10bank,C10); break;
case 11: CTL_IP_FL(C11bank,C11); break;
#ifndef C12nodef
case 12: CTL_IP_FL(C12bank,C12); break;
#endif
#ifndef C13nodef
case 13: CTL_IP_FL(C13bank,C13);
#ifdef PURPLE_KAZZO
CTL_IP_FL(C3bank,C3);
#endif
break;
#endif
#ifndef C14nodef
case 14: CTL_IP_FL(C14bank,C14); break;
#endif
#ifndef C15nodef
case 15: CTL_IP_FL(C15bank,C15); break;
#endif
#ifndef C16nodef
case 16: CTL_IP_FL(C16bank,C16); break;
#endif
#ifndef C17nodef
case 17: CTL_IP_FL(C17bank,C17); break;
#endif
#ifndef C18nodef
case 18: CTL_IP_FL(C18bank,C18); break;
#endif
#ifndef C19nodef
case 19: CTL_IP_FL(C19bank,C19); break;
#endif
#ifndef C20nodef
case 20: CTL_IP_FL(C20bank,C20); break;
#endif
case 21: CTL_IP_FL(C21bank,C21); break;
default: return ERR_CTL_PIN_NOT_PRESENT;
}
break;
case CTL_OP_:
switch ( operand ) {
case 0: CTL_OP(C0bank, C0); break;
case 1: CTL_OP(C1bank, C1); break;
case 2: CTL_OP(C2bank, C2); break;
#ifndef C3nodef
case 3: CTL_OP(C3bank, C3); break;
#endif
case 4: CTL_OP(C4bank, C4); break;
case 5: CTL_OP(C5bank, C5); break;
case 6: CTL_OP(C6bank, C6); break;
#ifndef C7nodef
case 7: CTL_OP(C7bank, C7); break;
#endif
case 8: CTL_OP(C8bank, C8); break;
case 9: CTL_OP(C9bank, C9); break;
case 10: CTL_OP(C10bank,C10); break;
case 11: CTL_OP(C11bank,C11); break;
#ifndef C12nodef
case 12: CTL_OP(C12bank,C12); break;
#endif
#ifndef C13nodef
case 13: CTL_OP(C13bank,C13);
#ifdef PURPLE_KAZZO
CTL_OP(C3bank,C3);
#endif
break;
#endif
#ifndef C14nodef
case 14: CTL_OP(C14bank,C14); break;
#endif
#ifndef C15nodef
case 15: CTL_OP(C15bank,C15); break;
#endif
#ifndef C16nodef
case 16: CTL_OP(C16bank,C16); break;
#endif
#ifndef C17nodef
case 17: CTL_OP(C17bank,C17); break;
#endif
#ifndef C18nodef
case 18: CTL_OP(C18bank,C18); break;
#endif
#ifndef C19nodef
case 19: CTL_OP(C19bank,C19); break;
#endif
#ifndef C20nodef
case 20: CTL_OP(C20bank,C20); break;
#endif
case 21: CTL_OP(C21bank,C21); break;
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;
case 1: CTL_SET_LO(C1bank, C1); break;
case 2: CTL_SET_LO(C2bank, C2); break;
#ifndef C3nodef
case 3: CTL_SET_LO(C3bank, C3); break;
#endif
case 4: CTL_SET_LO(C4bank, C4); break;
case 5: CTL_SET_LO(C5bank, C5); break;
case 6: CTL_SET_LO(C6bank, C6); break;
#ifndef C7nodef
case 7: CTL_SET_LO(C7bank, C7); break;
#endif
case 8: CTL_SET_LO(C8bank, C8); break;
case 9: CTL_SET_LO(C9bank, C9); break;
case 10: CTL_SET_LO(C10bank,C10); break;
case 11: CTL_SET_LO(C11bank,C11); break;
#ifndef C12nodef
case 12: CTL_SET_LO(C12bank,C12); break;
#endif
#ifndef C13nodef
case 13: CTL_SET_LO(C13bank,C13);
#ifdef PURPLE_KAZZO
CTL_SET_LO(C3bank,C3);
#endif
break;
#endif
#ifndef C14nodef
case 14: CTL_SET_LO(C14bank,C14); break;
#endif
#ifndef C15nodef
case 15: CTL_SET_LO(C15bank,C15); break;
#endif
#ifndef C16nodef
case 16: CTL_SET_LO(C16bank,C16); break;
#endif
#ifndef C17nodef
case 17: CTL_SET_LO(C17bank,C17); break;
#endif
#ifndef C18nodef
case 18: CTL_SET_LO(C18bank,C18); break;
#endif
#ifndef C19nodef
case 19: CTL_SET_LO(C19bank,C19); break;
#endif
#ifndef C20nodef
case 20: CTL_SET_LO(C20bank,C20); break;
#endif
case 21: CTL_SET_LO(C21bank,C21); break;
default: return ERR_CTL_PIN_NOT_PRESENT;
}
break;
case CTL_SET_HI_:
switch ( operand ) {
case 0: CTL_SET_HI(C0bank, C0); break;
case 1: CTL_SET_HI(C1bank, C1); break;
case 2: CTL_SET_HI(C2bank, C2); break;
#ifndef C3nodef
case 3: CTL_SET_HI(C3bank, C3); break;
#endif
case 4: CTL_SET_HI(C4bank, C4); break;
case 5: CTL_SET_HI(C5bank, C5); break;
case 6: CTL_SET_HI(C6bank, C6); break;
#ifndef C7nodef
case 7: CTL_SET_HI(C7bank, C7); break;
#endif
case 8: CTL_SET_HI(C8bank, C8); break;
case 9: CTL_SET_HI(C9bank, C9); break;
case 10: CTL_SET_HI(C10bank,C10); break;
case 11: CTL_SET_HI(C11bank,C11); break;
#ifndef C12nodef
case 12: CTL_SET_HI(C12bank,C12); break;
#endif
#ifndef C13nodef
case 13: CTL_SET_HI(C13bank,C13);
#ifdef PURPLE_KAZZO
CTL_SET_HI(C3bank,C3);
#endif
break;
#endif
#ifndef C14nodef
case 14: CTL_SET_HI(C14bank,C14); break;
#endif
#ifndef C15nodef
case 15: CTL_SET_HI(C15bank,C15); break;
#endif
#ifndef C16nodef
case 16: CTL_SET_HI(C16bank,C16); break;
#endif
#ifndef C17nodef
case 17: CTL_SET_HI(C17bank,C17); break;
#endif
#ifndef C18nodef
case 18: CTL_SET_HI(C18bank,C18); break;
#endif
#ifndef C19nodef
case 19: CTL_SET_HI(C19bank,C19); break;
#endif
#ifndef C20nodef
case 20: CTL_SET_HI(C20bank,C20); break;
#endif
case 21: CTL_SET_HI(C21bank,C21); break;
default: return ERR_CTL_PIN_NOT_PRESENT;
}
break;
case CTL_RD_:
rdata[RD_LEN] = HWORD_LEN;
switch ( operand ) {
case 0: CTL_RD(C0bank, C0, *ret_hword); break;
case 1: CTL_RD(C1bank, C1, *ret_hword); break;
case 2: CTL_RD(C2bank, C2, *ret_hword); break;
#ifndef C3nodef
case 3: CTL_RD(C3bank, C3, *ret_hword); break;
#endif
case 4: CTL_RD(C4bank, C4, *ret_hword); break;
case 5: CTL_RD(C5bank, C5, *ret_hword); break;
case 6: CTL_RD(C6bank, C6, *ret_hword); break;
#ifndef C7nodef
case 7: CTL_RD(C7bank, C7, *ret_hword); break;
#endif
case 8: CTL_RD(C8bank, C8, *ret_hword); break;
case 9: CTL_RD(C9bank, C9, *ret_hword); break;
case 10: CTL_RD(C10bank,C10, *ret_hword); break;
case 11: CTL_RD(C11bank,C11, *ret_hword); break;
#ifndef C12nodef
case 12: CTL_RD(C12bank,C12, *ret_hword); break;
#endif
#ifndef C13nodef
case 13: CTL_RD(C13bank,C13, *ret_hword); break;
#endif
#ifndef C14nodef
case 14: CTL_RD(C14bank,C14, *ret_hword); break;
#endif
#ifndef C15nodef
case 15: CTL_RD(C15bank,C15, *ret_hword); break;
#endif
#ifndef C16nodef
case 16: CTL_RD(C16bank,C16, *ret_hword); break;
#endif
#ifndef C17nodef
case 17: CTL_RD(C17bank,C17, *ret_hword); break;
#endif
#ifndef C18nodef
case 18: CTL_RD(C18bank,C18, *ret_hword); break;
#endif
#ifndef C19nodef
case 19: CTL_RD(C19bank,C19, *ret_hword); break;
#endif
#ifndef C20nodef
case 20: CTL_RD(C20bank,C20, *ret_hword); break;
#endif
case 21: CTL_RD(C21bank,C21, *ret_hword); break;
default: rdata[RD_LEN] = 0;
return ERR_CTL_PIN_NOT_PRESENT;
}
break;
//============================
//DATA PORT BYTE WIDE ACCESS
//opcode: type of operation
//operand: value to place on bus
//============================
case DATA_ENABLE_: DATA_ENABLE(); break;
case DATA_IP_PU_: DATA_IP_PU(); break;
case DATA_IP_: DATA_IP(); break;
case DATA_OP_: DATA_OP(); break;
case DATA_SET_: DATA_SET(operand); break;
case DATA_RD_: DATA_RD(rdata[RD0]);
rdata[RD_LEN] = 1; break;
//============================
//ADDR PORT 16bit WIDE ACCESS
//opcode: type of operation
//operand: value to place on bus
//============================
case ADDR_ENABLE_: ADDR_ENABLE(); break;
case ADDR_PU_: ADDR_PU(); break;
case ADDR_IP_: ADDR_IP(); break;
case ADDR_OP_: ADDR_OP(); break;
case ADDR_SET_: ADDR_SET(operand); break;
//============================
//EXP PORT 8bit ACCESS (bits1-8)
//opcode: type of operation
//operand: value to place on bus
//============================
case EXP_ENABLE_: EXP_ENABLE(); break;
case EXP_DISABLE_: EXP_DISABLE(); break;
case EXP_SET_: EXP_SET(operand); break;
//============================
//HIGH ADDR PORT 8bit WIDE ACCESS
//opcode: type of operation
//operand: value to place on bus
//============================
case HADDR_ENABLE_: HADDR_ENABLE(); break;
case HADDR_DISABLE_: HADDR_DISABLE(); break;
case HADDR_SET_: HADDR_SET(operand); break;
default:
//macro doesn't exist or isn't on this PCB version
return ERR_UNKN_PP_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 "Dbank->PORT"
* we need to juggle this data around and not stomp on anything
* Pre: DATA_OP() set
* curAHLaddr set by software_AHL_CLK
* Dbank->PORT 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
* Dbank->PORT and ALbank->PORT 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
curAXLaddr = Dbank->PORT; //This is desired AXL value
uint8_t orig_addr = ALbank->PORT; //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
Dbank->PORT = curAHLaddr;
//set ADDR as O/P and place desired value on bus
ADDR_OP(); //prob already be set, but in case not
ALbank->PORT = curAXLaddr;
//Clock both latches
AHL_OP(); //can't be sure "AHL" is OP as assumption is AXL will be used as latch
AHL_LO(); //can't be sure it's low either
//_AXHL_CLK(); //clock values
CTL_SET_HI(AHLbank, AHL); CTL_SET_LO(AHLbank, AHL);
//finally restore original DATA & ADDR values
Dbank->PORT = curAXLaddr;
ALbank->PORT = 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
* Dbank->PORT 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
* Dbank->PORT and ALbank->PORT replaced with original values
* AXHL left as O/P and ready for subsequent CLK
*/
void software_AHL_CLK()
{
//first store current DATA & ADDR values
curAHLaddr = Dbank->PORT; //This is desired AHL value (store it for other function's use)
uint8_t orig_addr = ALbank->PORT; //PORTA
//Desired AHL latch value should have already been placed on Dbank->PORT.
//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
ALbank->PORT = 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
CTL_SET_HI(AHLbank, AHL); CTL_SET_LO(AHLbank, AHL);
//finally restore original DATA & ADDR values
//never changed: Dbank->PORT = curAHLaddr;
ALbank->PORT = orig_addr;
}
#endif //GREEN_KAZZO