/********************************************************************\ Name: gpio.c Created by: Stefan Ritt Contents: Driver for MCP23S17 General Purpose IO Chip \********************************************************************/ #include #include #include #include #include "mscbemb.h" #include "fe_cc.h" // register addresses for non-banked layout (bank=0) #define GPIO_IODIRA 0x00 #define GPIO_IODIRB 0x01 #define GPIO_IPOLA 0x02 #define GPIO_IPOLB 0x03 #define GPIO_GPINTENA 0x04 #define GPIO_GPINTENB 0x05 #define GPIO_DEFVALA 0x06 #define GPIO_DEFVALB 0x07 #define GPIO_INTCONA 0x08 #define GPIO_INTCONB 0x09 #define GPIO_IOCON 0x0A #define GPIO_GPPUA 0x0C #define GPIO_GPPUB 0x0D #define GPIO_INTFA 0x0E #define GPIO_INTFB 0x0F #define GPIO_INTCAPA 0x10 #define GPIO_INTCAPB 0x11 #define GPIO_GPIOA 0x12 #define GPIO_GPIOB 0x13 #define GPIO_OLATA 0x14 #define GPIO_OLATB 0x15 static unsigned char gpio_mask[4][2] = { { 0xFF, 0xFF }, { 0xFF, 0xFF }, { 0xFF, 0xFF }, { 0xFF, 0xFF } }; /*------------------------------------------------------------------*/ void gpio_init() { unsigned char i; // program all four devices as outputs for (i=0 ; i< 4 ; i++) { gpio_write(i, GPIO_IOCON, 1<<3); // HAEN = 1 gpio_write(i, GPIO_IODIRA, 0x00); gpio_write(i, GPIO_IODIRB, 0x00); } // set /select lines to default state (high) gpio_board_select(0xFF); // set init lines to high (inactive) gpio_out(3, 1, 1); gpio_out(3, 2, 1); gpio_out(3, 3, 1); // set BP mode gpio_bp_mode_sel(0); gpio_attention(0); } /*------------------------------------------------------------------*/ void gpio_write(unsigned char device, unsigned char adr, unsigned char d) { spi_adr(SPI_ADR_SR, 0); // Device opcode 0x40 combined 3-bit hardware address, R/W = 0 (=write) spi_write_msb(0x40 | ((device & 0x07) << 1)); spi_write_msb(adr); spi_write_msb(d); spi_adr(0, 1); } /*------------------------------------------------------------------*/ unsigned char gpio_read(unsigned char device, unsigned char adr) { unsigned char d; spi_adr(SPI_ADR_SR, 0); // Device opcode 0x40 combined 3-bit hardware address, R/W = 1 (=read) spi_write_msb(0x40 | ((device & 0x07) << 1) | 0x01); spi_write_msb(adr); d = spi_read_msb(); spi_adr(0, 1); return d; } /*------------------------------------------------------------------*/ void gpio_out(unsigned char device, unsigned char bit_no, unsigned char flag) { unsigned char port; // write one bit to device if (bit_no < 8) port = 0; else { port = 1; bit_no -= 8; } if (flag) gpio_mask[device][port] |= (1 << bit_no); else gpio_mask[device][port] &= ~(1 << bit_no); gpio_write(device, port == 0 ? GPIO_OLATA : GPIO_OLATB, gpio_mask[device][port]); } /*------------------------------------------------------------------*/ unsigned char gpio_in(unsigned char device, unsigned char port) { // read port through GPIOA (port==0) or GPIOB (port==1) return gpio_read(device, port == 0 ? GPIO_GPIOA : GPIO_GPIOB); } /*------------------------------------------------------------------*/ void gpio_board_power(unsigned char p[16]) { unsigned char d; for (d=0 ; d<16 ; d++) gpio_out(2, d, !(p[d] & 0x01)); } /*------------------------------------------------------------------*/ void gpio_board_select(unsigned char b) { unsigned char d; for (d=0 ; d<16 ; d++) gpio_out(0, d, d != b); // inverse polarity } /*------------------------------------------------------------------*/ void gpio_max_config_select(unsigned char flag) { gpio_out(3, 0, flag); } /*------------------------------------------------------------------*/ void gpio_reset_fpga() { gpio_out(3, 1, 0); // inverse polarity gpio_out(3, 1, 1); } /*------------------------------------------------------------------*/ void gpio_reset_cpu() { gpio_out(3, 2, 0); // inverse polarity gpio_out(3, 2, 1); } /*------------------------------------------------------------------*/ void gpio_reset_max() { gpio_out(3, 3, 0); // inverse polarity gpio_out(3, 3, 1); } /*------------------------------------------------------------------*/ void gpio_bp_mode_sel(unsigned char mode) { gpio_out(3, 4, (mode >> 0) & 1); gpio_out(3, 5, (mode >> 1) & 1); } /*------------------------------------------------------------------*/ void gpio_attention(unsigned char mode) { gpio_out(3, 10, !((mode >> 0) & 1)); // inverse polarity gpio_out(3, 11, !((mode >> 1) & 1)); // inverse polarity }