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); }
void thread_delete(ustack_t *thread) { _deregister(thread); void *base = _unprotect(thread); as_free(AS_REGISTERED, base); }