static int pio_set(char* buf, mmap_gpio* pio) { uint32_t port = pio->port - 'A'; if (port > PIO_NR_PORTS) { return -1; } uint32_t *addr, val; uint32_t port_num_func, port_num_pull; uint32_t offset_func, offset_pull; port_num_func = pio->pin >> 3; offset_func = ((pio->pin & 0x07) << 2); port_num_pull = pio->pin >> 4; offset_pull = ((pio->pin & 0x0f) << 1); /* func */ if (pio->cfg >= 0) { addr = (uint32_t*)PIO_REG_CFG(buf, port, port_num_func); val = le32toh(*addr); val &= ~(0x07 << offset_func); val |= (pio->cfg & 0x07) << offset_func; *addr = htole32(val); } /* pull */ if (pio->pull >= 0) { addr = (uint32_t*)PIO_REG_PULL(buf, port, port_num_pull); val = le32toh(*addr); val &= ~(0x03 << offset_pull); val |= (pio->pull & 0x03) << offset_pull; *addr = htole32(val); } /* dlevel */ if (pio->drv_level >= 0) { addr = (uint32_t*)PIO_REG_DLEVEL(buf, port, port_num_pull); val = le32toh(*addr); val &= ~(0x03 << offset_pull); val |= (pio->drv_level & 0x03) << offset_pull; *addr = htole32(val); } /* data */ if (pio->data >= 0) { addr = (uint32_t*)PIO_REG_DATA(buf, port); val = le32toh(*addr); if (pio->data) val |= (0x01 << pio->pin); else val &= ~(0x01 << pio->pin); *addr = htole32(val); } return PIO_SUCCESS; }
static int pio_get(const char* buf, mmap_gpio* pio) { uint32_t port = pio->port - 'A'; if (port > PIO_NR_PORTS) { return -1; } uint32_t val; uint32_t port_num_func, port_num_pull; uint32_t offset_func, offset_pull; port_num_func = pio->pin >> 3; offset_func = ((pio->pin & 0x07) << 2); port_num_pull = pio->pin >> 4; offset_pull = ((pio->pin & 0x0f) << 1); /* func */ pio->cfg_address = PIO_REG_CFG(buf, port, port_num_func); val = le32toh(*(pio->cfg_address)); pio->cfg = (val>>offset_func) & 0x07; /* pull */ pio->pull_address = PIO_REG_PULL(buf, port, port_num_pull); val = le32toh(*(pio->pull_address)); pio->pull = (val>>offset_pull) & 0x03; /* dlevel */ pio->dlevel_address = PIO_REG_DLEVEL(buf, port, port_num_pull); val = le32toh(*(pio->dlevel_address)); pio->drv_level = (val>>offset_pull) & 0x03; /* i/o data */ if (pio->cfg > 1) pio->data = -1; else { pio->data_address = PIO_REG_DATA(buf, port); val = le32toh(*(pio->data_address)); pio->data = (val >> pio->pin) & 0x01; } return PIO_SUCCESS; }
void main(void) { uint32_t port, pin, val; uint32_t uart_port; uint32_t volatile *reg; uint32_t apb_freq; uint32_t uart_baud, uart_clk, lcr; uint32_t i; /* A80, Cubieboard4, Red LED On (PH06) */ port = 'H'; pin = 6; /* PIO Configure */ port -= 'A'; val = *(PIO_REG_CFG(PIO_BASE, port, pin)); val &= ~(0x07 << PIO_REG_CFG_POS(pin)); val |= (PIO_REG_CFG_VAL_OUTPUT << PIO_REG_CFG_POS(pin)); *(PIO_REG_CFG(PIO_BASE, port, pin)) = val; /* PIO data */ val = *(PIO_REG_DAT(PIO_BASE, port)); val &= ~(1 << pin); val |= (1 << pin); *(PIO_REG_DAT(PIO_BASE, port)) = val; /* A80, Cubieboard4, Red LED On (PH06) */ port = 'H'; pin = 12; /* PIO Configure */ port -= 'A'; val = *(PIO_REG_CFG(PIO_BASE, port, pin)); val &= ~(0x07 << PIO_REG_CFG_POS(pin)); val |= (PIO_REG_CFG_VAL_IO<< PIO_REG_CFG_POS(pin)); *(PIO_REG_CFG(PIO_BASE, port, pin)) = val; /* PIO level */ val = *(PIO_REG_LVL(PIO_BASE, port, pin)); val &= ~(0x0F << PIO_REG_LVL_POS(pin)); val |= (PIO_REG_LVL_VAL_1 << PIO_REG_LVL_POS(pin)); *(PIO_REG_LVL(PIO_BASE, port, pin)) = val; /* PIO Pull */ val = *(PIO_REG_PUL(PIO_BASE, port, pin)); val &= ~(0x0F << PIO_REG_PUL_POS(pin)); val |= (PIO_REG_PUL_VAL_HIGH << PIO_REG_PUL_POS(pin)); *(PIO_REG_PUL(PIO_BASE, port, pin)) = val; /**************************************************************************** * Magic ... ****************************************************************************/ #if 0 /* Timer init */ CCMU_REG_AVS |= (1U << 31); TMRC_AVS_CTRL = 3; TMRC_AVS_DIVISOR = 0xC2EE0; TMRC_AVS_COUNT0 = 0; TMRC_AVS_COUNT1 = 0; #endif /* PLL init, just for UART to work? */ //CCM_CPU_SOURCECTRL &= ~(0x01); CCM_PLL4_PERP0_CTRL = 0x80002800; //CCM_PLL12_PERP1_CTRL = 0x80003200; /* UART config */ uart_port = 0; //reset reg = (uint32_t volatile *)(0x06000400 + 0x1B4); *reg &= ~(1 << (16 + uart_port)); for( i = 0; i < 100; i++ ); *reg |= (1 << (16 + uart_port)); //gate reg = (uint32_t volatile *)(0x06000400 + 0x194); *reg &= ~(1 << (16 + uart_port)); for( i = 0; i < 100; i++ ); *reg |= (1 << (16 + uart_port)); // magic! *((uint32_t volatile *)0x01c202D8) |= (1 << (16 + uart_port)); // Set Baudrate apb_freq = 24 * 1000 * 1000; uart_baud = 115200; uart_clk = ( apb_freq + 8*uart_baud ) / (16*uart_baud); lcr = UART_REG_LCR(uart_port); UART_REG_HALT(uart_port) = 1; UART_REG_LCR(uart_port) = lcr | 0x80; UART_REG_DLH(uart_port) = uart_clk>>8; UART_REG_DLL(uart_port) = uart_clk&0xff; UART_REG_LCR(uart_port) = lcr & (~0x80); UART_REG_HALT(uart_port) = 0; // Set Lin Control Register UART_REG_LCR(uart_port) = ((0 /*PARITY*/ &0x03)<<3) | ((0/*STOP*/&0x01)<<2) | (3/*DLEN = 8*/&0x03); // Disable FIFOs UART_REG_FCR(uart_port) = 0x06; // Namaste! { char const * p_namaste = "\r\nNamaste !\r\n"; while (*p_namaste) { while (!SERIAL_WRITE_READY(uart_port)); SERIAL_WRITE_CHAR(uart_port, *p_namaste++); } } /**************************************************************************** * ... magic. ****************************************************************************/ #if 1 /* A80, Cubieboard4, Green LED On (PH17) */ port = 'H'; pin = 17; /* PIO Configure */ port -= 'A'; val = *(PIO_REG_CFG(PIO_BASE, port, pin)); val &= ~(0x07 << PIO_REG_CFG_POS(pin)); val |= (PIO_REG_CFG_VAL_OUTPUT << PIO_REG_CFG_POS(pin)); *(PIO_REG_CFG(PIO_BASE, port, pin)) = val; /* PIO data */ val = *(PIO_REG_DAT(PIO_BASE, port)); val &= ~(1 << pin); val |= (1 << pin); *(PIO_REG_DAT(PIO_BASE, port)) = val; #endif while(1); }