A31L12x F/W Packages  1.4.0
ABOV Cortex-M0+ Core based MCUs Integrated Driver
A31L12x_hal_spin.c
Go to the documentation of this file.
1 /***************************************************************************//****************************************************************************/
34 
35 /* Includes ----------------------------------------------------------------- */
36 //******************************************************************************
37 // Include
38 //******************************************************************************
39 
40 #include "A31L12x_hal_scu.h"
41 #include "A31L12x_hal_spin.h"
42 
43 //******************************************************************************
44 // Variable
45 //******************************************************************************
46 
47 uint32_t SPIn_BaseClock;
48 Bool SPIn_RXC = FALSE; // rx complete flag
49 
50 /* Public Functions --------------------------------------------------------- */
51 //******************************************************************************
52 // Function
53 //******************************************************************************
54 
55 /*-------------------------------------------------------------------------*//*-------------------------------------------------------------------------*/
64 static void spi_set_divisors( SPIn_Type* SPIx, uint32_t baudrate )
65 {
66  uint32_t numerator;
67  uint32_t denominator;
68  uint32_t n;
69  uint32_t bdr;
70 
71  // n
72  {
73  // baudrate = PCLK / (2 * (bdr + 1))
74  // bdr = (PCLK / (2 * baudrate)) - 1
75  n = 2;
76  }
77 
78  //--------------------------------------
79  // numerator & denominator
80  //
81  // bdr = SPIn_BaseClock / n / baudrate - 1
82  //--------------------------------------
83  numerator = SPIn_BaseClock;
84  denominator = baudrate;
85 
86  bdr = numerator / n / denominator - 1;
87 
88  SPIx->PREDR = ( uint16_t )( bdr & 0xffff );
89 }
90 
91 /*-------------------------------------------------------------------------*//*-------------------------------------------------------------------------*/
101 HAL_Status_Type HAL_SPIn_Init( SPIn_Type* SPIx, SPIn_CFG_Type* SPIn_Config )
102 {
103  /* Check SPI handle */
104  if( SPIx == NULL )
105  {
106  return HAL_ERROR;
107  }
108 
109 #if 1 // supported
110  if( SPIx == ( SPIn_Type* )SPI0 )
111  {
112  // enable peripheral clock and reset peripheral
113  HAL_SCU_Peripheral_EnableClock2( PPCLKEN2_SPI0CLKE, PPxCLKE_Enable );
114  HAL_SCU_Peripheral_SetReset2( PPRST2_SPI0RST );
115  }
116 #endif
117 
118 #if 1 // supported
119  if( SPIx == ( SPIn_Type* )SPI1 )
120  {
121  // enable peripheral clock and reset peripheral
122  HAL_SCU_Peripheral_EnableClock2( PPCLKEN2_SPI1CLKE, PPxCLKE_Enable );
123  HAL_SCU_Peripheral_SetReset2( PPRST2_SPI1RST );
124  }
125 #endif
126 
127  // select baudrate
128  SPIn_BaseClock = SystemPeriClock;
129  spi_set_divisors( SPIx, SPIn_Config->Baudrate );
130 
131  // select bit order / polarity(idle state) / phase(start state)
132  SPIx->CR = 0
133  | ( SPIn_Config->Order << SPIn_CR_FLSBn_Pos )
134  | ( SPIn_Config->ACK << SPIn_CR_CPOLn_Pos )
135  | ( SPIn_Config->Edge << SPIn_CR_CPHAn_Pos )
136  ;
137 
138  // clear flag
139  SPIx->SR = SPIx->SR
140  | SPIn_SR_SPInIFLAG_Msk // SPInIFLAG[07:07] [0] in [0(no request occurred) 1(request occurred; reset by w1)]
141  | SPIn_SR_SSnHIGH_Msk // SSnHIGH[04:04] [0] in [0(no effect) 1(The SSn pin has gone from low level to high; reset by w1)]
142  ;
143 
144  // clear rxc flag
145  SPIn_RXC = FALSE;
146 
147  // dummy read
148  SPIn_ReceiveByte( SPIx );
149  SPIn_ReceiveByte( SPIx );
150 
151  return HAL_OK;
152 }
153 
154 /*-------------------------------------------------------------------------*//*-------------------------------------------------------------------------*/
161 HAL_Status_Type SPIn_DeInit( SPIn_Type* SPIx )
162 {
163  /* Check SPI handle */
164  if( SPIx == NULL )
165  {
166  return HAL_ERROR;
167  }
168 
169 #if 1 // supported
170  if( SPIx == ( SPIn_Type* )SPI0 )
171  {
172  // reset peripheral and disable peripheral clock
173  HAL_SCU_Peripheral_SetReset2( PPRST2_SPI0RST );
174  HAL_SCU_Peripheral_EnableClock2( PPCLKEN2_SPI0CLKE, PPxCLKE_Disable );
175  }
176 #endif
177 
178 #if 1 // supported
179  if( SPIx == ( SPIn_Type* )SPI1 )
180  {
181  // reset peripheral and disable peripheral clock
182  HAL_SCU_Peripheral_SetReset2( PPRST2_SPI1RST );
183  HAL_SCU_Peripheral_EnableClock2( PPCLKEN2_SPI1CLKE, PPxCLKE_Disable );
184  }
185 #endif
186 
187  return HAL_OK;
188 }
189 
190 /*-------------------------------------------------------------------------*//*-------------------------------------------------------------------------*/
201 {
202  /* Check SPIn_Config */
203  if( SPIn_Config == NULL )
204  {
205  return HAL_ERROR;
206  }
207 
208  SPIn_Config->Baudrate = 38400;
209  SPIn_Config->Order = SPIn_LSB_FIRST;
210 
211 #if 1 // CPOLn : 0, CPHAn : 0 (X)
212  SPIn_Config->ACK = SPIn_TX_RISING;
213  SPIn_Config->Edge = SPIn_TX_LEADEDGE_SAMPLE;
214 #endif
215 
216 #if 0 // CPOLn : 0, CPHAn : 1 (O)
217  SPIn_Config->ACK = SPIn_TX_RISING;
218  SPIn_Config->Edge = SPIn_TX_LEADEDGE_SETUP;
219 #endif
220 
221 #if 0 // CPOLn : 1, CPHAn : 0 (X)
222  SPIn_Config->ACK = SPIn_TX_FALLING;
223  SPIn_Config->Edge = SPIn_TX_LEADEDGE_SAMPLE;
224 #endif
225 
226 #if 0 // CPOLn : 1, CPHAn : 1 (O)
227  SPIn_Config->ACK = SPIn_TX_FALLING;
228  SPIn_Config->Edge = SPIn_TX_LEADEDGE_SETUP;
229 #endif
230 
231  return HAL_OK;
232 }
233 
234 /*-------------------------------------------------------------------------*//*-------------------------------------------------------------------------*/
248 HAL_Status_Type SPIn_ConfigInterrupt( SPIn_Type* SPIx, SPIn_INT_Type SPIn_IntCfg, FunctionalState NewState )
249 {
250  uint32_t mask;
251 
252  /* Check SPI handle */
253  if( SPIx == NULL )
254  {
255  return HAL_ERROR;
256  }
257 
258  // get mask
259  switch( SPIn_IntCfg )
260  {
261  case SPIn_INTCFG_SPInIEN:
262  mask = SPIn_CR_SPInIEN_Msk;
263  break;
264 
265  default:
266  return HAL_ERROR;
267  }
268 
269  // enable/disable
270  if( NewState == ENABLE )
271  {
272  SPIx->CR |= mask;
273  }
274  else
275  {
276  SPIx->CR &= ~mask;
277  }
278 
279  return HAL_OK;
280 }
281 
282 /*-------------------------------------------------------------------------*//*-------------------------------------------------------------------------*/
299 {
300  uint16_t mask;
301 
302  /* Check SPI handle */
303  if( SPIx == NULL )
304  {
305  return HAL_ERROR;
306  }
307 
308  // if Control is for SPIx->CR
309  if( Control <= SPIn_CONTROL_SPInMS )
310  {
311  switch( Control )
312  {
313  case SPIn_CONTROL_SPInMS:
314  mask = SPIn_CR_SPInMS_Msk;
315  break;
316  }
317 
318  if( NewState == ENABLE )
319  {
320  SPIx->CR |= mask;
321  }
322  else
323  {
324  SPIx->CR &= ~mask;
325  }
326  }
327 
328  // if Control is for SPIx->SR
329  if( Control >= SPIn_CONTROL_FXCHn )
330  {
331  switch( Control )
332  {
333  case SPIn_CONTROL_FXCHn:
334  mask = SPIn_SR_FXCHn_Msk;
335  break;
336  case SPIn_CONTROL_SSnEN:
337  mask = SPIn_SR_SSnEN_Msk;
338  break;
339  }
340 
341  if( NewState == ENABLE )
342  {
343  SPIx->SR |= mask;
344  }
345  else
346  {
347  SPIx->SR &= ~mask;
348  }
349  }
350 
351  return HAL_OK;
352 }
353 
354 /*-------------------------------------------------------------------------*//*-------------------------------------------------------------------------*/
364 HAL_Status_Type SPIn_Enable( SPIn_Type* SPIx, FunctionalState state )
365 {
366  /* Check SPI handle */
367  if( SPIx == NULL )
368  {
369  return HAL_ERROR;
370  }
371 
372  if( state == ENABLE )
373  {
374  SPIx->CR |= ( 1 << SPIn_CR_SPInEN_Pos );
375  }
376  else
377  {
378  SPIx->CR &= ~( 1 << SPIn_CR_SPInEN_Pos );
379  }
380 
381  return HAL_OK;
382 }
383 
384 /*-------------------------------------------------------------------------*//*-------------------------------------------------------------------------*/
394 {
395  uint32_t reg;
396 
397  /* Check SPI handle */
398  if( SPIx == NULL )
399  {
400  return HAL_ERROR;
401  }
402 
403  reg = SPIx->SR;
404  reg &= ~SPIn_SR_SSnHIGH_Msk;
405 
406  switch( Status )
407  {
409  reg |= SPIn_SR_SPInIFLAG_Msk;
410  break;
411 
412  default:
413  return HAL_ERROR;
414  }
415 
416  SPIx->SR = reg;
417 
418  return HAL_OK;
419 }
420 
421 /*-------------------------------------------------------------------------*//*-------------------------------------------------------------------------*/
428 uint8_t SPIn_GetStatus( SPIn_Type* SPIx )
429 {
430  return ( SPIx->SR );
431 }
432 
433 /*-------------------------------------------------------------------------*//*-------------------------------------------------------------------------*/
442 HAL_Status_Type SPIn_SendByte( SPIn_Type* SPIx, uint8_t Data )
443 {
444  /* Check SPI handle */
445  if( SPIx == NULL )
446  {
447  return HAL_ERROR;
448  }
449 
450  SPIx->TDR = Data;
451 
452  return HAL_OK;
453 }
454 
455 /*-------------------------------------------------------------------------*//*-------------------------------------------------------------------------*/
462 uint8_t SPIn_ReceiveByte( SPIn_Type* SPIx )
463 {
464  return SPIx->RDR;
465 }
466 
467 /*-------------------------------------------------------------------------*//*-------------------------------------------------------------------------*/
484 uint32_t SPIn_Send( SPIn_Type* SPIx, uint8_t* txbuf, uint32_t buflen, TRANSFER_BLOCK_Type flag )
485 {
486  uint32_t bToSend, bSent, timeOut;
487  uint8_t* pChar = txbuf;
488 
489  // init counter
490  bToSend = buflen;
491  bSent = 0;
492 
493  // Blocking Mode
494  if( flag == BLOCKING )
495  {
496  while( bToSend )
497  {
498  // send byte
499  SPIn_SendByte( SPIx, ( *pChar++ ) );
500 
501  // wait until tx data register is empty with timeout
502  timeOut = SPIn_BLOCKING_TIMEOUT;
503  while( !( SPIx->SR & SPIn_SR_SPInIFLAG_Msk ) )
504  {
505  if( timeOut == 0 )
506  {
507  break;
508  }
509  timeOut--;
510  }
511 
512  // if timeout
513  if( timeOut == 0 )
514  {
515  break;
516  }
517 
518  // clear interrupt flag
520 
521  // update counter
522  bToSend--;
523  bSent++;
524 
525  // set rxc flag
526  SPIn_RXC = TRUE;
527  }
528  }
529 
530  // Non-Blocking Mode
531  else
532  {
533  while( bToSend )
534  {
535  // if tx data register is not empty
536  if( SPIx->SR & SPIn_SR_SPInIFLAG_Msk )
537  {
538  break;
539  }
540 
541  // send byte
542  SPIn_SendByte( SPIx, ( *pChar++ ) );
543 
544  // update counter
545  bToSend--;
546  bSent++;
547  }
548  }
549 
550  // return
551  return bSent;
552 }
553 
554 /*-------------------------------------------------------------------------*//*-------------------------------------------------------------------------*/
571 uint32_t SPIn_Receive( SPIn_Type* SPIx, uint8_t* rxbuf, uint32_t buflen, TRANSFER_BLOCK_Type flag )
572 {
573  uint32_t bToRecv, bRecv, timeOut;
574  uint8_t* pChar = rxbuf;
575 
576  // init counter
577  bToRecv = buflen;
578  bRecv = 0;
579 
580  // Blocking Mode
581  if( flag == BLOCKING )
582  {
583  while( bToRecv )
584  {
585  // wait until data are received with timeout
586  timeOut = SPIn_BLOCKING_TIMEOUT;
587  while( SPIn_RXC == FALSE )
588  {
589  if( timeOut == 0 )
590  {
591  break;
592  }
593  timeOut--;
594  }
595 
596  // if timeout
597  if( timeOut == 0 )
598  {
599  break;
600  }
601 
602  // receive byte
603  ( *pChar++ ) = SPIn_ReceiveByte( SPIx );
604 
605  // update counter
606  bToRecv--;
607  bRecv++;
608 
609  // clear rxc flag
610  SPIn_RXC = FALSE;
611  }
612  }
613 
614  // Non-Blocking Mode
615  else
616  {
617  while( bToRecv )
618  {
619  // if no data were received
620  if( !( SPIx->SR & SPIn_SR_SPInIFLAG_Msk ) )
621  {
622  break;
623  }
624 
625  // receive byte
626  ( *pChar++ ) = SPIn_ReceiveByte( SPIx );
627 
628  // update counter
629  bRecv++;
630  bToRecv--;
631  }
632  }
633 
634  // return
635  return bRecv;
636 }
637 
SPIn_INT_Type
HAL_Status_Type SPIn_Enable(SPIn_Type *SPIx, FunctionalState state)
SPIn enable control.
SPIn_STATUS_Type
uint32_t SPIn_Send(SPIn_Type *SPIx, uint8_t *txbuf, uint32_t buflen, TRANSFER_BLOCK_Type flag)
Send a block of data via SPIn peripheral.
void HAL_SCU_Peripheral_EnableClock2(uint32_t u32PeriClk2, uint32_t u32Ind)
Set Each Peripheral Clock.
HAL_Status_Type HAL_SPIn_Init(SPIn_Type *SPIx, SPIn_CFG_Type *SPIn_Config)
Initialize the SPIn peripheral with the specified parameters.
Bool SPIn_RXC
HAL_Status_Type
SPIn_CONTROL_Type
HAL_Status_Type SPIn_DeInit(SPIn_Type *SPIx)
Deinitialize the SPIn peripheral registers to their default reset values.
static void spi_set_divisors(SPIn_Type *SPIx, uint32_t baudrate)
Determines best dividers to get a target clock rate.
uint8_t SPIn_ReceiveByte(SPIn_Type *SPIx)
Receive a single data from SPIn peripheral.
HAL_Status_Type SPIn_DataControlConfig(SPIn_Type *SPIx, SPIn_CONTROL_Type Control, FunctionalState NewState)
Configure Data Control mode for SPIn peripheral.
uint32_t SPIn_Receive(SPIn_Type *SPIx, uint8_t *rxbuf, uint32_t buflen, TRANSFER_BLOCK_Type flag)
Receive a block of data via SPIn peripheral.
HAL_Status_Type SPIn_ClearStatus(SPIn_Type *SPIx, SPIn_STATUS_Type Status)
This function clears the flag bit of Status Register.
HAL_Status_Type SPIn_ConfigStructInit(SPIn_CFG_Type *SPIn_Config)
Fills each SPIn_CFG_Type structure member with its default value:
HAL_Status_Type SPIn_SendByte(SPIn_Type *SPIx, uint8_t Data)
Transmit a single data through SPIn peripheral.
SPIn_ACK_Type ACK
Contains all macro definitions and function prototypes support for spin firmware library on A31L12x.
FunctionalState
TRANSFER_BLOCK_Type
uint32_t SPIn_BaseClock
void HAL_SCU_Peripheral_SetReset2(uint32_t u32EachPeri2)
Set/Reset Each Peripheral Block Reset of PPRST2 Register.
SPIn_EDGE_Type Edge
SPIn_SPI_ORDER_Type Order
Contains all macro definitions and function prototypes support for scu firmware library on A31L12x.
HAL_Status_Type SPIn_ConfigInterrupt(SPIn_Type *SPIx, SPIn_INT_Type SPIn_IntCfg, FunctionalState NewState)
Configure the interrupt source of selected SPIn peripheral.
uint8_t SPIn_GetStatus(SPIn_Type *SPIx)
This function returns the current value of Status Register.