/** * @brief Tx 8-bit handler for Transmit and Receive in Interrupt mode. * @param hspi pointer to a SPI_HandleTypeDef structure that contains * the configuration information for SPI module. * @retval None */ static void SPI_2linesTxISR_8BIT(struct __SPI_HandleTypeDef *hspi) { #if SPI_HAS_FIFO /* Transmit data in packing Bit mode */ if (hspi->TxXferCount >= 2U) { hspi->Instance->DR = *((uint16_t *)hspi->pTxBuffPtr); hspi->pTxBuffPtr += sizeof(uint16_t); hspi->TxXferCount -= 2U; } /* Transmit data in 8 Bit mode */ else { #endif *(__IO uint8_t *)&hspi->Instance->DR = (*hspi->pTxBuffPtr++); hspi->TxXferCount--; #if SPI_HAS_FIFO } #endif /* check the end of the transmission */ if(hspi->TxXferCount == 0U) { /* Disable TXE interrupt */ __HAL_SPI_DISABLE_IT(hspi, SPI_IT_TXE); if(hspi->RxXferCount == 0U) { SPI_CloseRxTx_ISR(hspi); } } }
static HAL_StatusTypeDef SPI_WaitFlagStateUntilTimeout(SPI_HandleTypeDef *hspi, uint32_t Flag, uint32_t State, uint32_t Timeout, uint32_t Tickstart) { while((((hspi->Instance->SR & Flag) == (Flag)) ? SET : RESET) != State) { if(Timeout != HAL_MAX_DELAY) { if((Timeout == 0U) || ((HAL_GetTick()-Tickstart) >= Timeout)) { /* Disable the SPI and reset the CRC: the CRC value should be cleared on both master and slave sides in order to resynchronize the master and slave for their respective CRC calculation */ /* Disable TXE, RXNE and ERR interrupts for the interrupt process */ __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_TXE | SPI_IT_RXNE | SPI_IT_ERR)); hspi->State= HAL_SPI_STATE_READY; /* Process Unlocked */ __HAL_UNLOCK(hspi); return HAL_TIMEOUT; } } } return HAL_OK; }
/** * @brief Rx 8-bit handler for Transmit and Receive in Interrupt mode. * @param hspi pointer to a SPI_HandleTypeDef structure that contains * the configuration information for SPI module. * @retval None */ static void SPI_2linesRxISR_8BIT(struct __SPI_HandleTypeDef *hspi) { if (hspi->Init.Mode == SPI_MODE_MASTER) { *hspi->pRxBuffPtr++ = *((__IO uint8_t *)&hspi->Instance->DR); hspi->RxXferCount--; } else { //FIXME: this block below is probably not required... #if SPI_HAS_FIFO /* Receive data in packing mode */ if (hspi->RxXferCount > 1U) { *((uint16_t *)hspi->pRxBuffPtr) = hspi->Instance->DR; hspi->pRxBuffPtr += sizeof(uint16_t); hspi->RxXferCount -= 2U; } else { /* Receive data in 8 Bit mode */ #endif *hspi->pRxBuffPtr++ = *((__IO uint8_t *)&hspi->Instance->DR); hspi->RxXferCount--; #if SPI_HAS_FIFO } #endif } /* check end of the reception */ if(hspi->RxXferCount == 0U) { /* Disable RXNE interrupt */ __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_RXNE | SPI_IT_ERR)); if(hspi->TxXferCount == 0U) { SPI_CloseRxTx_ISR(hspi); } } }
/** * @brief This function handles SPI1 global interrupt. */ void SPI1_IRQHandler(void) { __HAL_SPI_DISABLE_IT(&hspi1, SPI_IT_RXNE); HAL_SPI_Receive(&hspi1, &SPI_rx_buf[0], 3, 100); __HAL_SPI_ENABLE_IT(&hspi1, SPI_IT_RXNE); }
static void SPI_CloseRxTx_ISR(SPI_HandleTypeDef *hspi) { uint32_t tickstart = 0U; __IO uint32_t count = SPI_DEFAULT_TIMEOUT * (SystemCoreClock / 24U / 1000U); tickstart = HAL_GetTick(); /* Disable ERR interrupt */ __HAL_SPI_DISABLE_IT(hspi, SPI_IT_ERR); #if SPI_HAS_FIFO (void)count; if (SPI_EndRxTxTransaction(hspi, SPI_DEFAULT_TIMEOUT, tickstart) != HAL_OK) { SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG); } #else /* Wait until TXE flag is set */ do { if(count-- == 0U) { SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG); break; } } while((hspi->Instance->SR & SPI_FLAG_TXE) == RESET); /* Check the end of the transaction */ if(SPI_CheckFlag_BSY(hspi, SPI_DEFAULT_TIMEOUT, tickstart)!=HAL_OK) { SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG); } /* Clear overrun flag in 2 Lines communication mode because received is not read */ __HAL_SPI_CLEAR_OVRFLAG(hspi); #endif if(hspi->ErrorCode == HAL_SPI_ERROR_NONE) { if(hspi->State == HAL_SPI_STATE_BUSY_RX) { hspi->State = HAL_SPI_STATE_READY; HAL_SPI_RxCpltCallback(hspi); } else { hspi->State = HAL_SPI_STATE_READY; HAL_SPI_TxRxCpltCallback(hspi); } } else { hspi->State = HAL_SPI_STATE_READY; HAL_SPI_ErrorCallback(hspi); } }
static void SPI_CloseTx_ISR(SPI_HandleTypeDef *hspi) { uint32_t tickstart = 0U; __IO uint32_t count = SPI_DEFAULT_TIMEOUT * (SystemCoreClock / 24U / 1000U); /* Init tickstart for timeout management*/ tickstart = HAL_GetTick(); (void)count; #if !SPI_HAS_FIFO /* Wait until TXE flag is set */ do { if(count-- == 0U) { SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG); break; } } while((hspi->Instance->SR & SPI_FLAG_TXE) == RESET); #endif /* Disable TXE and ERR interrupt */ __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_TXE | SPI_IT_ERR)); #if SPI_HAS_FIFO if (SPI_EndTxTransaction(hspi, SPI_DEFAULT_TIMEOUT, tickstart) != HAL_OK) { SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG); } #else /* Check Busy flag */ if(SPI_CheckFlag_BSY(hspi, SPI_DEFAULT_TIMEOUT, tickstart) != HAL_OK) { SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG); } #endif /* Clear overrun flag in 2 Lines communication mode because received is not read */ __HAL_SPI_CLEAR_OVRFLAG(hspi); hspi->State = HAL_SPI_STATE_READY; if(hspi->ErrorCode != HAL_SPI_ERROR_NONE) { HAL_SPI_ErrorCallback(hspi); } else { HAL_SPI_TxCpltCallback(hspi); } }
/** * @brief Tx 16-bit handler for Transmit and Receive in Interrupt mode. * @param hspi pointer to a SPI_HandleTypeDef structure that contains * the configuration information for SPI module. * @retval None */ static void SPI_2linesTxISR_16BIT(struct __SPI_HandleTypeDef *hspi) { /* Transmit data in 16 Bit mode */ hspi->Instance->DR = *((uint16_t *)hspi->pTxBuffPtr); hspi->pTxBuffPtr += sizeof(uint16_t); hspi->TxXferCount--; if(hspi->TxXferCount == 0U) { /* Disable TXE interrupt */ __HAL_SPI_DISABLE_IT(hspi, SPI_IT_TXE); if(hspi->RxXferCount == 0U) { SPI_CloseRxTx_ISR(hspi); } } }
/** * @brief Rx 16-bit handler for Transmit and Receive in Interrupt mode. * @param hspi pointer to a SPI_HandleTypeDef structure that contains * the configuration information for SPI module. * @retval None * * @note: Copied verbatim from STM32Cube */ static void SPI_2linesRxISR_16BIT(struct __SPI_HandleTypeDef *hspi) { /* Receive data in 16 Bit mode */ *((uint16_t*)hspi->pRxBuffPtr) = hspi->Instance->DR; hspi->pRxBuffPtr += sizeof(uint16_t); hspi->RxXferCount--; if(hspi->RxXferCount == 0U) { /* Disable RXNE interrupt */ __HAL_SPI_DISABLE_IT(hspi, SPI_IT_RXNE); if(hspi->TxXferCount == 0U) { SPI_CloseRxTx_ISR(hspi); } } }
int hal_spi_abort(int spi_num) { int rc; struct stm32_hal_spi *spi; int sr; rc = 0; STM32_HAL_SPI_RESOLVE(spi_num, spi); if (spi->slave) { goto err; } __HAL_DISABLE_INTERRUPTS(sr); spi->handle.State = HAL_SPI_STATE_READY; __HAL_SPI_DISABLE_IT(&spi->handle, SPI_IT_TXE | SPI_IT_RXNE | SPI_IT_ERR); spi->handle.Instance->CR1 &= ~SPI_CR1_SPE; __HAL_ENABLE_INTERRUPTS(sr); err: return rc; }
static HAL_StatusTypeDef SPI_WaitFifoStateUntilTimeout(SPI_HandleTypeDef *hspi, uint32_t Fifo, uint32_t State, uint32_t Timeout, uint32_t Tickstart) { __IO uint8_t tmpreg; while ((hspi->Instance->SR & Fifo) != State) { if ((Fifo == SPI_SR_FRLVL) && (State == SPI_FRLVL_EMPTY)) { tmpreg = *((__IO uint8_t *)&hspi->Instance->DR); /* To avoid GCC warning */ UNUSED(tmpreg); } if (Timeout != HAL_MAX_DELAY) { /* TODO: handle HAL_GetTick overflow */ if ((Timeout == 0U) || ((HAL_GetTick() - Tickstart) >= Timeout)) { /* Disable the SPI and reset the CRC: the CRC value should be cleared on both master and slave sides in order to resynchronize the master and slave for their respective CRC calculation */ /* Disable TXE, RXNE and ERR interrupts for the interrupt process */ __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_TXE | SPI_IT_RXNE | SPI_IT_ERR)); hspi->State = HAL_SPI_STATE_READY; /* Process Unlocked */ __HAL_UNLOCK(hspi); return HAL_TIMEOUT; } } } return HAL_OK; }
HAL_StatusTypeDef DevSPI::waitForFlag( uint32_t flag, uint32_t val, int ticks ) { if( ticks < 0 ) { ticks = maxWait; }; uint32_t st = HAL_GetTick(), ct = 0; for( ; ct < (unsigned)ticks; ct = HAL_GetTick() - st ) { if( ( spi->Instance->SR & flag ) == val ) { return HAL_OK; } taskYieldFun(); } // is really need? __HAL_SPI_DISABLE_IT( spi, (SPI_IT_TXE | SPI_IT_RXNE | SPI_IT_ERR ) ); if( spi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLED ) { __HAL_SPI_RESET_CRC( spi ); } spi->State= HAL_SPI_STATE_READY; __HAL_UNLOCK( spi ); return HAL_TIMEOUT; }
/* * GPIO interrupt when slave gets selected/deselected. */ static void spi_ss_isr(void *arg) { struct stm32_hal_spi *spi = (struct stm32_hal_spi *)arg; int ss; int len; uint16_t reg; spi_stat.ss_irq++; ss = hal_gpio_read(spi->cfg->ss_pin); if (ss == 0 && !spi->selected) { /* * We're now seeing chip select. Enable SPI, SPI interrupts. */ if (spi->tx_in_prog) { __HAL_SPI_ENABLE_IT(&spi->handle, SPI_IT_RXNE | SPI_IT_TXE | SPI_IT_ERR); } else { __HAL_SPI_ENABLE_IT(&spi->handle, SPI_IT_TXE | SPI_IT_ERR); } reg = spi->handle.Instance->CR1; reg &= ~SPI_CR1_SSI; reg |= SPI_CR1_SPE; spi->handle.Instance->CR1 = reg; spi->selected = 1; } if (ss == 1 && spi->selected) { /* * Chip select done. Check whether there's pending data to RX. */ if (spi->handle.Instance->SR & SPI_SR_RXNE && spi->handle.RxISR) { spi->handle.RxISR(&spi->handle); } /* * Disable SPI. */ reg = spi->handle.Instance->CR1; reg &= ~SPI_CR1_SPE; reg |= SPI_CR1_SSI; spi->handle.Instance->CR1 = reg; __HAL_SPI_DISABLE_IT(&spi->handle, SPI_IT_RXNE|SPI_IT_TXE|SPI_IT_ERR); len = spi->handle.RxXferSize - spi->handle.RxXferCount; if (len) { /* * If some data was clocked out, reset to start sending * default data and call callback, if user was waiting for * data. */ spi->handle.State = HAL_SPI_STATE_READY; HAL_SPI_QueueTransmit(&spi->handle, spi->def_char, 2); if (spi->tx_in_prog) { spi->tx_in_prog = 0; if (spi->txrx_cb_func) { spi->txrx_cb_func(spi->txrx_cb_arg, len); } } } spi->selected = 0; } }