1 
2 /******************************************************************************
3 * @brief providing APIs for configuring SPI module (SPI).
4 *
5 *******************************************************************************
6 *
7 * provide APIs for configuring SPI module (SPI).
8 ******************************************************************************/
9 #include "common.h"
10 #include "spi.h"
11 
12 
13 /******************************************************************************
14 * Local variables
15 ******************************************************************************/
16 
17 SPI_CallbackType SPI_Callback[MAX_SPI_NO] = {(SPI_CallbackType)NULL};
18 
19 
20 /******************************************************************************
21 * Local function prototypes
22 ******************************************************************************/
23 
24 /******************************************************************************
25 * Local functions
26 *****************************************************************************/
27 
28 /******************************************************************************
29 * Global functions
30 ******************************************************************************/
31 
32 /******************************************************************************
33 * define SPI APIs
34 *
35 *//*! @addtogroup spi_api_list
36 * @{
37 *******************************************************************************/
38 /*****************************************************************************//*!
39    *
40    * @brief initialize SPI as per params.
41    *
42    * @param[in]  pSPI   point to SPI module type.
43    * @param[in]  pConfig point to configuration parameters.
44    *
45    * @return none.
46    *
47    * @ Pass/ Fail criteria: none.
48    *****************************************************************************/
SPI_Init(SPI_Type * pSPI,SPI_ConfigType * pConfig)49 void SPI_Init(SPI_Type *pSPI, SPI_ConfigType *pConfig)
50 {
51 #if defined(CPU_NV32M3)
52      /* sanity check */
53     ASSERT((pSPI == SPI0));
54     SIM->SCGC |= SIM_SCGC_SPI0_MASK;
55 #else
56     /* sanity check */
57     ASSERT((pSPI == SPI0) ||  (pSPI == SPI1));
58 
59     /* enable SPI clock gating on */
60     if( pSPI == SPI0)
61     {
62         SIM->SCGC |= SIM_SCGC_SPI0_MASK;
63     }
64     else
65     {
66         SIM->SCGC |= SIM_SCGC_SPI1_MASK;
67     }
68 #endif
69     /* configure other control bits */
70     if( pConfig->sSettings.bIntEn)
71     {
72         SPI_IntEnable(pSPI);
73 #if defined(CPU_NV32M3)
74         NVIC_EnableIRQ(SPI0_IRQn);
75 #else
76         if( pSPI == SPI0 )
77         {
78 			NVIC_EnableIRQ(SPI0_IRQn);
79         }
80         else
81         {
82 			NVIC_EnableIRQ(SPI1_IRQn);
83         }
84 #endif
85     }
86 
87     if( pConfig->sSettings.bTxIntEn)
88     {
89         SPI_TxIntEnable(pSPI);
90 #if defined(CPU_NV32M3)
91         NVIC_EnableIRQ(SPI0_IRQn);
92 #else
93         if( pSPI == SPI0 )
94         {
95 			NVIC_EnableIRQ(SPI0_IRQn);
96         }
97         else
98         {
99 			NVIC_EnableIRQ(SPI1_IRQn);
100         }
101 #endif
102     }
103     if( pConfig->sSettings.bMasterMode)
104     {
105         SPI_SetMasterMode(pSPI);
106     }
107     else
108     {
109 		SPI_SetSlaveMode(pSPI);
110     }
111 
112     if( pConfig->sSettings.bClkPolarityLow)
113     {
114     	SPI_SetClockPol(pSPI,1);
115     }
116     if( pConfig->sSettings.bClkPhase1)
117     {
118         SPI_SetClockPhase(pSPI,1);
119     }else
120 	{
121      SPI_SetClockPhase(pSPI,0);
122 	}
123     if( pConfig->sSettings.bShiftLSBFirst)
124     {
125         SPI_SetLSBFirst(pSPI);
126     }
127     if( pConfig->sSettings.bMatchIntEn)
128     {
129         SPI_MatchIntEnable(pSPI);
130     }
131     if( pConfig->sSettings.bModeFaultEn)
132     {
133         SPI_ModfEnable(pSPI);
134     }
135     if( pConfig->sSettings.bMasterAutoDriveSS)
136     {
137         /* set both SSOE and MODFEN bits when auto drive slave SS is enabled */
138         SPI_SSOutputEnable(pSPI);
139         SPI_ModfEnable(pSPI);
140     }
141 
142     if( pConfig->sSettings.bPinAsOuput)
143     {
144         SPI_BidirPinEnable(pSPI);
145     }
146 
147     if( pConfig->sSettings.bBidirectionModeEn)
148     {
149         SPI_BidirOutEnable(pSPI);
150     }
151     if( pConfig->sSettings.bStopInWaitMode)
152     {
153         SPI_ClockStopEnable(pSPI);
154     }
155 
156     if(pConfig->sSettings.bMasterMode)
157     {
158         SPI_SetBaudRate(pSPI,pConfig->u32BusClkHz,pConfig->u32BitRate);
159     }
160 
161 	/* enable SPI module */
162     if( pConfig->sSettings.bModuleEn)
163     {
164         SPI_Enable(pSPI);
165     }
166 }
167 
168 /*****************************************************************************//*!
169    *
170    * @brief SPI set band rate.
171    *
172    * @param[in]  pSPI   point to SPI module type.
173    * @param[in]  u32BusClock   Bus clock.
174    * @param[in]  u32Bps   set spi's baudrate.
175    *
176    * @return  none.
177    *
178    * @ Pass/ Fail criteria: none.
179    *****************************************************************************/
SPI_SetBaudRate(SPI_Type * pSPI,uint32_t u32BusClock,uint32_t u32Bps)180 void SPI_SetBaudRate(SPI_Type *pSPI,uint32_t u32BusClock,uint32_t u32Bps)
181 {
182 	uint32_t u32BitRateDivisor;
183 	uint8_t u8Sppr;
184 	uint8_t u8Spr;
185     uint8_t u8ReadFlag;
186 	u32BitRateDivisor = u32BusClock/u32Bps; /* calculate bit rate divisor */
187 
188     u8ReadFlag = 0;
189     /* find best fit SPPR and SPR */
190     for (u8Spr = 0; u8Spr <= 8; u8Spr++)
191     {
192         for(u8Sppr = 0; u8Sppr <= 7; u8Sppr++)
193         {
194             if((u32BitRateDivisor>>(u8Spr+1))<=(u8Sppr+1))
195             {
196                 u8ReadFlag = 1;
197                 break;
198             }
199         }
200         if(u8ReadFlag)
201         {
202             break;
203         }
204     }
205     if(u8Sppr >=8)
206     {
207         u8Sppr = 7;
208     }
209     if(u8Spr >8)
210     {
211         u8Spr = 8;
212     }
213     /* set bit rate */
214     pSPI->BR = SPI_BR_SPPR(u8Sppr) | SPI_BR_SPR(u8Spr);
215 }
216 
217 /*****************************************************************************//*!
218    *
219    * @brief implement write data to SPI.
220    *
221    * @param[in]   pSPI  pointer to SPI module type.
222    * @param[in]   pWrBuff -- write data buffer pointer.
223    * @param[in]   uiLength -- read/write data length.
224    * @param[out]   pRdBuff -- read data buffer pointer.
225    *
226    * @return  if <0, means error, 0: success.
227    *
228    * @ Pass/ Fail criteria: none.
229    *****************************************************************************/
SPI_TransferWait(SPI_Type * pSPI,SPI_WidthType * pRdBuff,SPI_WidthType * pWrBuff,uint32 uiLength)230 ResultType SPI_TransferWait(SPI_Type *pSPI, SPI_WidthType* pRdBuff, SPI_WidthType *pWrBuff,uint32 uiLength)
231 {
232     ResultType err = SPI_ERR_SUCCESS;
233     uint32_t  i;
234 
235     if(!uiLength)
236     {
237         return (err);
238     }
239     for(i = 0; i < uiLength; i++)
240     {
241         while(!SPI_IsSPTEF(pSPI));
242         SPI_WriteDataReg(pSPI,pWrBuff[i]);
243         while(!SPI_IsSPRF(pSPI));
244         pRdBuff[i] = SPI_ReadDataReg(pSPI);
245     }
246     return (err);
247 }
248 
249 
250 
251 /*****************************************************************************//*!
252    *
253    * @brief Deinitialize SPI to the default state (reset value).
254    *
255    * @param[in]   pSPI  pointer to SPI module type.
256    *
257    * @return none.
258    *
259    * @ Pass/ Fail criteria: none.
260    *****************************************************************************/
SPI_DeInit(SPI_Type * pSPI)261 void SPI_DeInit(SPI_Type *pSPI)
262 {
263     int16 i;
264     pSPI->C1 = SPI_C1_DEFAULT;
265     pSPI->C2 = SPI_C2_DEFAULT;
266     pSPI->BR = SPI_BR_DEFAULT;
267     pSPI->M  = SPI_M_DEFAULT;
268     for(i = 0; i<100; i++);                 /* wait for some cycles for the ISR exit */
269 }
270 
271 /*****************************************************************************//*!
272    *
273    * @brief  set up SPI callback routines to be called by interrupt service routine.
274    *
275    * @param[in]   pSPI  pointer to SPI module type.
276    * @param[in]  pfnCallback  callback routine.
277    *
278    * @return none.
279    *
280    * @ Pass/ Fail criteria: none.
281 *****************************************************************************/
SPI_SetCallback(SPI_Type * pSPI,SPI_CallbackType pfnCallback)282 void SPI_SetCallback(SPI_Type *pSPI,SPI_CallbackType pfnCallback)
283 {
284     uint32_t    u32Port = ((uint32_t)pSPI-(uint32_t)SPI0)>>12;
285     ASSERT(u32Port <2);
286     SPI_Callback[u32Port] = pfnCallback;
287 }
288 
289 /*! @} End of spi_api_list                                               						*/
290 
291 
292 /*****************************************************************************//*!
293    *
294    * @brief SPI0 interrupt service routine.
295    *
296    * @param   none.
297    * @return  none.
298    *
299    * @ Pass/ Fail criteria: none.
300    *****************************************************************************/
301 
SPI0_Isr(void)302 void SPI0_Isr(void)
303 {
304     if( SPI_Callback[0] )
305     {
306 		SPI_Callback[0]();
307     }
308 }
309 #ifndef CPU_NV32M3
310 /*****************************************************************************//*!
311    *
312    * @brief SPI1 interrupt service routine.
313    *
314    * @param   none.
315    * @return  none.
316    *
317    * @ Pass/ Fail criteria: none
318    *****************************************************************************/
319 
SPI1_Isr(void)320 void SPI1_Isr(void)
321 {
322     if( SPI_Callback[1] )
323     {
324 		SPI_Callback[1]();
325     }
326 }
327 #endif
328 
329 
330