/**************************************************** * FUNCTION: Disable interrupt for Galois SM_GPIO pin * PARAMS: port - SM_GPIO port # (0 ~ 7) * RETURN: 0 - succeed * -1 - fail ***************************************************/ int SM_GPIO_PortDisableIRQ(int port) { int reg_mask, reg_en; int value, gpio_port = port; if((port >= 0) && (port < 8)){ reg_mask = SM_APB_GPIO_BASE + APB_GPIO_INTMASK; reg_en = SM_APB_GPIO_BASE + APB_GPIO_INTEN; } else if ((port >= 8) && (port < MAX_PORT)){ reg_mask = SM_APB_GPIO1_BASE + APB_GPIO_INTMASK; reg_en = SM_APB_GPIO1_BASE + APB_GPIO_INTEN; port -= 8; } else { return -1; } SM_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); SM_GPIO_PortUnlock(gpio_port); return 0; }
/******************************************************************************* * Function: PIC_SetPerPIC_TgtGIntE * * Description: Set all of perPIC registers at once. (Target) * * Inputs: PIC_num-- PIC number. * fGIntE--------FIQ globale interrupt enable bit. 1-- enable, 0 -- disable * nGIntE--------IRQ globale interrupt enable bit. 1-- enable, 0 -- disable * Outputs: none * * Return: none *******************************************************************************/ void PIC_SetPerPIC_TgtGIntE(UNSG32 PIC_num, UNSG32 fGIntE, UNSG32 nGIntE) { UNSG32 base_addr=MEMMAP_PIC_REG_BASE+PIC_num*sizeof(SIE_perPIC); GA_REG_WORD32_WRITE(base_addr+RA_perPIC_fGIntE, fGIntE); GA_REG_WORD32_WRITE(base_addr+RA_perPIC_nGIntE, nGIntE); }
/**************************************************** * FUNCTION: Set Galois SM_GPIO pin as in or out * PARAMS: port - SM_GPIO port # (0 ~ 11) * in - 1: IN, 0: OUT * RETURN: 0 - succeed * -1 - fail ***************************************************/ int SM_GPIO_PortSetInOut(int port, int in) { int reg_ddr, reg_ctl; int ddr, ctl; if((port >= 0) && (port < 8)){ reg_ddr = SM_APB_GPIO_BASE + APB_GPIO_SWPORTA_DDR; reg_ctl = SM_APB_GPIO_BASE + APB_GPIO_PORTA_CTL; } else if ((port >= 8) && (port < 12)){ #if (BERLIN_CHIP_VERSION >= BERLIN_C_0) reg_ddr = SM_APB_GPIO1_BASE + APB_GPIO_SWPORTA_DDR; reg_ctl = SM_APB_GPIO1_BASE + APB_GPIO_PORTA_CTL; #else reg_ddr = SM_APB_GPIO_BASE + APB_GPIO_SWPORTB_DDR; reg_ctl = SM_APB_GPIO_BASE + APB_GPIO_PORTB_CTL; #endif port -= 8; } else return -1; /* 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); return 0; }
/******************************************************************************* * Function: PIC_SetSource * * Description: Set PIC common registers. (Source input) * * Inputs: PIC_num-- PIC number. * fsrcPolSel-- FIQ src Polarity, 32bits. each bit 1-active high, 0- active low * fsrcSensSel--FIQ sensitivity. 32bits. each bits1- Edge triggered, 0- level triggered * nsrcPolSel-- IRQ src Polarity, 32bits. each bit 1-active high, 0- active low * nsrcSensSel-- IRQ sensitivity. 32bits. each bit 1- Edge triggered, 0- level triggered * Outputs: none * * Return: none *******************************************************************************/ void PIC_SetSource(UNSG32 PIC_num, UNSG32 fsrcPolSel, UNSG32 fsrcSensSel, UNSG32 nsrcPolSel, UNSG32 nsrcSensSel) { UNSG32 base_addr=MEMMAP_PIC_REG_BASE+RA_PIC_cmn; UNSG32 fSrcPolSel_offset; UNSG32 fSrcSensSel_offset; UNSG32 nSrcPolSel_offset; UNSG32 nSrcSensSel_offset; switch (PIC_num) { case 1: // fSrcPolSel_offset = RA_cmn_fSrcPolSel1; fSrcSensSel_offset = RA_cmn_fSrcSensSel1; nSrcPolSel_offset = RA_cmn_nSrcPolSel1; nSrcSensSel_offset = RA_cmn_nSrcSensSel1; break; case 2: // fSrcPolSel_offset = RA_cmn_fSrcPolSel2; fSrcSensSel_offset = RA_cmn_fSrcSensSel2; nSrcPolSel_offset = RA_cmn_nSrcPolSel2; nSrcSensSel_offset = RA_cmn_nSrcSensSel2; break; case 0: // default : // fSrcPolSel_offset = RA_cmn_fSrcPolSel0; fSrcSensSel_offset = RA_cmn_fSrcSensSel0; nSrcPolSel_offset = RA_cmn_nSrcPolSel0; nSrcSensSel_offset = RA_cmn_nSrcSensSel0; break; } GA_REG_WORD32_WRITE(base_addr+fSrcPolSel_offset, fsrcPolSel); GA_REG_WORD32_WRITE(base_addr+fSrcSensSel_offset, fsrcSensSel); GA_REG_WORD32_WRITE(base_addr+nSrcPolSel_offset, nsrcPolSel); GA_REG_WORD32_WRITE(base_addr+nSrcSensSel_offset, nsrcSensSel); }
/**************************************************** * FUNCTION: Set Galois SM_GPIO pin as in or out * PARAMS: port - SM_GPIO port # (0 ~ 11) * in - 1: IN, 0: OUT * RETURN: 0 - succeed * -1 - fail ***************************************************/ int SM_GPIO_PortSetInOut(int port, int in) { int reg_ddr, reg_ctl; int ddr, ctl; int gpio_port = port; if((port >= 0) && (port < 8)){ reg_ddr = SM_APB_GPIO_BASE + APB_GPIO_SWPORTA_DDR; reg_ctl = SM_APB_GPIO_BASE + APB_GPIO_PORTA_CTL; } else if ((port >= 8) && (port < MAX_PORT)){ reg_ddr = SM_APB_GPIO1_BASE + APB_GPIO_SWPORTA_DDR; reg_ctl = SM_APB_GPIO1_BASE + APB_GPIO_PORTA_CTL; port -= 8; } else return -1; SM_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); SM_GPIO_PortUnlock(gpio_port); return 0; }
/******************************************************************************* * Function: PIC_SetSourcePerVector * * Description: Set PIC common registers for specific vector. (Source input) * * Inputs: vec_num-- vector number. (corresponding to the bit number) * fsrcPolSel-- FIQ src Polarity, 1-active high, 0- active low * fsrcSensSel--FIQ sensitivity. 1- Edge triggered, 0- level triggered * nsrcPolSel-- IRQ src Polarity, 1-active high, 0- active low * nsrcSensSel-- IRQ sensitivity. 1- Edge triggered, 0- level triggered * Outputs: none * * Return: none *******************************************************************************/ void PIC_SetSourcePerVector(UNSG32 vec_num, UNSG32 fsrcPolSel, UNSG32 fsrcSensSel, UNSG32 nsrcPolSel, UNSG32 nsrcSensSel) { UNSG32 temp; UNSG32 mask; UNSG32 base_addr=MEMMAP_PIC_REG_BASE+RA_PIC_cmn; mask = ~(1<<vec_num); // set fsrcPolsel GA_REG_WORD32_READ(base_addr+RA_cmn_fSrcPolSel, &temp); temp &= mask; temp |= fsrcPolSel << vec_num; GA_REG_WORD32_WRITE(base_addr+RA_cmn_fSrcPolSel, temp); // set fsrcSensSel GA_REG_WORD32_READ(base_addr+RA_cmn_fSrcSensSel, &temp); temp &= mask; temp |= fsrcSensSel << vec_num; GA_REG_WORD32_WRITE(base_addr+RA_cmn_fSrcSensSel, temp); // set nSrcPolSel GA_REG_WORD32_READ(base_addr+RA_cmn_nSrcPolSel, &temp); temp &= mask; temp |= nsrcPolSel << vec_num; GA_REG_WORD32_WRITE(base_addr+RA_cmn_nSrcPolSel, temp); //set nSrcSensSel GA_REG_WORD32_READ(base_addr+RA_cmn_nSrcSensSel, &temp); temp &= mask; temp |= nsrcSensSel << vec_num; GA_REG_WORD32_WRITE(base_addr+RA_cmn_nSrcSensSel, temp); }
/**************************************************** * 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; 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; /* 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); return 0; }
/**************************************************** * FUNCTION: Disable interrupt for Galois SM_GPIO pin * PARAMS: port - SM_GPIO port # (0 ~ 7) * RETURN: 0 - succeed * -1 - fail ***************************************************/ int SM_GPIO_PortDisableIRQ(int port) { int reg_mask, reg_en; int value; if((port >= 0) && (port < 8)){ reg_mask = SM_APB_GPIO_BASE + APB_GPIO_INTMASK; reg_en = SM_APB_GPIO_BASE + APB_GPIO_INTEN; } else if ((port >= 8) && (port < 12)){ #if (BERLIN_CHIP_VERSION >= BERLIN_C_0) reg_mask = SM_APB_GPIO1_BASE + APB_GPIO_INTMASK; reg_en = SM_APB_GPIO1_BASE + APB_GPIO_INTEN; port -= 8; #else return -1; #endif } else { return -1; } /* 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); return 0; }
/******************************************************************************* * Function: PIC_SetSource * * Description: Set PIC common registers. (Source input) * * Inputs: fsrcPolSel-- FIQ src Polarity, 32bits. each bit 1-active high, 0- active low * fsrcSensSel--FIQ sensitivity. 32bits. each bits1- Edge triggered, 0- level triggered * nsrcPolSel-- IRQ src Polarity, 32bits. each bit 1-active high, 0- active low * nsrcSensSel-- IRQ sensitivity. 32bits. each bit 1- Edge triggered, 0- level triggered * Outputs: none * * Return: none *******************************************************************************/ void PIC_SetSource(UNSG32 fsrcPolSel, UNSG32 fsrcSensSel, UNSG32 nsrcPolSel, UNSG32 nsrcSensSel) { UNSG32 base_addr=MEMMAP_PIC_REG_BASE+RA_PIC_cmn; GA_REG_WORD32_WRITE(base_addr+RA_cmn_fSrcPolSel, fsrcPolSel); GA_REG_WORD32_WRITE(base_addr+RA_cmn_fSrcSensSel, fsrcSensSel); GA_REG_WORD32_WRITE(base_addr+RA_cmn_nSrcPolSel, nsrcPolSel); GA_REG_WORD32_WRITE(base_addr+RA_cmn_nSrcSensSel, nsrcSensSel); }
/******************************************************************************* * Function: PIC_SetPerPIC_TgtSel * * Description: Set target select register. (Target) * * Inputs: PIC_num-- PIC number. * fsrcPolSel-- FIQ src Polarity, 1-active high, 0- active low * fsrcSensSel--FIQ sensitivity. 1- Edge triggered, 0- level triggered * nsrcPolSel-- IRQ src Polarity, 1-active high, 0- active low * nsrcSensSel-- IRQ sensitivity. 1- Edge triggered, 0- level triggered * Outputs: none * * Return: none *******************************************************************************/ void PIC_SetPerPIC_TgtSel(UNSG32 PIC_num, UNSG32 fTgtPolSel, UNSG32 fTgtSensSel, UNSG32 nTgtPolSel, UNSG32 nTgtSensSel) { UNSG32 base_addr=MEMMAP_PIC_REG_BASE+PIC_num*sizeof(SIE_perPIC); GA_REG_WORD32_WRITE(base_addr+RA_perPIC_fTgtPolSel, fTgtPolSel); GA_REG_WORD32_WRITE(base_addr+RA_perPIC_fTgtSensSel, fTgtSensSel); GA_REG_WORD32_WRITE(base_addr+RA_perPIC_nTgtPolSel, nTgtPolSel); GA_REG_WORD32_WRITE(base_addr+RA_perPIC_nTgtSensSel, nTgtSensSel); }
/******************************************************************************* * Function: PIC_ClrIntStsPerVector * * Description: Clear interrupt status for specific vector. * * Inputs: fIntSts-- FIQ Interrupt status. (1--- clear, 0-- do nothing) * nIntSts-- IRQ Interrupt status. (1--- clear, 0-- do nothing) * Outputs: none * * Return: none *******************************************************************************/ void PIC_ClrIntStsPerVector(UNSG32 vec_num, UNSG32 fIntSts, UNSG32 nIntSts) { UNSG32 base_addr=MEMMAP_PIC_REG_BASE+RA_PIC_cmn; UNSG32 temp; if (fIntSts) { temp = fIntSts << vec_num; GA_REG_WORD32_WRITE(base_addr+RA_cmn_fIntSts, temp); } if (nIntSts) { temp = nIntSts << vec_num; GA_REG_WORD32_WRITE(base_addr+RA_cmn_nIntSts, temp); } }
/**************************************************** * 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: PIC_SRCHOSTtoDSTHOST_write_int * * Description: Set or clear SRC_HOST to DST_HOST interrupt. * * Inputs: src_host-- source host (PIC_CPU0== 0, PIC_CPU1 == 1, PIC_PCIE== 2) * dst_host-- destination host * Outputs: none * * Return: none *******************************************************************************/ void PIC_SRCHOSTtoDSTHOST_write_int(UNSG32 src_host, UNSG32 dst_host, UNSG32 enable) { UNSG32 base_addr=MEMMAP_PIC_REG_BASE+PIC_int_interhost[dst_host][src_host]; if (enable) { enable = 1; } GA_REG_WORD32_WRITE(base_addr, enable); }
/**************************************************** * 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 SM_GPIO port status * PARAMS: port - SM_GPIO port # (0 ~ 11) * *value - pointer to port status * RETURN: 0 - succeed * -1 - fail ***************************************************/ int SM_GPIO_PortRead(int port, int *value) { int reg_ddr, reg_ext, reg_ctl; int ddr, ext, ctl; if((port >= 0) && (port < 8)){ reg_ddr = SM_APB_GPIO_BASE + APB_GPIO_SWPORTA_DDR; reg_ext = SM_APB_GPIO_BASE + APB_GPIO_EXT_PORTA; reg_ctl = SM_APB_GPIO_BASE + APB_GPIO_PORTA_CTL; } else if ((port >= 8) && (port < 12)){ #if (BERLIN_CHIP_VERSION >= BERLIN_C_0) reg_ddr = SM_APB_GPIO1_BASE + APB_GPIO_SWPORTA_DDR; reg_ext = SM_APB_GPIO1_BASE + APB_GPIO_EXT_PORTA; reg_ctl = SM_APB_GPIO1_BASE + APB_GPIO_PORTA_CTL; #else reg_ddr = SM_APB_GPIO_BASE + APB_GPIO_SWPORTB_DDR; reg_ext = SM_APB_GPIO_BASE + APB_GPIO_EXT_PORTB; reg_ctl = SM_APB_GPIO_BASE + APB_GPIO_PORTB_CTL; #endif port -= 8; } else return -1; /* software mode */ GA_REG_WORD32_READ(reg_ctl, &ctl); ctl &= ~(1 << port); GA_REG_WORD32_WRITE(reg_ctl, ctl); /* 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; return 0; }
/******************************************************************************* * Function: PIC_SetPerPIC_PerVector * * Description: Set perPIC registers for sepcific vector. (Target) * * Inputs: PIC_num-- PIC number. * vec_num--- Vector number. * fIntE--------FIQ interrupt enable bit, 32bits. each bit 1-- enable, 0 -- disable * nIntE--------IRQ interrupt enable bit, 32bits. each bit 1-- enable, 0 -- disable * Outputs: none * * Return: none *******************************************************************************/ void PIC_SetPerPIC_PerVector(UNSG32 PIC_num, UNSG32 vec_num, UNSG32 fIntE, UNSG32 nIntE) { UNSG32 temp; UNSG32 mask; UNSG32 base_addr=MEMMAP_PIC_REG_BASE+PIC_num*sizeof(SIE_perPIC); mask = ~(1<<vec_num); // set fIntE GA_REG_WORD32_READ(base_addr+RA_perPIC_fIntE, &temp); temp &= mask; temp |= fIntE << vec_num; GA_REG_WORD32_WRITE(base_addr+RA_perPIC_fIntE, temp); // set nIntE GA_REG_WORD32_READ(base_addr+RA_perPIC_nIntE, &temp); temp &= mask; temp |= nIntE << vec_num; GA_REG_WORD32_WRITE(base_addr+RA_perPIC_nIntE, temp); }
/**************************************************** * FUNCTION: read SM_GPIO port status * PARAMS: port - SM_GPIO port # (0 ~ 11) * *value - pointer to port status * RETURN: 0 - succeed * -1 - fail ***************************************************/ int SM_GPIO_PortRead(int port, int *value) { int reg_ddr, reg_ext, reg_ctl; int ddr, ext, ctl; int gpio_port = port; if((port >= 0) && (port < 8)){ reg_ddr = SM_APB_GPIO_BASE + APB_GPIO_SWPORTA_DDR; reg_ext = SM_APB_GPIO_BASE + APB_GPIO_EXT_PORTA; reg_ctl = SM_APB_GPIO_BASE + APB_GPIO_PORTA_CTL; } else if ((port >= 8) && (port < MAX_PORT)){ reg_ddr = SM_APB_GPIO1_BASE + APB_GPIO_SWPORTA_DDR; reg_ext = SM_APB_GPIO1_BASE + APB_GPIO_EXT_PORTA; reg_ctl = SM_APB_GPIO1_BASE + APB_GPIO_PORTA_CTL; port -= 8; } else return -1; SM_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 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; SM_GPIO_PortUnlock(gpio_port); return 0; }
/******************************************************************************* * Function: APB_UART_init * * Description: initialize UART * * Inputs: channel-- choose UART0 or UART1, 0 means UART0, 1 means UART1 * tclk-- UART source clock * baud-- UART baud rate * Outputs: none * * Return: none *******************************************************************************/ void APB_UART_init(UNSG32 channel, UNSG32 tclk, UNSG32 baud) { UNSG32 base = APB_UART_INST0_BASE; UNSG32 ulDivisor; UNSG32 tmp ; if (channel == 0) base = APB_UART_INST0_BASE; else if (channel == 1) base = APB_UART_INST1_BASE; //UART FIFO control register:FCR(Enable FIFO mode) GA_REG_WORD32_WRITE(base+APB_UART_FCR, (3<<6) | (3<<4) | (1<<2) | (1<<1) | (1<<0)); //UART modem control register:MCR GA_REG_WORD32_WRITE(base+APB_UART_MCR, 0); //UART line control register: Normal,No parity,1 stop,8 bits and enable baud divider register GA_REG_WORD32_WRITE(base+APB_UART_LCR, 0x3 | BIT7); //UART control register //GA_REG_WORD32_WRITE(base+OFS_UCON, 0x245); GA_REG_WORD32_READ(base+APB_UART_LCR, &tmp); #define UART_LCR_DLAB 0x80 /* Divisor latch access bit */ //UART baud divider register ulDivisor = (tclk/baud+8)/16; //Before setting i_uart_0_UART_DLL/i_uart_0_UART_DLH, the Divisor latch access bit should be set GA_REG_WORD32_WRITE(base+APB_UART_LCR, tmp | UART_LCR_DLAB) ; GA_REG_WORD32_WRITE(base+APB_UART_DLL, ulDivisor & 0xff); GA_REG_WORD32_WRITE(base+APB_UART_DLH, (ulDivisor >> 8) & 0xff); // After setting i_uart_0_UART_DLL/i_uart_0_UART_DLH, the Divisor latch access bit should be cleared to access other bits GA_REG_WORD32_WRITE(base+APB_UART_LCR, tmp & ~UART_LCR_DLAB) ; }
/******************************************************************************* * Function: PIC_SetPerPIC * * Description: Set all of perPIC registers at once. (Target) * * Inputs: PIC_num-- PIC number. * fsrcPolSel-- FIQ src Polarity, 1-active high, 0- active low * fsrcSensSel--FIQ sensitivity. 1- Edge triggered, 0- level triggered * fIntE--------FIQ interrupt enable bit, 32bits. each bit 1-- enable, 0 -- disable * fGIntE--------FIQ globale interrupt enable bit. 1-- enable, 0 -- disable * nsrcPolSel-- IRQ src Polarity, 1-active high, 0- active low * nsrcSensSel-- IRQ sensitivity. 1- Edge triggered, 0- level triggered * nIntE--------IRQ interrupt enable bit, 32bits. each bit 1-- enable, 0 -- disable * nGIntE--------IRQ globale interrupt enable bit. 1-- enable, 0 -- disable * Outputs: none * * Return: none *******************************************************************************/ void PIC_SetPerPIC(UNSG32 PIC_num, UNSG32 fTgtPolSel, UNSG32 fTgtSensSel, UNSG32 fIntE, UNSG32 fGIntE, UNSG32 nTgtPolSel, UNSG32 nTgtSensSel, UNSG32 nIntE, UNSG32 nGIntE) { UNSG32 base_addr=MEMMAP_PIC_REG_BASE+PIC_num*sizeof(SIE_perPIC); GA_REG_WORD32_WRITE(base_addr+RA_perPIC_fTgtPolSel, fTgtPolSel); GA_REG_WORD32_WRITE(base_addr+RA_perPIC_fTgtSensSel, fTgtSensSel); GA_REG_WORD32_WRITE(base_addr+RA_perPIC_fIntE, fIntE); GA_REG_WORD32_WRITE(base_addr+RA_perPIC_fGIntE, fGIntE); GA_REG_WORD32_WRITE(base_addr+RA_perPIC_nTgtPolSel, nTgtPolSel); GA_REG_WORD32_WRITE(base_addr+RA_perPIC_nTgtSensSel, nTgtSensSel); GA_REG_WORD32_WRITE(base_addr+RA_perPIC_nIntE, nIntE); GA_REG_WORD32_WRITE(base_addr+RA_perPIC_nGIntE, nGIntE); }
/******************************************************************************* * Function: APB_UART_putc * * Description: initialize UART * * Inputs: channel-- choose UART0 or UART1, 0 means UART0, 1 means UART1 * c-- output characterPB_UART_init * Outputs: none * * Return: none *******************************************************************************/ void APB_UART_putc(UNSG32 channel, SIGN8 ch) { UNSG32 base = APB_UART_INST0_BASE; UNSG32 status, ulReg; if (channel == 0) base = APB_UART_INST0_BASE; else if (channel == 1) base = APB_UART_INST1_BASE; //Enable thr for write? LCR GA_REG_WORD32_READ(base+APB_UART_LCR, &ulReg); GA_REG_WORD32_WRITE(base+APB_UART_LCR, ulReg & ~(BIT7)); // Wait for Tx FIFO not full(Check THRE bit) do { GA_REG_WORD32_READ(base+APB_UART_LSR, &status); } while (!(status & BIT5)) ; //UART TX data register GA_REG_WORD32_WRITE(base+APB_UART_THR, ch); }
/**************************************************** * FUNCTION: Enable interrupt for Galois SM_GPIO pin * PARAMS: port - SM_GPIO port # (0 ~ 7) * RETURN: 0 - succeed * -1 - fail * NOTE: You also need to enable SM_GPIO interrupt in ICTL. ***************************************************/ int SM_GPIO_PortEnableIRQ(int port) { int reg_mask, reg_en, reg_eoi; int value, gpio_port = port; if((port >= 0) && (port < 8)){ reg_mask = SM_APB_GPIO_BASE + APB_GPIO_INTMASK; reg_en = SM_APB_GPIO_BASE + APB_GPIO_INTEN; reg_eoi = SM_APB_GPIO_BASE + APB_GPIO_PORTA_EOI; } else if ((port >= 8) && (port < MAX_PORT)){ reg_mask = SM_APB_GPIO1_BASE + APB_GPIO_INTMASK; reg_en = SM_APB_GPIO1_BASE + APB_GPIO_INTEN; reg_eoi = SM_APB_GPIO1_BASE + APB_GPIO_PORTA_EOI; port -= 8; } else { return -1; } SM_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); SM_GPIO_PortUnlock(gpio_port); return 0; }
/**************************************************** * FUNCTION: Enable interrupt for Galois SM_GPIO pin * PARAMS: port - SM_GPIO port # (0 ~ 7) * RETURN: 0 - succeed * -1 - fail * NOTE: You also need to enable SM_GPIO interrupt in ICTL. ***************************************************/ int SM_GPIO_PortEnableIRQ(int port) { int reg_mask, reg_en, reg_eoi; int value; if((port >= 0) && (port < 8)){ reg_mask = SM_APB_GPIO_BASE + APB_GPIO_INTMASK; reg_en = SM_APB_GPIO_BASE + APB_GPIO_INTEN; reg_eoi = SM_APB_GPIO_BASE + APB_GPIO_PORTA_EOI; } else if ((port >= 8) && (port < 12)){ #if (BERLIN_CHIP_VERSION >= BERLIN_C_0) reg_mask = SM_APB_GPIO1_BASE + APB_GPIO_INTMASK; reg_en = SM_APB_GPIO1_BASE + APB_GPIO_INTEN; reg_eoi = SM_APB_GPIO1_BASE + APB_GPIO_PORTA_EOI; port -= 8; #else return -1; #endif } else { return -1; } /* 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); return 0; }
/**************************************************** * FUNCTION: Attach or detach PWM to GPIO pins * PARAMS: attach - 1: PWM, 0: GPIO * RETURN: 0 - succeed. * -1 - fail. ***************************************************/ int GPIO_AttachPWM(int attach) { int reg_pinmux = MEMMAP_CHIP_CTRL_REG_BASE + 0x0000; // RA_Gbl_pinMux int pinmux; GA_REG_WORD32_READ(reg_pinmux, &pinmux); pinmux &= ~0x07; // Gbl_pinMux_gp0 mask if (attach) pinmux |= (0x03 << 0); // Gbl_pinMux_gp0_MODE_3 else pinmux |= (0x01 << 0); // Gbl_pinMux_gp0_MODE_1 GA_REG_WORD32_WRITE(reg_pinmux, pinmux); 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: Clear interrupt for Galois SM_GPIO pin * PARAMS: port - SM_GPIO port # (0 ~ 7) * RETURN: 0 - succeed. * -1 - fail. ***************************************************/ int SM_GPIO_PortClearInterrupt(int port) { int reg_eoi; int value, gpio_port = port; if((port >= 0) && (port < 8)){ reg_eoi = SM_APB_GPIO_BASE + APB_GPIO_PORTA_EOI; } else if ((port >= 8) && (port < MAX_PORT)){ reg_eoi = SM_APB_GPIO1_BASE + APB_GPIO_PORTA_EOI; port -= 8; } else { return -1; } SM_GPIO_PortLock(gpio_port); /* see above, write 1 to clear interrupt */ value = (1 << port); GA_REG_WORD32_WRITE(reg_eoi, value); SM_GPIO_PortUnlock(gpio_port); return 0; }
/******************************************************************************* * Function: APB_UART_getc_nonblock * * Description: non blocking mode read charactor from UART * * Inputs: channel-- choose UART0 or UART1, 0 means UART0, 1 means UART1 * c-- output character * Outputs: none * * Return: 0-- didn't get any character * 1-- get one character *******************************************************************************/ UNSG8 APB_UART_getc_nonblock(UNSG32 channel, UNSG8 *ch) { UNSG32 base = APB_UART_INST0_BASE; UNSG32 status, ulReg; UNSG32 data; if (channel == 0) base = APB_UART_INST0_BASE; else if (channel == 1) base = APB_UART_INST1_BASE; GA_REG_WORD32_READ(base+APB_UART_LSR, &status); if (status & BIT0) /* If there's char[s] in RBR or FIFO */ { //Enable rbr for read GA_REG_WORD32_READ(base+APB_UART_LCR, &ulReg); GA_REG_WORD32_WRITE(base+APB_UART_LCR, ulReg & ~(BIT7)); GA_REG_WORD32_READ(base+APB_UART_RBR, &data); *ch = data & 0xFF; return 1; } return 0; }
/**************************************************** * FUNCTION: Clear interrupt for Galois SM_GPIO pin * PARAMS: port - SM_GPIO port # (0 ~ 7) * RETURN: 0 - succeed. * -1 - fail. ***************************************************/ int SM_GPIO_PortClearInterrupt(int port) { int reg_eoi; int value; if((port >= 0) && (port < 8)){ reg_eoi = SM_APB_GPIO_BASE + APB_GPIO_PORTA_EOI; } else if ((port >= 8) && (port < 12)){ #if (BERLIN_CHIP_VERSION >= BERLIN_C_0) reg_eoi = SM_APB_GPIO1_BASE + APB_GPIO_PORTA_EOI; port -= 8; #else return -1; #endif } else { return -1; } /* see above, write 1 to clear interrupt */ value = (1 << port); GA_REG_WORD32_WRITE(reg_eoi, value); return 0; }
static irqreturn_t pe_devices_zsp_isr(int irq, void *dev_id) { UNSG32 addr, v_id; T32ZspInt2Soc_status reg; printk("kernel : ZSP intr received!.\n"); PIC_SetPerPIC_PerVector(CPUINDEX, irq, PIC_INT_DISABLE, PIC_INT_DISABLE); addr = MEMMAP_ZSP_REG_BASE + RA_ZspRegs_Int2Soc + RA_ZspInt2Soc_status; GA_REG_WORD32_READ(addr, &(reg.u32)); addr = MEMMAP_ZSP_REG_BASE + RA_ZspRegs_Int2Soc + RA_ZspInt2Soc_clear; v_id = ADSP_ZSPINT2Soc_IRQ0; if ((reg.u32) & (1 << v_id)) { GA_REG_WORD32_WRITE(addr, v_id); } tasklet_hi_schedule(&pe_zsp_tasklet); // this is audio zsp, video zsp interrupt will use another tasklet to post msg. PIC_SetPerPIC_PerVector(CPUINDEX, irq, PIC_INT_ENABLE, PIC_INT_ENABLE); return IRQ_HANDLED; }