• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * WspiBusDrv.c
3  *
4  * Copyright(c) 1998 - 2009 Texas Instruments. All rights reserved.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  *  * Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  *  * Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in
15  *    the documentation and/or other materials provided with the
16  *    distribution.
17  *  * Neither the name Texas Instruments nor the names of its
18  *    contributors may be used to endorse or promote products derived
19  *    from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 
35 /** \file   WspiBusDrv.c
36  *  \brief  The WSPI bus driver upper layer. Platform independent.
37  *          Uses the SpiAdapter API.
38  *          Introduces a generic bus-independent API upwards.
39  *
40  *  \see    BusDrv.h, SpiAdapter.h, SpiAdapter.c
41  */
42 
43 #include "tidef.h"
44 #include "report.h"
45 #include "osApi.h"
46 #include "wspi.h"
47 #include "BusDrv.h"
48 #include "TxnDefs.h"
49 #define __FILE_ID__		FILE_ID_124
50 
51 /************************************************************************
52  * Defines
53  ************************************************************************/
54 #define WSPI_FIXED_BUSY_LEN     1
55 #define WSPI_INIT_CMD_MASK      0
56 
57 
58 /************************************************************************
59  * Types
60  ************************************************************************/
61 
62 /* The busDrv module Object */
63 typedef struct _TBusDrvObj
64 {
65     TI_HANDLE	    hOs;
66     TI_HANDLE	    hReport;
67 	TI_HANDLE	    hDriver;
68 	TI_HANDLE	    hWspi;
69 
70 	TTxnDoneCb      fTxnDoneCb;         /* The callback to call upon full transaction completion. */
71 	TI_HANDLE       hCbHandle;          /* The callback handle */
72     TTxnStruct *    pCurrTxn;           /* The transaction currently being processed */
73     TI_STATUS       eCurrTxnStatus;     /* COMPLETE, PENDING or ERROR */
74     TI_UINT32       uCurrTxnBufsCount;
75     TI_BOOL         bPendingByte;
76     TTxnDoneCb      fTxnConnectDoneCb;         /* The callback to call upon full transaction completion. */
77 
78 
79 } TBusDrvObj;
80 
81 
82 /************************************************************************
83  * Internal functions prototypes
84  ************************************************************************/
85 
86 static void asyncEnded_CB(TI_HANDLE hBusTxn, int status);
87 static void ConnectDone_CB(TI_HANDLE hBusDrv, int status);
88 
89 /************************************************************************
90  *
91  *   Module functions implementation
92  *
93  ************************************************************************/
94 
95 /**
96  * \fn     busDrv_Create
97  * \brief  Create the module
98  *
99  * Allocate and clear the module's object.
100  *
101  * \note
102  * \param  hOs - Handle to Os Abstraction Layer
103  * \return Handle of the allocated object, NULL if allocation failed
104  * \sa     busDrv_Destroy
105  */
busDrv_Create(TI_HANDLE hOs)106 TI_HANDLE busDrv_Create (TI_HANDLE hOs)
107 {
108     TI_HANDLE   hBusDrv;
109     TBusDrvObj *pBusDrv;
110 
111     hBusDrv = os_memoryAlloc(hOs, sizeof(TBusDrvObj));
112     if (hBusDrv == NULL)
113         return NULL;
114 
115     pBusDrv = (TBusDrvObj *)hBusDrv;
116 
117     os_memoryZero(hOs, hBusDrv, sizeof(TBusDrvObj));
118 
119     pBusDrv->hOs = hOs;
120 
121     // addapt to WSPI
122 
123     pBusDrv->hWspi= WSPI_Open(hOs);
124 
125     return pBusDrv;
126 }
127 
128 
129 /**
130  * \fn     busDrv_Destroy
131  * \brief  Destroy the module.
132  *
133  * Close SPI lower bus driver and free the module's object.
134  *
135  * \note
136  * \param  The module's object
137  * \return TI_OK on success or TI_NOK on failure
138  * \sa     busDrv_Create
139  */
busDrv_Destroy(TI_HANDLE hBusDrv)140 TI_STATUS busDrv_Destroy (TI_HANDLE hBusDrv)
141 {
142     TBusDrvObj *pBusDrv = (TBusDrvObj*)hBusDrv;
143 
144     if (pBusDrv)
145     {
146         // addapt to WSPI
147         WSPI_Close(pBusDrv->hWspi);
148         os_memoryFree (pBusDrv->hOs, pBusDrv, sizeof(TBusDrvObj));
149     }
150     return TI_OK;
151 }
152 
153 
154 /****************************************************************************
155  *                      busDrv_Init
156  ****************************************************************************
157  * DESCRIPTION: config the module.
158  *
159  * INPUTS:  hBusDrv - handle to the module context
160  *          hReport - handle to report module context that is used when we output debug messages
161  *          CBFunc  - The callback to call upon transaction complete (calls the tasklet).
162  *          CBArg   - The handle for the CBFunc.
163  *
164  * OUTPUT:  none.
165  *
166  * RETURNS: one of the error codes (0 => TI_OK)
167  ****************************************************************************/
busDrv_Init(TI_HANDLE hBusDrv,TI_HANDLE hReport)168 void busDrv_Init (TI_HANDLE    hBusDrv,
169                        TI_HANDLE    hReport)
170 {
171     TBusDrvObj *pBusDrv = (TBusDrvObj*) hBusDrv;
172 
173 
174 
175     pBusDrv->hReport    = hReport;
176 
177 
178 
179 }
180 
181 
182 
183 
184 
185 
186 /**
187  * \fn     busDrv_ConnectBus
188  * \brief  Configure bus driver
189  *
190  * Called by TxnQ.
191  * Configure the bus driver with its connection configuration (such as baud-rate, bus width etc)
192  *     and establish the physical connection.
193  * Done once upon init (and not per functional driver startup).
194  *
195  * \note
196  * \param  hBusDrv    - The module's object
197  * \param  pBusDrvCfg - A union used for per-bus specific configuration.
198  * \param  fCbFunc    - CB function for Async transaction completion (after all txn parts are completed).
199  * \param  hCbArg     - The CB function handle
200  * \return TI_OK / TI_NOK
201  * \sa
202  */
busDrv_ConnectBus(TI_HANDLE hBusDrv,TBusDrvCfg * pBusDrvCfg,TBusDrvTxnDoneCb fCbFunc,TI_HANDLE hCbArg,TBusDrvTxnDoneCb fConnectCbFunc)203 TI_STATUS busDrv_ConnectBus (TI_HANDLE        hBusDrv,
204                              TBusDrvCfg       *pBusDrvCfg,
205                              TBusDrvTxnDoneCb fCbFunc,
206                              TI_HANDLE        hCbArg,
207                              TBusDrvTxnDoneCb fConnectCbFunc
208                              )
209 {
210     TBusDrvObj *pBusDrv = (TBusDrvObj*)hBusDrv;
211     int         iStatus;
212     WSPIConfig_t wspi_config;
213     WSPI_CB_T cb;
214 
215     /* Save the parameters (TxnQ callback for TxnDone events) */
216     pBusDrv->fTxnDoneCb    = fCbFunc;
217     pBusDrv->hCbHandle     = hCbArg;
218     pBusDrv->fTxnConnectDoneCb = fConnectCbFunc;
219 
220     /* Configure the WSPI driver parameters  */
221 
222     wspi_config.isFixedAddress = TI_FALSE;
223     wspi_config.fixedBusyLength = WSPI_FIXED_BUSY_LEN;
224     wspi_config.mask = WSPI_INIT_CMD_MASK;
225 
226     cb.CBFunc = ConnectDone_CB;/* The BusTxn callback called upon Async transaction end. */
227     cb.CBArg  = hBusDrv;   /* The handle for the BusDrv. */
228 
229     /* Configure the WSPI module */
230     iStatus = WSPI_Configure(pBusDrv->hWspi, pBusDrv->hReport, &wspi_config, &cb);
231 
232 
233     if ((iStatus == 0) || (iStatus == 1))
234     {
235         TRACE1 (pBusDrv->hReport, REPORT_SEVERITY_INIT, "busDrv_ConnectBus: called Status %d\n",iStatus);
236 
237 
238         TRACE2 (pBusDrv->hReport, REPORT_SEVERITY_INFORMATION, "busDrv_ConnectBus: Successful Status %d\n",iStatus);
239         return TI_OK;
240     }
241     else
242     {
243         TRACE2(pBusDrv->hReport, REPORT_SEVERITY_ERROR, "busDrv_ConnectBus: Status = %d,\n", iStatus);
244         return TI_NOK;
245     }
246 }
247 /**
248  * \fn     busDrv_DisconnectBus
249  * \brief  Disconnect SDIO driver
250  *
251  * Called by TxnQ. Disconnect the SDIO driver.
252  *
253  * \note
254  * \param  hBusDrv - The module's object
255  * \return TI_OK / TI_NOK
256  * \sa
257  */
busDrv_DisconnectBus(TI_HANDLE hBusDrv)258 TI_STATUS   busDrv_DisconnectBus   (TI_HANDLE hBusDrv)
259 {
260     return TI_OK;
261 }
262 
263 
264 /**
265  * \fn     busDrv_Transact
266  * \brief  Process transaction
267  *
268  * Called by the TxnQ module to initiate a new transaction.
269  * Call either write or read functions according to Txn direction field.
270  *
271  * \note   It's assumed that this function is called only when idle (i.e. previous Txn is done).
272  * \param  hBusDrv - The module's object
273  * \param  pTxn    - The transaction object
274  * \return COMPLETE if Txn completed in this context, PENDING if not, ERROR if failed
275  * \sa     busDrv_PrepareTxnParts, busDrv_SendTxnParts
276  */
busDrv_Transact(TI_HANDLE hBusDrv,TTxnStruct * pTxn)277 ETxnStatus busDrv_Transact (TI_HANDLE hBusDrv, TTxnStruct *pTxn)
278 {
279     TBusDrvObj *pBusDrv = (TBusDrvObj*)hBusDrv;
280     WSPI_CB_T cb;
281     TI_UINT8 * tempReadBuff;
282     TI_UINT8 * tempWriteBuff;
283     pBusDrv->pCurrTxn       = pTxn;
284     pBusDrv->eCurrTxnStatus = TXN_STATUS_COMPLETE;  /* The Txn is Sync as long as it continues in this context */
285     cb.CBFunc = asyncEnded_CB;  /* The BusTxn callback called upon Async transaction end. */
286     cb.CBArg  = hBusDrv;   /* The handle for the BusTxnCB. */
287 
288     /* If write command */
289     if (TXN_PARAM_GET_DIRECTION(pTxn) == TXN_DIRECTION_WRITE)
290     {
291 
292         //WLAN_REPORT_INIT(pBusDrv->hReport, TNETW_DRV_MODULE_LOG,
293         //    ("busDrv_Transact:  Write to pTxn->uHwAddr %x\n", pTxn->uHwAddr ));
294 
295 
296          /*WLAN_REPORT_ERROR(pBusDrv->hReport, BUS_DRV_MODULE_LOG,
297             ("busDrv_Transact: Buff= %x, Len=%d\n", pTxn->aBuf[0], pTxn->aLen[0]));*/
298         /*1.write memory*/
299           /* Decrease the data pointer to the beginning of the WSPI padding */
300           tempWriteBuff = pTxn->aBuf[0];
301           tempWriteBuff -= WSPI_PAD_LEN_WRITE;
302 
303           /* Write the data to the WSPI in Aync mode (not completed in the current context). */
304           pBusDrv->eCurrTxnStatus = WSPI_WriteAsync(pBusDrv->hWspi, pTxn->uHwAddr,tempWriteBuff,pTxn->aLen[0], &cb, TI_TRUE, TI_TRUE,TXN_PARAM_GET_FIXED_ADDR(pTxn));
305 
306     }
307 
308     /* If read command */
309     else
310     {
311         //WLAN_REPORT_INIT(pBusDrv->hReport, TNETW_DRV_MODULE_LOG,
312         //    ("busDrv_Transact:  Read from pTxn->uHwAddr %x pTxn %x \n", pTxn->uHwAddr,pTxn));
313 
314         /*1. Read mem */
315          /* Decrease the tempReadBuff pointer to the beginning of the WSPI padding */
316         tempReadBuff = pTxn->aBuf[0];
317         tempReadBuff -= WSPI_PAD_LEN_READ;
318         /* Read the required data from the WSPI in Aync mode (not completed in the current context). */
319         pBusDrv->eCurrTxnStatus  = WSPI_ReadAsync(pBusDrv->hWspi, pTxn->uHwAddr,tempReadBuff,pTxn->aLen[0], &cb, TI_TRUE, TI_TRUE,TXN_PARAM_GET_FIXED_ADDR(pTxn));
320 
321 
322     }
323 
324     /* return transaction status - COMPLETE, PENDING or ERROR */
325     return (pBusDrv->eCurrTxnStatus == WSPI_TXN_COMPLETE ? TXN_STATUS_COMPLETE :
326 			(pBusDrv->eCurrTxnStatus == WSPI_TXN_PENDING ? TXN_STATUS_PENDING : TXN_STATUS_ERROR));
327 
328 
329 }
330 
331 
332 /****************************************************************************
333  *                      asyncEnded_CB()
334  ****************************************************************************
335  * DESCRIPTION:
336  *      Called back by the WSPI driver from Async transaction end interrupt (ISR context).
337  *      Calls the upper layers callback.
338  *
339  * INPUTS:  status -
340  *
341  * OUTPUT:  None
342  *
343  * RETURNS: None
344  ****************************************************************************/
asyncEnded_CB(TI_HANDLE hBusDrv,int status)345 static void asyncEnded_CB(TI_HANDLE hBusDrv, int status)
346 {
347     TBusDrvObj *pBusDrv = (TBusDrvObj*)hBusDrv;
348     /* If the last transaction failed, call failure CB and exit. */
349     if (status != 0)
350     {
351         TRACE2(pBusDrv->hReport, REPORT_SEVERITY_ERROR, "asyncEnded_CB : Status = %d, fTxnDoneCb = 0x%x\n", status,pBusDrv->fTxnDoneCb);
352 
353         TXN_PARAM_SET_STATUS(pBusDrv->pCurrTxn, TXN_PARAM_STATUS_ERROR);
354     }
355 	else
356 	{
357 		TRACE2(pBusDrv->hReport, REPORT_SEVERITY_INFORMATION,"asyncEnded_CB: Successful async cb done pBusDrv->pCurrTxn %x\n", pBusDrv->pCurrTxn);
358 	}
359 
360     /* Call the upper layer CB */
361 
362     pBusDrv->fTxnDoneCb(pBusDrv->hCbHandle,pBusDrv->pCurrTxn);
363 }
364 
365 
366 /****************************************************************************
367  *                      ConnectDone_CB()
368  ****************************************************************************
369  * DESCRIPTION:
370  *      Called back by the WSPI driver from Async transaction end interrupt (ISR context).
371  *      Calls the upper layers callback.
372  *
373  * INPUTS:  status -
374  *
375  * OUTPUT:  None
376  *
377  * RETURNS: None
378  ****************************************************************************/
ConnectDone_CB(TI_HANDLE hBusDrv,int status)379 static void ConnectDone_CB(TI_HANDLE hBusDrv, int status)
380 {
381     TBusDrvObj *pBusDrv = (TBusDrvObj*)hBusDrv;
382     /* If the last transaction failed, call failure CB and exit. */
383     if (status != 0)
384     {
385         TRACE2(pBusDrv->hReport, REPORT_SEVERITY_ERROR, "ConnectDone_CB : Status = %d, fTxnConnectDoneCb = 0x%x\n", status,pBusDrv->fTxnConnectDoneCb);
386 
387         TXN_PARAM_SET_STATUS(pBusDrv->pCurrTxn, TXN_PARAM_STATUS_ERROR);
388     }
389 	else
390 	{
391 		TRACE1 (pBusDrv->hReport, REPORT_SEVERITY_INIT, "ConnectDone_CB: Successful Connect Async cb done \n");
392 	}
393 
394     /* Call the upper layer CB */
395 
396     pBusDrv->fTxnConnectDoneCb(pBusDrv->hCbHandle,pBusDrv->pCurrTxn);
397 }
398 
399 
400