#include // #define RESETBUS /* 0xc0 = NOP 0xd0 = Addr 0xe0 = Write 0xf0 = Read */ /* outputs */ sbit STROBE = P3^7; /* clock pin is P3.7 */ sbit COM1 = P1^5; /* command1 pin is P1.5 */ sbit COM0 = P1^4; /* command0 pin is P1.4 */ sbit DATA3 = P1^3; /* data3 pin is P1.3 */ sbit DATA2 = P1^2; /* data2 pin is P1.2 */ sbit DATA1 = P1^1; /* data1 pin is P1.1 */ sbit DATA0 = P1^0; /* data0 pin is P1.0 */ #define NOPCOM 0x00 #define ADDRCOM 0x10 #define READCOM 0x30 #define WRITECOM 0x20 /* macro definitions */ #define AddrNibl0(addr)\ P1 = (0xC0 | ADDRCOM | (addr & 0xf)); \ STROBE = 1; STROBE = 0; /* clock it */ #define AddrNibl1(addr)\ P1 = (0xC0 | ADDRCOM | ((addr>>4) & 0xf));\ STROBE = 1; STROBE = 0; /* clock it */ #define AddrNibl2(addr)\ P1 = (0xC0 | ADDRCOM | ((addr>>8) & 0xf));\ STROBE = 1; STROBE = 0; /* clock it */ #define AddrNibl3(addr)\ P1 = (0xC0 | ADDRCOM | ((addr>>12) & 0xf));\ STROBE = 1; STROBE = 0; /* clock it */ #define WriteNibl0(value)\ P1 = (0xC0 | WRITECOM | (value & 0xf));\ STROBE = 1; STROBE = 0; /* clock it */ // The FPGA pulls down on STROBE to cause us to wait #define WriteNibl1(value) \ P1 =(0xC0 | WRITECOM | ((value>>4) & 0xf)); \ STROBE = 1; \ while (STROBE==0) {}; /* Wait for FPGA to release STROBE */ \ STROBE = 0; // We have to tristate the data lines with the 0xf // The FPGA pulls down on STROBE until the read data is ready #define ReadNibl0(value) \ P1 = (0xC0 | READCOM | 0xf); /* Remember to tristate data lines! */ \ STROBE = 1; /* clock it */ \ while ( STROBE==0 ) {} /* Wait until FPGA is ready */ \ value = (P1 & 0x0f); \ STROBE = 0; #define ReadNibl1(value)\ P1 = (0xC0 | READCOM | 0xf); /* Remember to tristate data lines */ \ STROBE = 1; /* clock it */\ value = ((P1 << 4) | value); \ STROBE = 0; unsigned char XRead(unsigned int address) { unsigned char value; /* 16 bits of address */ AddrNibl0(address); AddrNibl1(address); AddrNibl2(address); AddrNibl3(address); /* read the data bits back */ ReadNibl0(value); ReadNibl1(value); return value; } void XWrite(unsigned int address, unsigned char value) { /* 16 bits of address */ AddrNibl0(address); AddrNibl1(address); AddrNibl2(address); AddrNibl3(address); /* Send the data */ WriteNibl0(value); WriteNibl1(value); } // Initialize the Xbus by issuing a bunch of NOPs to get // the FPGA state machine into the idle mode void XInit() { P1 = 0xff; // Tristate port 1 STROBE = 0; // Start with strobe low P1 = (0xC0 | NOPCOM ); STROBE = 1; STROBE = 0; /* clock it */ P1 = (0xC0 | NOPCOM ); STROBE = 1; STROBE = 0; /* clock it */ P1 = (0xC0 | NOPCOM ); STROBE = 1; STROBE = 0; /* clock it */ P1 = (0xC0 | NOPCOM ); STROBE = 1; STROBE = 0; /* clock it */ P1 = (0xC0 | NOPCOM ); STROBE = 1; STROBE = 0; /* clock it */ P1 = (0xC0 | NOPCOM ); STROBE = 1; STROBE = 0; /* clock it */ P1 = (0xC0 | NOPCOM ); STROBE = 1; STROBE = 0; /* clock it */ P1 = (0xC0 | NOPCOM ); STROBE = 1; STROBE = 0; /* clock it */ } unsigned char XReadCont() { unsigned char value; ReadNibl0(value); ReadNibl1(value); return value; }