Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
DMA и прерывания вы не сможете удобно и эффективно использовать при передаче «солянки» из данных и команд…
DMA channel x number of data register (DMA_CNDTRx)
…
NDT[15:0]: Number of data to transfer
Number of data to be transferred (0 up to 65535). This register can only be written when the channel is disabled. Once the channel is enabled, this register is read-only, indicating the remaining bytes to be transmitted. This register decrements after each DMA transfer.
Что за дисплей подключали?
про 16 бит у меня написано, да и не ставилась цель рассказывать про битность
DMA и прерывания вы не сможете удобно и эффективно использовать при передаче «солянки» из данных и команд
Меня привлекают общедоступные популярные библиотеки от производителя, которые обновляются регулярно. Они экономят время. При этом, я не отбрасываю теорию и low-level работу, когда это необходимо.
/**
* @brief Transmit and Receive an amount of data in blocking mode.
* @param hspi: pointer to a SPI_HandleTypeDef structure that contains
* the configuration information for SPI module.
* @param pTxData: pointer to transmission data buffer
* @param pRxData: pointer to reception data buffer
* @param Size: amount of data to be sent and received
* @param Timeout: Timeout duration
* @retval HAL status
*/
HAL_StatusTypeDef HAL_SPI_TransmitReceive(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size, uint32_t Timeout)
{
#ifdef USE_SPI_CRC
__IO uint16_t tmpreg = 0U;
#endif
uint32_t tickstart = 0U;
HAL_StatusTypeDef errorcode = HAL_OK;
/* Check Direction parameter */
assert_param(IS_SPI_DIRECTION_2LINES(hspi->Init.Direction));
/* Process Locked */
__HAL_LOCK(hspi);
/* Init tickstart for timeout managment*/
tickstart = HAL_GetTick();
if(!((hspi->State == HAL_SPI_STATE_READY) || \
((hspi->Init.Mode == SPI_MODE_MASTER) && (hspi->Init.Direction == SPI_DIRECTION_2LINES) && (hspi->State == HAL_SPI_STATE_BUSY_RX))))
{
errorcode = HAL_BUSY;
goto error;
}
if((pTxData == NULL) || (pRxData == NULL) || (Size == 0U))
{
errorcode = HAL_ERROR;
goto error;
}
/* Don't overwrite in case of HAL_SPI_STATE_BUSY_RX */
if(hspi->State == HAL_SPI_STATE_READY)
{
hspi->State = HAL_SPI_STATE_BUSY_TX_RX;
}
/* Set the transaction information */
hspi->ErrorCode = HAL_SPI_ERROR_NONE;
hspi->pRxBuffPtr = (uint8_t *)pRxData;
hspi->RxXferCount = Size;
hspi->RxXferSize = Size;
hspi->pTxBuffPtr = (uint8_t *)pTxData;
hspi->TxXferCount = Size;
hspi->TxXferSize = Size;
/*Init field not used in handle to zero */
hspi->RxISR = NULL;
hspi->TxISR = NULL;
#ifdef USE_SPI_CRC
/* Reset CRC Calculation */
if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
{
SPI_RESET_CRC(hspi);
}
#endif
/* Check if the SPI is already enabled */
if((hspi->Instance->CR1 &SPI_CR1_SPE) != SPI_CR1_SPE)
{
/* Enable SPI peripheral */
__HAL_SPI_ENABLE(hspi);
}
/* Transmit and Receive data in 16 Bit mode */
if(hspi->Init.DataSize == SPI_DATASIZE_16BIT)
{
while ((hspi->TxXferCount > 0U) || (hspi->RxXferCount > 0U))
{
/* Check TXE flag */
if((hspi->TxXferCount > 0U) && (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXE)))
{
hspi->Instance->DR = *((uint16_t *)pTxData);
pTxData += sizeof(uint16_t);
hspi->TxXferCount--;
#ifdef USE_SPI_CRC
/* Enable CRC Transmission */
if((hspi->TxXferCount == 0U) && (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE))
{
SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);
}
#endif
}
/* Check RXNE flag */
if((hspi->RxXferCount > 0U) && (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXNE)))
{
*((uint16_t *)pRxData) = hspi->Instance->DR;
pRxData += sizeof(uint16_t);
hspi->RxXferCount--;
}
if((Timeout != HAL_MAX_DELAY) && ((HAL_GetTick()-tickstart) >= Timeout))
{
errorcode = HAL_TIMEOUT;
goto error;
}
}
}
/* Transmit and Receive data in 8 Bit mode */
else
{
while((hspi->TxXferCount > 0U) || (hspi->RxXferCount > 0U))
{
/* check TXE flag */
if((hspi->TxXferCount > 0U) && (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXE)))
{
*(__IO uint8_t *)&hspi->Instance->DR = (*pTxData++);
hspi->TxXferCount--;
#ifdef USE_SPI_CRC
/* Enable CRC Transmission */
if((hspi->TxXferCount == 0U) && (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE))
{
SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);
}
#endif
}
/* Wait until RXNE flag is reset */
if((hspi->RxXferCount > 0U) && (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXNE)))
{
(*(uint8_t *)pRxData++) = hspi->Instance->DR;
hspi->RxXferCount--;
}
if((Timeout != HAL_MAX_DELAY) && ((HAL_GetTick()-tickstart) >= Timeout))
{
errorcode = HAL_TIMEOUT;
goto error;
}
}
}
#ifdef USE_SPI_CRC
/* Read CRC from DR to close CRC calculation process */
if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
{
/* Wait until TXE flag */
if(SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_RXNE, SET, Timeout, tickstart) != HAL_OK)
{
/* Error on the CRC reception */
SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC);
errorcode = HAL_TIMEOUT;
goto error;
}
/* Read CRC */
tmpreg = hspi->Instance->DR;
/* To avoid GCC warning */
UNUSED(tmpreg);
}
/* Check if CRC error occurred */
if(__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_CRCERR))
{
SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC);
/* Clear CRC Flag */
__HAL_SPI_CLEAR_CRCERRFLAG(hspi);
errorcode = HAL_ERROR;
}
#endif
/* Check the end of the transaction */
if(SPI_CheckFlag_BSY(hspi, Timeout, tickstart) != HAL_OK)
{
SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
errorcode = HAL_ERROR;
}
error :
hspi->State = HAL_SPI_STATE_READY;
__HAL_UNLOCK(hspi);
return errorcode;
}
/* Check the end of the transaction */
if(SPI_CheckFlag_BSY(hspi, Timeout, tickstart) != HAL_OK)
{
SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
errorcode = HAL_ERROR;
}
STM32: SPI: LCD — Вы всё делаете не так [восклицательный знак]