void gpio_init(int pin, int mode){ GPIO_TypeDef *addr = _gpio_addr(pin); if( !addr ) return; int plx = splhigh(); int io = pin >> 4; pin &= 0xF; int pos = (pin & 0x7) << 2; #if defined(PLATFORM_STM32F4) || defined(PLATFORM_STM32F7) RCC->AHB1ENR |= 1 << io; #elif defined(PLATFORM_STM32F0) RCC->AHBENR |= 1 << (io + 17); #elif defined(PLATFORM_STM32L4) RCC->AHB2ENR |= 1 << io; #elif defined(PLATFORM_STM32L1) // F,G,H are mixed-up on the L1 switch( io ){ case 5: RCC->AHBENR |= 1 << 6; break; case 6: RCC->AHBENR |= 1 << 7; break; case 7: RCC->AHBENR |= 1 << 5; break; default: RCC->AHBENR |= 1 << io; break; } #else # error "unknown platform" #endif addr->MODER &= ~( 3 << (pin*2) ); addr->PUPDR &= ~( 3 << (pin*2) ); addr->OSPEEDR &= ~( 3 << (pin*2) ); addr->MODER |= (mode&3) << (pin*2); addr->PUPDR |= ((mode>>5) & 3) << (pin*2); addr->OSPEEDR |= ((mode>>3) & 3) << (pin*2); addr->OTYPER &= ~( 1<<pin ); addr->OTYPER |= ((mode>>2) & 1) << pin; if( pin >= 8 ){ addr->AFRH &= ~(0xF << pos); addr->AFRH |= ((mode>>8) & 0xF) << pos; }else{
void gpio_init(uint32_t pin, uint32_t mode){ int plx = splhigh(); int io = pin >> 5; Pio *addr = _gpio_addr(pin); pin &= 0x1F; _unprotect(addr); // (1:input schmitt) (1:input deglitch) (2:pull up/dn) (1:push/pull,open-drain) (2:AF) (2:mode) switch( mode & 3 ){ case GPIO_INPUT: _enable_pio(io); // fall through case GPIO_ANALOG: addr->PIO_PER = 1<<pin; addr->PIO_ODR = 1<<pin; break; case GPIO_OUTPUT: _enable_pio(io); addr->PIO_PER = 1<<pin; addr->PIO_OER = 1<<pin; addr->PIO_OWER = 1<<pin; // permit writes via odsr break; default: addr->PIO_PDR = 1<<pin; addr->PIO_ODR = 1<<pin; switch( mode & 0xF ){ case GPIO_AF_A: addr->PIO_ABCDSR[0] &= ~(1<<pin); addr->PIO_ABCDSR[1] &= ~(1<<pin); break; case GPIO_AF_B: addr->PIO_ABCDSR[0] |= 1<<pin; addr->PIO_ABCDSR[1] &= ~(1<<pin); break; case GPIO_AF_C: addr->PIO_ABCDSR[0] &= ~(1<<pin); addr->PIO_ABCDSR[1] |= 1<<pin; break; case GPIO_AF_D: addr->PIO_ABCDSR[0] |= 1<<pin; addr->PIO_ABCDSR[1] |= 1<<pin; break; } break; } // push-pull or open-drain if( mode & GPIO_OPEN_DRAIN ) addr->PIO_MDER |= 1<<pin; else addr->PIO_MDDR |= 1<<pin; // pull up, pull down? if( mode & GPIO_PULL_UP ) addr->PIO_PUER |= 1<<pin; else addr->PIO_PUDR |= 1<<pin; if( mode & GPIO_PULL_DN ) addr->PIO_PPDER |= 1<<pin; else addr->PIO_PPDDR |= 1<<pin; // input filters if( mode & GPIO_SCHMITT ) addr->PIO_SCHMITT |= 1<<pin; else addr->PIO_SCHMITT &= ~(1<<pin); // ... _protect(addr); splx(plx); }