@@ -73,11 +73,40 @@ static int spi_stm32_get_err(SPI_TypeDef *spi)
7373 return 0 ;
7474}
7575
76- /* Shift a SPI frame as master. */
77- static void spi_stm32_shift_m ( SPI_TypeDef * spi , struct spi_stm32_data * data )
76+ static inline void spi_stm32_shift_m8 ( SPI_TypeDef * spi ,
77+ struct spi_stm32_data * data )
7878{
79+ struct spi_context * ctx = & (data -> ctx );
7980 u16_t tx_frame = SPI_STM32_TX_NOP ;
8081 u16_t rx_frame ;
82+ bool xfer_16 ;
83+
84+ if (spi_context_tx_buf_on (ctx ) && spi_context_rx_buf_on (ctx )) {
85+ xfer_16 = (MIN (ctx -> tx_len , ctx -> rx_len ) > 1 ) ? true : false;
86+ } else if (spi_context_tx_buf_on (ctx )) {
87+ xfer_16 = (ctx -> tx_len > 1 ) ? true : false;
88+ } else if (spi_context_rx_buf_on (ctx )) {
89+ xfer_16 = (ctx -> rx_len > 1 ) ? true : false;
90+ } else {
91+ /* Should never get here, but place case for it anyways */
92+ return ;
93+ }
94+
95+ #if defined(CONFIG_SPI_STM32_HAS_FIFO )
96+ if (xfer_16 ) {
97+ ll_func_set_fifo_threshold_16bit (spi );
98+ } else {
99+ ll_func_set_fifo_threshold_8bit (spi );
100+ }
101+ #endif
102+
103+ if (xfer_16 && spi_context_tx_buf_on (ctx )) {
104+ tx_frame = UNALIGNED_GET ((u16_t * )(ctx -> tx_buf ));
105+ spi_context_update_tx (ctx , 1 , 2 );
106+ } else if (spi_context_tx_buf_on (ctx )) {
107+ tx_frame = UNALIGNED_GET ((u8_t * )(ctx -> tx_buf ));
108+ spi_context_update_tx (ctx , 1 , 1 );
109+ }
81110
82111 while (!ll_func_tx_is_empty (spi )) {
83112 /* NOP */
@@ -95,37 +124,68 @@ static void spi_stm32_shift_m(SPI_TypeDef *spi, struct spi_stm32_data *data)
95124 }
96125#endif
97126
98- if (SPI_WORD_SIZE_GET (data -> ctx .config -> operation ) == 8 ) {
99- if (spi_context_tx_on (& data -> ctx )) {
100- tx_frame = UNALIGNED_GET ((u8_t * )(data -> ctx .tx_buf ));
101- }
102- LL_SPI_TransmitData8 (spi , tx_frame );
103- /* The update is ignored if TX is off. */
104- spi_context_update_tx (& data -> ctx , 1 , 1 );
105- } else {
106- if (spi_context_tx_on (& data -> ctx )) {
107- tx_frame = UNALIGNED_GET ((u16_t * )(data -> ctx .tx_buf ));
108- }
127+ if (xfer_16 ) {
109128 LL_SPI_TransmitData16 (spi , tx_frame );
110- /* The update is ignored if TX is off. */
111- spi_context_update_tx ( & data -> ctx , 2 , 1 );
129+ } else {
130+ LL_SPI_TransmitData8 ( spi , tx_frame );
112131 }
113132
114133 while (!ll_func_rx_is_not_empty (spi )) {
115134 /* NOP */
116135 }
117136
118- if (SPI_WORD_SIZE_GET (data -> ctx .config -> operation ) == 8 ) {
119- rx_frame = LL_SPI_ReceiveData8 (spi );
120- if (spi_context_rx_buf_on (& data -> ctx )) {
121- UNALIGNED_PUT (rx_frame , (u8_t * )data -> ctx .rx_buf );
137+ if (xfer_16 ) {
138+ rx_frame = LL_SPI_ReceiveData16 (spi );
139+ if (spi_context_rx_buf_on (ctx )) {
140+ UNALIGNED_PUT (rx_frame , (u16_t * )ctx -> rx_buf );
141+ spi_context_update_rx (ctx , 1 , 2 );
122142 }
123- spi_context_update_rx (& data -> ctx , 1 , 1 );
124143 } else {
125- rx_frame = LL_SPI_ReceiveData16 (spi );
126- if (spi_context_rx_buf_on (& data -> ctx )) {
127- UNALIGNED_PUT (rx_frame , (u16_t * )data -> ctx .rx_buf );
144+ rx_frame = LL_SPI_ReceiveData8 (spi );
145+ if (spi_context_rx_buf_on (ctx )) {
146+ UNALIGNED_PUT (rx_frame , (u8_t * )ctx -> rx_buf );
147+ spi_context_update_rx (ctx , 1 , 1 );
148+ }
149+ }
150+ }
151+
152+ static inline void spi_stm32_shift_m16 (SPI_TypeDef * spi ,
153+ struct spi_stm32_data * data )
154+ {
155+ u16_t tx_frame = SPI_STM32_TX_NOP ;
156+ u16_t rx_frame ;
157+
158+ if (spi_context_tx_buf_on (& data -> ctx )) {
159+ tx_frame = UNALIGNED_GET ((u16_t * )(data -> ctx .tx_buf ));
160+ spi_context_update_tx (& data -> ctx , 2 , 1 );
161+ }
162+
163+ while (!ll_func_tx_is_empty (spi )) {
164+ /* NOP */
165+ }
166+
167+ #ifdef CONFIG_SOC_SERIES_STM32MP1X
168+ /* With the STM32MP1, if the device is the SPI master, we need to enable
169+ * the start of the transfer with LL_SPI_StartMasterTransfer(spi)
170+ */
171+ if (LL_SPI_GetMode (spi ) == LL_SPI_MODE_MASTER ) {
172+ LL_SPI_StartMasterTransfer (spi );
173+ while (!LL_SPI_IsActiveMasterTransfer (spi )) {
174+ /* NOP */
128175 }
176+ }
177+ #endif
178+
179+ LL_SPI_TransmitData16 (spi , tx_frame );
180+
181+ while (!ll_func_rx_is_not_empty (spi )) {
182+ /* NOP */
183+ }
184+
185+ rx_frame = LL_SPI_ReceiveData16 (spi );
186+
187+ if (spi_context_rx_buf_on (& data -> ctx )) {
188+ UNALIGNED_PUT (rx_frame , (u16_t * )data -> ctx .rx_buf );
129189 spi_context_update_rx (& data -> ctx , 2 , 1 );
130190 }
131191}
@@ -176,7 +236,11 @@ static int spi_stm32_shift_frames(SPI_TypeDef *spi, struct spi_stm32_data *data)
176236 u16_t operation = data -> ctx .config -> operation ;
177237
178238 if (SPI_OP_MODE_GET (operation ) == SPI_OP_MODE_MASTER ) {
179- spi_stm32_shift_m (spi , data );
239+ if (SPI_WORD_SIZE_GET (data -> ctx .config -> operation ) == 8 ) {
240+ spi_stm32_shift_m8 (spi , data );
241+ } else {
242+ spi_stm32_shift_m16 (spi , data );
243+ }
180244 } else {
181245 spi_stm32_shift_s (spi , data );
182246 }
0 commit comments