/**************************************************** * FUNCTION: Clear interrupt for Galois GPIO pin * PARAMS: port - GPIO port # (0 ~ 31) * RETURN: 0 - succeed. * -1 - fail. ***************************************************/ int GPIO_PortClearInterrupt(int port) { int reg_eoi; int value, gpio_port = port; if((port >= 0) && (port < 8)){ reg_eoi = APB_GPIO_INST0_BASE + APB_GPIO_PORTA_EOI; } else if ((port >= 8) && (port < 16)){ reg_eoi = APB_GPIO_INST1_BASE + APB_GPIO_PORTA_EOI; port -= 8; } else if ((port >= 16) && (port < 24)){ reg_eoi = APB_GPIO_INST2_BASE + APB_GPIO_PORTA_EOI; port -= 16; } else if ((port >= 24) && (port < 32)){ reg_eoi = APB_GPIO_INST3_BASE + APB_GPIO_PORTA_EOI; port -= 24; } else return -1; GPIO_PortLock(gpio_port); /* see above, write 1 to clear interrupt */ value = (1 << port); GA_REG_WORD32_WRITE(reg_eoi, value); GPIO_PortUnlock(gpio_port); return 0; }
/**************************************************** * FUNCTION: Enable interrupt for Galois GPIO pin * PARAMS: port - GPIO port # (0 ~ 31) * RETURN: 0 - succeed * -1 - fail * NOTE: You also need to enable GPIO interrupt in ICTL. ***************************************************/ int GPIO_PortEnableIRQ(int port) { int reg_mask, reg_en, reg_eoi; int value, gpio_port = port; if((port >= 0) && (port < 8)){ reg_mask = APB_GPIO_INST0_BASE + APB_GPIO_INTMASK; reg_en = APB_GPIO_INST0_BASE + APB_GPIO_INTEN; reg_eoi = APB_GPIO_INST0_BASE + APB_GPIO_PORTA_EOI; } else if ((port >= 8) && (port < 16)){ reg_mask = APB_GPIO_INST1_BASE + APB_GPIO_INTMASK; reg_en = APB_GPIO_INST1_BASE + APB_GPIO_INTEN; reg_eoi = APB_GPIO_INST1_BASE + APB_GPIO_PORTA_EOI; port -= 8; } else if ((port >= 16) && (port < 24)){ reg_mask = APB_GPIO_INST2_BASE + APB_GPIO_INTMASK; reg_en = APB_GPIO_INST2_BASE + APB_GPIO_INTEN; reg_eoi = APB_GPIO_INST2_BASE + APB_GPIO_PORTA_EOI; port -= 16; } else if ((port >= 24) && (port < 32)){ reg_mask = APB_GPIO_INST3_BASE + APB_GPIO_INTMASK; reg_en = APB_GPIO_INST3_BASE + APB_GPIO_INTEN; reg_eoi = APB_GPIO_INST3_BASE + APB_GPIO_PORTA_EOI; port -= 24; } else return -1; GPIO_PortLock(gpio_port); /* Enable interrupt */ GA_REG_WORD32_READ(reg_en, &value); value |= (1 << port); GA_REG_WORD32_WRITE(reg_en, value); /* Write-only, write 1 to clear interrupt */ value = (1 << port); GA_REG_WORD32_WRITE(reg_eoi, value); /* Unmask interrupt */ GA_REG_WORD32_READ(reg_mask, &value); value &= ~(1 << port); GA_REG_WORD32_WRITE(reg_mask, value); GPIO_PortUnlock(gpio_port); return 0; }
/**************************************************** * FUNCTION: toggle GPIO port between high and low * PARAMS: port - GPIO port # (0 ~ 31) * value - 1: high; 0: low * RETURN: 0 - succeed * -1 - fail ***************************************************/ int GPIO_PortWrite(int port, int value) { int reg_ddr, reg_dr, gpio_port = port; int ddr, dr; if((port >= 0) && (port < 8)){ reg_ddr = APB_GPIO_INST0_BASE + APB_GPIO_SWPORTA_DDR; reg_dr = APB_GPIO_INST0_BASE + APB_GPIO_SWPORTA_DR; } else if ((port >= 8) && (port < 16)){ reg_ddr = APB_GPIO_INST1_BASE + APB_GPIO_SWPORTA_DDR; reg_dr = APB_GPIO_INST1_BASE + APB_GPIO_SWPORTA_DR; port -= 8; } else if ((port >= 16) && (port < 24)){ reg_ddr = APB_GPIO_INST2_BASE + APB_GPIO_SWPORTA_DDR; reg_dr = APB_GPIO_INST2_BASE + APB_GPIO_SWPORTA_DR; port -= 16; } else if ((port >= 24) && (port < 32)){ reg_ddr = APB_GPIO_INST3_BASE + APB_GPIO_SWPORTA_DDR; reg_dr = APB_GPIO_INST3_BASE + APB_GPIO_SWPORTA_DR; port -= 24; } else return -1; GPIO_PortLock(gpio_port); /* set port to output mode */ GA_REG_WORD32_READ(reg_ddr, &ddr); ddr |= (1<<port); GA_REG_WORD32_WRITE(reg_ddr, ddr); /* set port value */ GA_REG_WORD32_READ(reg_dr, &dr); if (value){ dr |= (1<<port); } else { dr &= ~(1<<port); } GA_REG_WORD32_WRITE(reg_dr, dr); GPIO_PortUnlock(gpio_port); return 0; }
/**************************************************** * FUNCTION: Set Galois GPIO pin as in or out * PARAMS: port - GPIO port # (0 ~ 31) * in - 1: IN, 0: OUT * RETURN: 0 - succeed * -1 - fail ***************************************************/ int GPIO_PortSetInOut(int port, int in) { int reg_ddr, reg_ctl, gpio_port = port; int ddr, ctl; if((port >= 0) && (port < 8)){ reg_ddr = APB_GPIO_INST0_BASE + APB_GPIO_SWPORTA_DDR; reg_ctl = APB_GPIO_INST0_BASE + APB_GPIO_PORTA_CTL; } else if ((port >= 8) && (port < 16)){ reg_ddr = APB_GPIO_INST1_BASE + APB_GPIO_SWPORTA_DDR; reg_ctl = APB_GPIO_INST1_BASE + APB_GPIO_PORTA_CTL; port -= 8; } else if ((port >= 16) && (port < 24)){ reg_ddr = APB_GPIO_INST2_BASE + APB_GPIO_SWPORTA_DDR; reg_ctl = APB_GPIO_INST2_BASE + APB_GPIO_PORTA_CTL; port -= 16; } else if ((port >= 24) && (port < 32)){ reg_ddr = APB_GPIO_INST3_BASE + APB_GPIO_SWPORTA_DDR; reg_ctl = APB_GPIO_INST3_BASE + APB_GPIO_PORTA_CTL; port -= 24; } else return -1; GPIO_PortLock(gpio_port); /* software mode */ GA_REG_WORD32_READ(reg_ctl, &ctl); ctl &= ~(1 << port); GA_REG_WORD32_WRITE(reg_ctl, ctl); /* set port to output mode */ GA_REG_WORD32_READ(reg_ddr, &ddr); if (in) ddr &= ~(1 << port); else ddr |= (1 << port); GA_REG_WORD32_WRITE(reg_ddr, ddr); GPIO_PortUnlock(gpio_port); return 0; }
/**************************************************** * FUNCTION: read GPIO port status * PARAMS: port - GPIO port # (0 ~ 31) * *value - pointer to port status * RETURN: 0 - succeed * -1 - fail ***************************************************/ int GPIO_PortRead(int port, int *value) { int reg_ddr, reg_ext, gpio_port = port; int ddr, ext; if((port >= 0) && (port < 8)){ reg_ddr = APB_GPIO_INST0_BASE + APB_GPIO_SWPORTA_DDR; reg_ext = APB_GPIO_INST0_BASE + APB_GPIO_EXT_PORTA; } else if ((port >= 8) && (port < 16)){ reg_ddr = APB_GPIO_INST1_BASE + APB_GPIO_SWPORTA_DDR; reg_ext = APB_GPIO_INST1_BASE + APB_GPIO_EXT_PORTA; port -= 8; } else if ((port >= 16) && (port < 24)){ reg_ddr = APB_GPIO_INST2_BASE + APB_GPIO_SWPORTA_DDR; reg_ext = APB_GPIO_INST2_BASE + APB_GPIO_EXT_PORTA; port -= 16; } else if ((port >= 24) && (port < 32)){ reg_ddr = APB_GPIO_INST3_BASE + APB_GPIO_SWPORTA_DDR; reg_ext = APB_GPIO_INST3_BASE + APB_GPIO_EXT_PORTA; port -= 24; } else return -1; GPIO_PortLock(gpio_port); /* set port to input mode */ GA_REG_WORD32_READ(reg_ddr, &ddr); ddr &= ~(1<<port); GA_REG_WORD32_WRITE(reg_ddr, ddr); /* get port value */ GA_REG_WORD32_READ(reg_ext, &ext); if (ext & (1<<port)) *value = 1; else *value = 0; GPIO_PortUnlock(gpio_port); return 0; }
/**************************************************** * FUNCTION: Disable interrupt for Galois GPIO pin * PARAMS: port - GPIO port # (0 ~ 31) * RETURN: 0 - succeed * -1 - fail ***************************************************/ int GPIO_PortDisableIRQ(int port) { int reg_mask, reg_en; int value, gpio_port = port; if((port >= 0) && (port < 8)){ reg_mask = APB_GPIO_INST0_BASE + APB_GPIO_INTMASK; reg_en = APB_GPIO_INST0_BASE + APB_GPIO_INTEN; } else if ((port >= 8) && (port < 16)){ reg_mask = APB_GPIO_INST1_BASE + APB_GPIO_INTMASK; reg_en = APB_GPIO_INST1_BASE + APB_GPIO_INTEN; port -= 8; } else if ((port >= 16) && (port < 24)){ reg_mask = APB_GPIO_INST2_BASE + APB_GPIO_INTMASK; reg_en = APB_GPIO_INST2_BASE + APB_GPIO_INTEN; port -= 16; } else if ((port >= 24) && (port < 32)){ reg_mask = APB_GPIO_INST3_BASE + APB_GPIO_INTMASK; reg_en = APB_GPIO_INST3_BASE + APB_GPIO_INTEN; port -= 24; } else return -1; GPIO_PortLock(gpio_port); /* Mask interrupt */ GA_REG_WORD32_READ(reg_mask, &value); value |= (1 << port); GA_REG_WORD32_WRITE(reg_mask, value); /* Disable interrupt */ GA_REG_WORD32_READ(reg_en, &value); value &= ~(1 << port); GA_REG_WORD32_WRITE(reg_en, value); GPIO_PortUnlock(gpio_port); return 0; }
/**************************************************** * FUNCTION: Init interrupt for Galois GPIO pin, and set * interrupt level or edge, but keep interrupt closed. * PARAMS: port - GPIO port # (0 ~ 31) * int_edge - 1: edge triggered, 0: level triggered. * int_polarity - 1: rise edge/high level triggered. * 0: fall edge/low level triggered. * RETURN: 0 - succeed * -1 - fail ***************************************************/ int GPIO_PortInitIRQ(int port, int int_edge, int int_polarity) { int reg_ddr, reg_debounce, reg_edge, reg_polarity; int reg_mask;//, reg_en, reg_eoi; int value, gpio_port = port; if((port >= 0) && (port < 8)){ reg_ddr = APB_GPIO_INST0_BASE + APB_GPIO_SWPORTA_DDR; reg_mask = APB_GPIO_INST0_BASE + APB_GPIO_INTMASK; //reg_en = APB_GPIO_INST0_BASE + APB_GPIO_INTEN; //reg_eoi = APB_GPIO_INST0_BASE + APB_GPIO_PORTA_EOI; reg_debounce = APB_GPIO_INST0_BASE + APB_GPIO_DEBOUNCE; reg_edge = APB_GPIO_INST0_BASE + APB_GPIO_INTTYPE_LEVEL; reg_polarity = APB_GPIO_INST0_BASE + APB_GPIO_INT_POLARITY; } else if ((port >= 8) && (port < 16)){ reg_ddr = APB_GPIO_INST1_BASE + APB_GPIO_SWPORTA_DDR; reg_mask = APB_GPIO_INST1_BASE + APB_GPIO_INTMASK; //reg_en = APB_GPIO_INST1_BASE + APB_GPIO_INTEN; //reg_eoi = APB_GPIO_INST1_BASE + APB_GPIO_PORTA_EOI; reg_debounce = APB_GPIO_INST1_BASE + APB_GPIO_DEBOUNCE; reg_edge = APB_GPIO_INST1_BASE + APB_GPIO_INTTYPE_LEVEL; reg_polarity = APB_GPIO_INST1_BASE + APB_GPIO_INT_POLARITY; port -= 8; } else if ((port >= 16) && (port < 24)){ reg_ddr = APB_GPIO_INST2_BASE + APB_GPIO_SWPORTA_DDR; reg_mask = APB_GPIO_INST2_BASE + APB_GPIO_INTMASK; //reg_en = APB_GPIO_INST2_BASE + APB_GPIO_INTEN; //reg_eoi = APB_GPIO_INST2_BASE + APB_GPIO_PORTA_EOI; reg_debounce = APB_GPIO_INST2_BASE + APB_GPIO_DEBOUNCE; reg_edge = APB_GPIO_INST2_BASE + APB_GPIO_INTTYPE_LEVEL; reg_polarity = APB_GPIO_INST2_BASE + APB_GPIO_INT_POLARITY; port -= 16; } else if ((port >= 24) && (port < 32)){ reg_ddr = APB_GPIO_INST3_BASE + APB_GPIO_SWPORTA_DDR; reg_mask = APB_GPIO_INST3_BASE + APB_GPIO_INTMASK; //reg_en = APB_GPIO_INST3_BASE + APB_GPIO_INTEN; //reg_eoi = APB_GPIO_INST3_BASE + APB_GPIO_PORTA_EOI; reg_debounce = APB_GPIO_INST3_BASE + APB_GPIO_DEBOUNCE; reg_edge = APB_GPIO_INST3_BASE + APB_GPIO_INTTYPE_LEVEL; reg_polarity = APB_GPIO_INST3_BASE + APB_GPIO_INT_POLARITY; port -= 24; } else return -1; GPIO_PortLock(gpio_port); /* Mask interrupt */ GA_REG_WORD32_READ(reg_mask, &value); value |= (1 << port); GA_REG_WORD32_WRITE(reg_mask, value); /* Direction is input */ GA_REG_WORD32_READ(reg_ddr, &value); value &= ~(1 << port); GA_REG_WORD32_WRITE(reg_ddr, value); /* Enable debounce */ GA_REG_WORD32_READ(reg_debounce, &value); value |= (1 << port); GA_REG_WORD32_WRITE(reg_debounce, value); /* int_edge=1: Edge triggered interrupt */ GA_REG_WORD32_READ(reg_edge, &value); value |= (int_edge << port); GA_REG_WORD32_WRITE(reg_edge, value); /* int_polarity=1: rise-edge triggered interrupt */ GA_REG_WORD32_READ(reg_polarity, &value); value |= (int_polarity << port); GA_REG_WORD32_WRITE(reg_polarity, value); /* Enable interrupt */ //GA_REG_WORD32_READ(reg_en, &value); //value |= (1 << port); //GA_REG_WORD32_WRITE(reg_en, value); /* Write-only, write 1 to clear interrupt */ //value = (1 << port); //GA_REG_WORD32_WRITE(reg_eoi, value); /* Unmask interrupt */ //GA_REG_WORD32_READ(reg_mask, &value); //value &= ~(1 << port); //GA_REG_WORD32_WRITE(reg_mask, value); GPIO_PortUnlock(gpio_port); return 0; }
/**************************************************** * FUNCTION: toggle GPIO port between high and low * PARAMS: port - GPIO port # (0 ~ 31) * value - 1: high; 0: low * RETURN: 0 - succeed * -1 - fail ***************************************************/ int GPIO_PortWrite(int port, int value) { int reg_ddr, reg_dr, gpio_port = port; int ddr, dr; #if defined(CONFIG_BERLIN2Q) || defined(CONFIG_BERLIN2CDP) if((port >= 0) && (port < 32)){ #else if((port >= 0) && (port < 8)){ #endif reg_ddr = APB_GPIO_INST0_BASE + APB_GPIO_SWPORTA_DDR; reg_dr = APB_GPIO_INST0_BASE + APB_GPIO_SWPORTA_DR; #if defined(CONFIG_BERLIN2Q) || defined(CONFIG_BERLIN2CDP) } else if ((port >= 32) && (port < 64)){ #else } else if ((port >= 8) && (port < 16)){ #endif reg_ddr = APB_GPIO_INST1_BASE + APB_GPIO_SWPORTA_DDR; reg_dr = APB_GPIO_INST1_BASE + APB_GPIO_SWPORTA_DR; #if defined(CONFIG_BERLIN2Q) || defined(CONFIG_BERLIN2CDP) port -= 32; } else if ((port >= 64) && (port < 96)){ #else port -= 8; } else if ((port >= 16) && (port < 24)){ #endif reg_ddr = APB_GPIO_INST2_BASE + APB_GPIO_SWPORTA_DDR; reg_dr = APB_GPIO_INST2_BASE + APB_GPIO_SWPORTA_DR; #if defined(CONFIG_BERLIN2Q) || defined(CONFIG_BERLIN2CDP) port -= 64; } else if ((port >= 96) && (port < 128)){ #else port -= 16; } else if ((port >= 24) && (port < 32)){ #endif reg_ddr = APB_GPIO_INST3_BASE + APB_GPIO_SWPORTA_DDR; reg_dr = APB_GPIO_INST3_BASE + APB_GPIO_SWPORTA_DR; #if defined(CONFIG_BERLIN2Q) || defined(CONFIG_BERLIN2CDP) port -= 96; #else port -= 24; #endif } else return -1; GPIO_PortLock(gpio_port); /* set port to output mode */ GA_REG_WORD32_READ(reg_ddr, &ddr); ddr |= (1<<port); GA_REG_WORD32_WRITE(reg_ddr, ddr); /* set port value */ GA_REG_WORD32_READ(reg_dr, &dr); if (value){ dr |= (1<<port); } else { dr &= ~(1<<port); } GA_REG_WORD32_WRITE(reg_dr, dr); GPIO_PortUnlock(gpio_port); return 0; } /**************************************************** * FUNCTION: read GPIO port status * PARAMS: port - GPIO port # (0 ~ 31) * *value - pointer to port status * RETURN: 0 - succeed * -1 - fail ***************************************************/ int GPIO_PortRead(int port, int *value) { int reg_ddr, reg_ext, gpio_port = port; int ddr, ext; #if defined(CONFIG_BERLIN2Q) || defined(CONFIG_BERLIN2CDP) if((port >= 0) && (port < 32)){ #else if((port >= 0) && (port < 8)){ #endif reg_ddr = APB_GPIO_INST0_BASE + APB_GPIO_SWPORTA_DDR; reg_ext = APB_GPIO_INST0_BASE + APB_GPIO_EXT_PORTA; #if defined(CONFIG_BERLIN2Q) || defined(CONFIG_BERLIN2CDP) } else if ((port >= 32) && (port < 64)){ #else } else if ((port >= 8) && (port < 16)){ #endif reg_ddr = APB_GPIO_INST1_BASE + APB_GPIO_SWPORTA_DDR; reg_ext = APB_GPIO_INST1_BASE + APB_GPIO_EXT_PORTA; #if defined(CONFIG_BERLIN2Q) || defined(CONFIG_BERLIN2CDP) port -= 32; } else if ((port >= 64) && (port < 96)){ #else port -= 8; } else if ((port >= 16) && (port < 24)){ #endif reg_ddr = APB_GPIO_INST2_BASE + APB_GPIO_SWPORTA_DDR; reg_ext = APB_GPIO_INST2_BASE + APB_GPIO_EXT_PORTA; #if defined(CONFIG_BERLIN2Q) || defined(CONFIG_BERLIN2CDP) port -= 64; } else if ((port >= 96) && (port < 128)){ #else port -= 16; } else if ((port >= 24) && (port < 32)){ #endif reg_ddr = APB_GPIO_INST3_BASE + APB_GPIO_SWPORTA_DDR; reg_ext = APB_GPIO_INST3_BASE + APB_GPIO_EXT_PORTA; #if defined(CONFIG_BERLIN2Q) || defined(CONFIG_BERLIN2CDP) port -= 96; #else port -= 24; #endif } else return -1; GPIO_PortLock(gpio_port); /* set port to input mode */ GA_REG_WORD32_READ(reg_ddr, &ddr); ddr &= ~(1<<port); GA_REG_WORD32_WRITE(reg_ddr, ddr); /* get port value */ GA_REG_WORD32_READ(reg_ext, &ext); if (ext & (1<<port)) *value = 1; else *value = 0; GPIO_PortUnlock(gpio_port); return 0; } /**************************************************** * FUNCTION: Set Galois GPIO pin as in or out * PARAMS: port - GPIO port # (0 ~ 31) * in - 1: IN, 0: OUT * RETURN: 0 - succeed * -1 - fail ***************************************************/ int GPIO_PortSetInOut(int port, int in) { int reg_ddr, reg_ctl, gpio_port = port; int ddr, ctl; #if defined(CONFIG_BERLIN2CDP) if((port >= 0) && (port < 32)){ #else if((port >= 0) && (port < 8)){ #endif reg_ddr = APB_GPIO_INST0_BASE + APB_GPIO_SWPORTA_DDR; reg_ctl = APB_GPIO_INST0_BASE + APB_GPIO_PORTA_CTL; #if defined(CONFIG_BERLIN2CDP) } else if ((port >= 32) && (port < 64)){ #else } else if ((port >= 8) && (port < 16)){ #endif reg_ddr = APB_GPIO_INST1_BASE + APB_GPIO_SWPORTA_DDR; reg_ctl = APB_GPIO_INST1_BASE + APB_GPIO_PORTA_CTL; #if defined(CONFIG_BERLIN2CDP) port -= 32; #else port -= 8; } else if ((port >= 16) && (port < 24)){ reg_ddr = APB_GPIO_INST2_BASE + APB_GPIO_SWPORTA_DDR; reg_ctl = APB_GPIO_INST2_BASE + APB_GPIO_PORTA_CTL; port -= 16; } else if ((port >= 24) && (port < 32)){ reg_ddr = APB_GPIO_INST3_BASE + APB_GPIO_SWPORTA_DDR; reg_ctl = APB_GPIO_INST3_BASE + APB_GPIO_PORTA_CTL; port -= 24; #endif } else return -1; GPIO_PortLock(gpio_port); #if !defined(CONFIG_BERLIN2CDP) /* software mode */ GA_REG_WORD32_READ(reg_ctl, &ctl); ctl &= ~(1 << port); GA_REG_WORD32_WRITE(reg_ctl, ctl); #endif /* set port to output mode */ GA_REG_WORD32_READ(reg_ddr, &ddr); if (in) ddr &= ~(1 << port); else ddr |= (1 << port); GA_REG_WORD32_WRITE(reg_ddr, ddr); GPIO_PortUnlock(gpio_port); return 0; } /**************************************************** * FUNCTION: Get direction of Galois GPIO pin: in or out * PARAMS: port - GPIO port # (0 ~ 31) * *inout - PORT_DDR_IN: IN, PORT_DDR_OUT: OUT * RETURN: 0 - succeed * -1 - fail ***************************************************/ int GPIO_PortGetInOut(int port, int *inout) { int reg_ddr; if((port >= 0) && (port < 8)){ reg_ddr = APB_GPIO_INST0_BASE + APB_GPIO_SWPORTA_DDR; } else if ((port >= 8) && (port < 16)){ reg_ddr = APB_GPIO_INST1_BASE + APB_GPIO_SWPORTA_DDR; port -= 8; } else if ((port >= 16) && (port < 24)){ reg_ddr = APB_GPIO_INST2_BASE + APB_GPIO_SWPORTA_DDR; port -= 16; } else if ((port >= 24) && (port < 32)){ reg_ddr = APB_GPIO_INST3_BASE + APB_GPIO_SWPORTA_DDR; port -= 24; } else return -1; GA_REG_WORD32_READ(reg_ddr, inout); *inout = (*inout & (1 << port))? PORT_DDR_OUT : PORT_DDR_IN; return 0; }