/***************************************************************************//** * @brief * Init USART for synchronous mode. * * @details * This function will configure basic settings in order to operate in * synchronous mode. * * Special control setup not covered by this function must be done after * using this function by direct modification of the CTRL register. * * Notice that pins used by the USART module must be properly configured * by the user explicitly, in order for the USART to work as intended. * (When configuring pins, one should remember to consider the sequence of * configuration, in order to avoid unintended pulses/glitches on output * pins.) * * @param[in] usart * Pointer to USART peripheral register block. (UART does not support this * mode.) * * @param[in] init * Pointer to initialization structure used to configure basic async setup. ******************************************************************************/ void USART_InitSync(USART_TypeDef *usart, const USART_InitSync_TypeDef *init) { /* Make sure the module exists on the selected chip */ EFM_ASSERT(USART_REF_VALID(usart)); /* Init USART registers to HW reset state. */ USART_Reset(usart); /* Set bits for synchronous mode */ usart->CTRL |= (USART_CTRL_SYNC) | ((uint32_t) init->clockMode) | (init->msbf ? USART_CTRL_MSBF : 0); #if defined(USART_INPUT_RXPRS) && defined(USART_TRIGCTRL_AUTOTXTEN) usart->CTRL |= (init->prsRxEnable ? USART_INPUT_RXPRS : 0) | (init->autoTx ? USART_CTRL_AUTOTX : 0); #endif /* Configure databits, leave stopbits and parity at reset default (not used) */ usart->FRAME = ((uint32_t) (init->databits)) | (USART_FRAME_STOPBITS_DEFAULT) | (USART_FRAME_PARITY_DEFAULT); /* Configure baudrate */ USART_BaudrateSyncSet(usart, init->refFreq, init->baudrate); /* Finally enable (as specified) */ if (init->master) { usart->CMD = USART_CMD_MASTEREN; } usart->CMD = (uint32_t) (init->enable); }
/***************************************************************************//** * @brief * SPI/USART Initialization * * @param[in] bit_rate * Bit rate for SPI Bus in MHz: Either 2000000 or 12000000 * ******************************************************************************/ void spi_init(int bit_rate) { CMU_ClockEnable(cmuClock_GPIO, true); CMU_ClockEnable(SPI_cmuClock, true); gpio_init(spi_pins, sizeof(spi_pins)/sizeof(gpio_init_t)); USART_Reset(SPI_PORT); USART_InitSync(SPI_PORT, &spiInit); SPI_PORT->CTRL |= USART_CTRL_TXBIL_HALFFULL; SPI_PORT->ROUTE = USART_ROUTE_TXPEN | USART_ROUTE_RXPEN | USART_ROUTE_CLKPEN | (USART_LOC << _USART_ROUTE_LOCATION_SHIFT); if (bit_rate) USART_BaudrateSyncSet(SPI_PORT, 0, bit_rate); USART_IntClear(SPI_PORT, USART_IF_RXDATAV | USART_IF_TXBL); NVIC_ClearPendingIRQ(SPI_TX_IRQn); NVIC_EnableIRQ(SPI_TX_IRQn); NVIC_ClearPendingIRQ(SPI_RX_IRQn); NVIC_EnableIRQ(SPI_RX_IRQn); so_busy = false; so_irq_count = 0; so_spurious_irq_count = 0; so_irq_fake_count = 0; // register (but don't enable) rx pin GPIO interrupt gpio_irq_handler_install(RX_PORT, RX_PIN, SO_IRQ, NULL); }
/***************************************************************************//** * @brief * Init USART for synchronous mode. * * @details * This function will configure basic settings in order to operate in * synchronous mode. * * Special control setup not covered by this function must be done after * using this function by direct modification of the CTRL register. * * Notice that pins used by the USART module must be properly configured * by the user explicitly, in order for the USART to work as intended. * (When configuring pins, one should remember to consider the sequence of * configuration, in order to avoid unintended pulses/glitches on output * pins.) * * @param[in] usart * Pointer to USART peripheral register block. (UART does not support this * mode.) * * @param[in] init * Pointer to initialization structure used to configure basic async setup. ******************************************************************************/ void USART_InitSync(USART_TypeDef *usart, const USART_InitSync_TypeDef *init) { /* Make sure the module exists on the selected chip */ EFM_ASSERT( USART_REF_VALID(usart) || USARTRF_REF_VALID(usart) ); /* Init USART registers to HW reset state. */ USART_Reset(usart); /* Set bits for synchronous mode */ usart->CTRL |= (USART_CTRL_SYNC) | (uint32_t)init->clockMode | (init->msbf ? USART_CTRL_MSBF : 0); #if defined(_USART_CTRL_AUTOTX_MASK) usart->CTRL |= init->autoTx ? USART_CTRL_AUTOTX : 0; #endif #if defined(_USART_INPUT_RXPRS_MASK) /* Configure PRS input mode. */ if (init->prsRxEnable) { usart->INPUT = (uint32_t)init->prsRxCh | USART_INPUT_RXPRS; } #endif /* Configure databits, leave stopbits and parity at reset default (not used) */ usart->FRAME = (uint32_t)init->databits | USART_FRAME_STOPBITS_DEFAULT | USART_FRAME_PARITY_DEFAULT; /* Configure baudrate */ USART_BaudrateSyncSet(usart, init->refFreq, init->baudrate); /* Finally enable (as specified) */ if (init->master) { usart->CMD = USART_CMD_MASTEREN; } #if defined(_USART_TIMING_CSHOLD_MASK) usart->TIMING = ((init->autoCsHold << _USART_TIMING_CSHOLD_SHIFT) & _USART_TIMING_CSHOLD_MASK) | ((init->autoCsSetup << _USART_TIMING_CSSETUP_SHIFT) & _USART_TIMING_CSSETUP_MASK); if (init->autoCsEnable) { usart->CTRL |= USART_CTRL_AUTOCS; } #endif usart->CMD = (uint32_t)init->enable; }
/***************************************************************************//** * @brief * Init USART for synchronous mode. * * @details * This function will configure basic settings in order to operate in * synchronous mode. Consider using USART_Reset() prior to this function if * state of configuration is not known, since only configuration settings * specified by @p init are set. * * Special control setup not covered by this function may be done either * before or after using this function (but normally before enabling) * by direct modification of the CTRL register. * * Notice that pins used by the USART module must be properly configured * by the user explicitly, in order for the USART to work as intended. * (When configuring pins, one should remember to consider the sequence of * configuration, in order to avoid unintended pulses/glitches on output * pins.) * * @param[in] usart * Pointer to USART peripheral register block. (UART does not support this * mode.) * * @param[in] init * Pointer to initialization structure used to configure basic async setup. ******************************************************************************/ void USART_InitSync(USART_TypeDef *usart, USART_InitSync_TypeDef *init) { /* Make sure the module exists on the selected chip */ EFM_ASSERT(USART_REF_VALID(usart)); /* Ensure disabled while doing config */ usart->CMD = USART_CMD_RXDIS | USART_CMD_TXDIS | USART_CMD_MASTERDIS; /* Reset bits that should be reset for synchronous mode or needs reconfig */ usart->CTRL &= ~(_USART_CTRL_CLKPOL_MASK | _USART_CTRL_CLKPHA_MASK | _USART_CTRL_MSBF_MASK | _USART_CTRL_SCMODE_MASK | _USART_CTRL_SCRETRANS_MASK); /* Set bits for synchronous mode */ usart->CTRL |= USART_CTRL_SYNC | (uint32_t)(init->clockMode); if (init->msbf) { usart->CTRL |= USART_CTRL_MSBF; } /* Make sure IrDA is disabled */ usart->IRCTRL &= ~USART_IRCTRL_IREN; /* Configure databits, leave stopbits and parity at reset default (not used) */ usart->FRAME = (uint32_t)(init->databits) | USART_FRAME_STOPBITS_DEFAULT | USART_FRAME_PARITY_DEFAULT; /* Configure baudrate */ USART_BaudrateSyncSet(usart, init->refFreq, init->baudrate); /* Finally enable (as specified) */ if (init->master) { usart->CMD = USART_CMD_MASTEREN; } usart->CMD = (uint32_t)(init->enable); }
/***************************************************************************//** * @brief * Update the SPI peripheral with given baudrate and mode ******************************************************************************/ void TD_SPI_UpdateConf(uint8_t id) { uint8_t bus = TD_SPI_Conf[id].bus; if (!SPI[bus].inited) { TD_SPI_InitBus(bus); } if (SPI[bus].freq != TD_SPI_Conf[id].freq) { SPI[bus].freq = TD_SPI_Conf[id].freq; DEBUG_PRINTF("SPI:%dF=%d\r\n", bus, SPI[bus].freq); USART_BaudrateSyncSet(USART, ref_freq, SPI[bus].freq); } if (SPI[bus].mode != TD_SPI_Conf[id].mode) { SPI[bus].mode = TD_SPI_Conf[id].mode; USART->CMD = USART_CMD_RXDIS | USART_CMD_TXDIS | USART_CMD_MASTERDIS | USART_CMD_RXBLOCKDIS | USART_CMD_TXTRIDIS | USART_CMD_CLEARTX | USART_CMD_CLEARRX; USART->CTRL = (USART->CTRL & (~0x300)) | ((uint32_t) SPI[bus].mode); USART->CMD = USART_CMD_MASTEREN | (USART_CMD_RXEN | USART_CMD_TXEN); DEBUG_PRINTF("SPI:%dM=%d\r\n", bus, SPI[bus].mode); } }
/**************************************************************************//** * @brief Set SPI clock to maximum frequency. *****************************************************************************/ void MICROSD_SpiClkFast(void) { USART_BaudrateSyncSet(MICROSD_USART, 0, MICROSD_HI_SPI_FREQ); xfersPrMsec = MICROSD_HI_SPI_FREQ / 8000; }
void spi_frequency(spi_t *obj, int hz) { USART_BaudrateSyncSet(obj->spi.spi, REFERENCE_FREQUENCY, hz); }