Home | History | Annotate | Download | only in Txn
      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  */
    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  */
    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  ****************************************************************************/
    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  */
    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  */
    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  */
    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  ****************************************************************************/
    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  ****************************************************************************/
    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