1 | {
|
2 | uint32_t tmp = 0U, tmp1 = 0U;
|
3 | HAL_StatusTypeDef errorcode = HAL_OK;
|
4 |
|
5 | /* check rx & tx dma handles */
|
6 | assert_param(IS_SPI_DMA_HANDLE(hspi->hdmarx));
|
7 | assert_param(IS_SPI_DMA_HANDLE(hspi->hdmatx));
|
8 |
|
9 | /* Check Direction parameter */
|
10 | assert_param(IS_SPI_DIRECTION_2LINES(hspi->Init.Direction));
|
11 |
|
12 | /* Process locked */
|
13 | __HAL_LOCK(hspi);
|
14 |
|
15 | tmp = hspi->State;
|
16 | tmp1 = hspi->Init.Mode;
|
17 | if (!((tmp == HAL_SPI_STATE_READY) ||
|
18 | ((tmp1 == SPI_MODE_MASTER) && (hspi->Init.Direction == SPI_DIRECTION_2LINES) && (tmp == HAL_SPI_STATE_BUSY_RX))))
|
19 | {
|
20 | errorcode = HAL_BUSY;
|
21 | goto error;
|
22 | }
|
23 |
|
24 | if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0U))
|
25 | {
|
26 | errorcode = HAL_ERROR;
|
27 | goto error;
|
28 | }
|
29 |
|
30 | /* Don't overwrite in case of HAL_SPI_STATE_BUSY_RX */
|
31 | if (hspi->State != HAL_SPI_STATE_BUSY_RX)
|
32 | {
|
33 | hspi->State = HAL_SPI_STATE_BUSY_TX_RX;
|
34 | }
|
35 |
|
36 | /* Set the transaction information */
|
37 | hspi->ErrorCode = HAL_SPI_ERROR_NONE;
|
38 | hspi->pTxBuffPtr = (uint8_t *)pTxData;
|
39 | hspi->TxXferSize = Size;
|
40 | hspi->TxXferCount = Size;
|
41 | hspi->pRxBuffPtr = (uint8_t *)pRxData;
|
42 | hspi->RxXferSize = Size;
|
43 | hspi->RxXferCount = Size;
|
44 |
|
45 | /* Init field not used in handle to zero */
|
46 | hspi->RxISR = NULL;
|
47 | hspi->TxISR = NULL;
|
48 |
|
49 | #if (USE_SPI_CRC != 0U)
|
50 | /* Reset CRC Calculation */
|
51 | if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
|
52 | {
|
53 | SPI_RESET_CRC(hspi);
|
54 | }
|
55 | #endif /* USE_SPI_CRC */
|
56 |
|
57 |
|
58 | #if defined (STM32F302xC) || defined (STM32F303xC) || defined (STM32F373xC) || defined (STM32F358xx) || defined (STM32F378xx)
|
59 | /* packing mode management is enabled by the DMA settings */
|
60 | if ((hspi->Init.DataSize <= SPI_DATASIZE_8BIT) && (hspi->hdmarx->Init.MemDataAlignment == DMA_MDATAALIGN_HALFWORD))
|
61 | {
|
62 | /* Restriction the DMA data received is not allowed in this mode */
|
63 | errorcode = HAL_ERROR;
|
64 | goto error;
|
65 | }
|
66 | #endif
|
67 |
|
68 | /* Reset the threshold bit */
|
69 | CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_LDMATX | SPI_CR2_LDMARX);
|
70 |
|
71 | /* The packing mode management is enabled by the DMA settings according the spi data size */
|
72 | if (hspi->Init.DataSize > SPI_DATASIZE_8BIT)
|
73 | {
|
74 | /* Set fiforxthreshold according the reception data length: 16bit */
|
75 | CLEAR_BIT(hspi->Instance->CR2, SPI_RXFIFO_THRESHOLD);
|
76 | }
|
77 | else
|
78 | {
|
79 | /* Set fiforxthresold according the reception data length: 8bit */
|
80 | SET_BIT(hspi->Instance->CR2, SPI_RXFIFO_THRESHOLD);
|
81 |
|
82 | if (hspi->hdmatx->Init.MemDataAlignment == DMA_MDATAALIGN_HALFWORD)
|
83 | {
|
84 | if ((hspi->TxXferSize & 0x1U) == 0x0U)
|
85 | {
|
86 | CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_LDMATX);
|
87 | hspi->TxXferCount = hspi->TxXferCount >> 1U;
|
88 | }
|
89 | else
|
90 | {
|
91 | SET_BIT(hspi->Instance->CR2, SPI_CR2_LDMATX);
|
92 | hspi->TxXferCount = (hspi->TxXferCount >> 1U) + 1U;
|
93 | }
|
94 | }
|
95 |
|
96 | if (hspi->hdmarx->Init.MemDataAlignment == DMA_MDATAALIGN_HALFWORD)
|
97 | {
|
98 | /* Set fiforxthresold according the reception data length: 16bit */
|
99 | CLEAR_BIT(hspi->Instance->CR2, SPI_RXFIFO_THRESHOLD);
|
100 |
|
101 | if ((hspi->RxXferCount & 0x1U) == 0x0U)
|
102 | {
|
103 | CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_LDMARX);
|
104 | hspi->RxXferCount = hspi->RxXferCount >> 1U;
|
105 | }
|
106 | else
|
107 | {
|
108 | SET_BIT(hspi->Instance->CR2, SPI_CR2_LDMARX);
|
109 | hspi->RxXferCount = (hspi->RxXferCount >> 1U) + 1U;
|
110 | }
|
111 | }
|
112 | }
|
113 |
|
114 | /* Check if we are in Rx only or in Rx/Tx Mode and configure the DMA transfer complete callback */
|
115 | if (hspi->State == HAL_SPI_STATE_BUSY_RX)
|
116 | {
|
117 | /* Set the SPI Rx DMA Half transfer complete callback */
|
118 | hspi->hdmarx->XferHalfCpltCallback = SPI_DMAHalfReceiveCplt;
|
119 | hspi->hdmarx->XferCpltCallback = SPI_DMAReceiveCplt;
|
120 | }
|
121 | else
|
122 | {
|
123 | /* Set the SPI Tx/Rx DMA Half transfer complete callback */
|
124 | hspi->hdmarx->XferHalfCpltCallback = SPI_DMAHalfTransmitReceiveCplt;
|
125 | hspi->hdmarx->XferCpltCallback = SPI_DMATransmitReceiveCplt;
|
126 | }
|
127 |
|
128 | /* Set the DMA error callback */
|
129 | hspi->hdmarx->XferErrorCallback = SPI_DMAError;
|
130 |
|
131 | /* Set the DMA AbortCpltCallback */
|
132 | hspi->hdmarx->XferAbortCallback = NULL;
|
133 |
|
134 | /* Enable the Rx DMA Stream/Channel */
|
135 | HAL_DMA_Start_IT(hspi->hdmarx, (uint32_t)&hspi->Instance->DR, (uint32_t)hspi->pRxBuffPtr, hspi->RxXferCount);
|
136 |
|
137 | /* Enable Rx DMA Request */
|
138 | SET_BIT(hspi->Instance->CR2, SPI_CR2_RXDMAEN);
|
139 |
|
140 | /* Set the SPI Tx DMA transfer complete callback as NULL because the communication closing
|
141 | is performed in DMA reception complete callback */
|
142 | hspi->hdmatx->XferHalfCpltCallback = NULL;
|
143 | hspi->hdmatx->XferCpltCallback = NULL;
|
144 | hspi->hdmatx->XferErrorCallback = NULL;
|
145 | hspi->hdmatx->XferAbortCallback = NULL;
|
146 |
|
147 | /* Enable the Tx DMA Stream/Channel */
|
148 | HAL_DMA_Start_IT(hspi->hdmatx, (uint32_t)hspi->pTxBuffPtr, (uint32_t)&hspi->Instance->DR, hspi->TxXferCount);
|
149 |
|
150 | /* Check if the SPI is already enabled */
|
151 | if ((hspi->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE)
|
152 | {
|
153 | /* Enable SPI peripheral */
|
154 | __HAL_SPI_ENABLE(hspi);
|
155 | }
|
156 | /* Enable the SPI Error Interrupt Bit */
|
157 | __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_ERR));
|
158 |
|
159 | /* Enable Tx DMA Request */
|
160 | SET_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN);
|
161 |
|
162 | error :
|
163 | /* Process Unlocked */
|
164 | __HAL_UNLOCK(hspi);
|
165 | return errorcode;
|
166 | }
|