static void enable_serial_wakeup(int enable) { static uint32_t save_exticr; if (enable) { /** * allow to wake up from serial port (RX on pin PA10) * by setting it as a GPIO with an external interrupt. */ save_exticr = STM32_AFIO_EXTICR(10 / 4); STM32_AFIO_EXTICR(10 / 4) = (save_exticr & ~(0xf << 8)); } else { /* serial port wake up : don't go back to sleep */ if (STM32_EXTI_PR & (1 << 10)) disable_sleep(SLEEP_MASK_FORCE_NO_DSLEEP); /* restore keyboard external IT on PC10 */ STM32_AFIO_EXTICR(10 / 4) = save_exticr; } }
void spi_slave_init(void) { stm32_spi_regs_t *spi = STM32_SPI1_REGS; /* * MISO: AFIO Push-pull */ STM32_GPIO_CRL(GPIO_A) = (STM32_GPIO_CRL(GPIO_A) & 0xfff0ffff) | 0x000b0000; /* Set DFF to 8-bit (default) */ /* Set CPOL and CPHA (default) */ /* Configure LSBFIRST (default) */ /* Set SSM and clear SSI */ spi->cr1 |= STM32_SPI_CR1_SSM; spi->cr1 &= ~STM32_SPI_CR1_SSI; /* Enable RXNE interrupt */ spi->cr2 |= STM32_SPI_CR2_RXNEIE; /*task_enable_irq(STM32_IRQ_SPI1);*/ /* Enable TX and RX DMA */ spi->cr2 |= STM32_SPI_CR2_TXDMAEN | STM32_SPI_CR2_RXDMAEN; /* Clear MSTR */ spi->cr1 &= ~STM32_SPI_CR1_MSTR; /* Enable CRC */ spi->cr1 |= STM32_SPI_CR1_CRCEN; /* Set SPE */ spi->cr1 |= STM32_SPI_CR1_SPE; /* Dummy byte to clock out when the next packet comes in */ spi->dr = DUMMY_DATA; /* Enable interrupt on PA0 (GPIO_SPI_NSS) */ STM32_AFIO_EXTICR(0) &= ~0xF; STM32_EXTI_IMR |= (1 << 0); task_clear_pending_irq(STM32_IRQ_EXTI0); task_enable_irq(STM32_IRQ_EXTI0); }
int stm32_configgpio(uint32_t cfgset) { uint32_t base; uint32_t cr; uint32_t regval; uint32_t regaddr; unsigned int port; unsigned int pin; unsigned int pos; unsigned int modecnf; irqstate_t flags; bool input; /* Verify that this hardware supports the select GPIO port */ port = (cfgset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; if (port >= STM32_NGPIO_PORTS) { return -EINVAL; } /* Get the port base address */ base = g_gpiobase[port]; /* Get the pin number and select the port configuration register for that * pin */ pin = (cfgset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT; if (pin < 8) { cr = base + STM32_GPIO_CRL_OFFSET; pos = pin; } else { cr = base + STM32_GPIO_CRH_OFFSET; pos = pin - 8; } /* Input or output? */ input = ((cfgset & GPIO_INPUT) != 0); /* Interrupts must be disabled from here on out so that we have mutually * exclusive access to all of the GPIO configuration registers. */ //flags = irqsave(); CoSchedLock(); /* Decode the mode and configuration */ regval = getreg32(cr); if (input) { /* Input.. force mode = INPUT */ modecnf = 0; } else { /* Output or alternate function */ modecnf = (cfgset & GPIO_MODE_MASK) >> GPIO_MODE_SHIFT; } modecnf |= ((cfgset & GPIO_CNF_MASK) >> GPIO_CNF_SHIFT) << 2; /* Set the port configuration register */ regval &= ~(GPIO_CR_MODECNF_MASK(pos)); regval |= (modecnf << GPIO_CR_MODECNF_SHIFT(pos)); putreg32(regval, cr); /* Set or reset the corresponding BRR/BSRR bit */ if (!input) { /* It is an output or an alternate function. We have to look at the CNF * bits to know which. */ unsigned int cnf = (cfgset & GPIO_CNF_MASK); if (cnf != GPIO_CNF_OUTPP && cnf != GPIO_CNF_OUTOD) { /* Its an alternate function pin... we can return early */ //irqrestore(flags); CoSchedUnlock(); return OK; } } else { /* It is an input pin... Should it configured as an EXTI interrupt? */ if ((cfgset & GPIO_EXTI) != 0) { int shift; /* Yes.. Set the bits in the EXTI CR register */ regaddr = STM32_AFIO_EXTICR(pin); regval = getreg32(regaddr); shift = AFIO_EXTICR_EXTI_SHIFT(pin); regval &= ~(AFIO_EXTICR_PORT_MASK << shift); regval |= (((uint32_t)port) << shift); putreg32(regval, regaddr); } if ((cfgset & GPIO_CNF_MASK) != GPIO_CNF_INPULLUD) { /* Neither... we can return early */ //irqrestore(flags); CoSchedUnlock(); return OK; } } /* If it is an output... set the pin to the correct initial state. * If it is pull-down or pull up, then we need to set the ODR * appropriately for that function. */ if ((cfgset & GPIO_OUTPUT_SET) != 0) { /* Use the BSRR register to set the output */ regaddr = base + STM32_GPIO_BSRR_OFFSET; } else { /* Use the BRR register to clear */ regaddr = base + STM32_GPIO_BRR_OFFSET; } regval = getreg32(regaddr); regval |= (1 << pin); putreg32(regval, regaddr); //irqrestore(flags); CoSchedUnlock(); return OK; }