/* demonstrate a multiplexed display controlled via the PIO8255 */ // base address for the stack. This leaves very little space for // the stack, but means that you can watch program-code and stack // and heap accesses at the same time in the memory editor. // Remember that byte-address 0x800 is displayed at word-address 0x200 // in the RAM editor. #define STACKBASE 0x00000800 // base address for some debugging output in the RAM. // Remember that byte-address 0x880 is displayed at word-address 0x220 // in the RAM editor. #define BASE 0x00000880 // axxx.xxxx is mapped to 0xxx.xxxx by the (static) R-3000 MMU // but remains axxx.xxx in this demo because we disable the MMU. #define PIO_BASE 0xa0080000 #define PIO_REGA (PIO_BASE+0) #define PIO_REGB (PIO_BASE+4) #define PIO_REGC (PIO_BASE+8) #define PIO_XREG (PIO_BASE+12) #define PIO_MODE_CHANGE 0x80 #define PIO_GROUPA_MODE0 0x00 #define PIO_GROUPA_MODE1 0x20 #define PIO_GROUPA_MODE2 0x60 #define PIO_GROUPB_MODE0 0x00 #define PIO_GROUPB_MODE1 0x04 #define PIO_PORTA_INPUT 0x10 #define PIO_PORTA_OUTPUT 0x00 #define PIO_UPPERC_INPUT 0x08 #define PIO_UPPERC_OUTPUT 0x00 #define PIO_PORTB_INPUT 0x02 #define PIO_PORTB_OUTPUT 0x00 #define PIO_LOWERC_INPUT 0x01 #define PIO_LOWERC_OUTPUT 0x00 void pioSetMode( int value ) { int *xreg = (int*) PIO_XREG; int command = PIO_MODE_CHANGE | (value&0x000000ff); *xreg = command; } void pioWritePortA( int value ) { int *reg = (int*) PIO_REGA; int data = value & 0x000000ff; *reg = data; } void pioWritePortB( int value ) { int *reg = (int*) PIO_REGB; int data = value & 0x000000ff; *reg = data; } void pioWritePortC( int value ) { int *reg = (int*) PIO_REGC; int data = value & 0x000000ff; *reg = data; } void pioWriteUpperC( int value ) { int *reg = (int*) PIO_REGC; int data = (*reg & 0x0000000f) | value & 0x000000f0; *reg = data; } void pioWriteLowerC( int value ) { int *reg = (int*) PIO_REGC; int data = (*reg & 0x000000f0) | value & 0x0000000f; *reg = data; } int pioReadPortA() { int *reg = (int*) PIO_REGA; int data = *reg; return data; } int pioReadPortB() { int *reg = (int*) PIO_REGB; int data = *reg; return data; } int pioReadPortC() { int *reg = (int*) PIO_REGC; int data = *reg; return data; } /* +-A-+ F B +-G-+ E C +-D-+ (P) encoding is 0000....00 PGFEDCBA p is not driven by this routine. If necessary, OR the return value with mask 0x80. */ int sevenSegment( int value ) { switch( value ) { case 0: return 0x0000003f; // 00111111 case 1: return 0x00000006; // 00000110 case 2: return 0x0000005b; // 01011011 case 3: return 0x0000004f; // 01001111 case 4: return 0x00000066; // 01100110 case 5: return 0x0000006d; // 01101101 case 6: return 0x0000007d; // 01111101 case 7: return 0x00000007; // 00000111 case 8: return 0x0000007f; // 01111111 case 9: return 0x0000006f; // 01101111 case 0xa: return 0x00000077; // 01110111 case 0xb: return 0x0000007c; // 01111100 case 0xc: return 0x00000039; // 00111001 case 0xd: return 0x0000005e; // 01011110 case 0xe: return 0x00000079; // 01111001 case 0xf: return 0x00000071; // 01110001 default: // three horizontal bars as error indicator return 0x00000049; // 01001001 } } void waitLoop() { int i, limit; int *ptr; ptr = (int*) BASE; limit = 0x0015; for( i=0; i < limit; i++ ) { *ptr = i; } } void displayValue( int value ) { int tmp, mask, hex, segs, i; int ndigits = 5; int *ptr = (int*) BASE; *(ptr-1) = 0xdeadbeef; *(ptr-2) = value; mask = 0xf; for( i=0; i < ndigits; i++ ) { pioWritePortB( 0x00 ); // all digits off hex = value & mask; segs = sevenSegment( hex >> (i << 2) ); pioWritePortA( segs ); pioWritePortB( 1 << i ); // one digit on waitLoop(); mask = mask << 4; } pioWritePortB( 0 ); // disable all digits again } int main( int argc, char** argv ) { int count; pioSetMode( PIO_MODE_CHANGE | PIO_GROUPA_MODE0 | PIO_GROUPB_MODE0 | PIO_PORTA_OUTPUT | PIO_PORTB_OUTPUT | PIO_UPPERC_INPUT | PIO_LOWERC_INPUT ); for( count=0; ; count++ ) { displayValue( count ); } }