Statistics
| Branch: | Tag: | Revision:

mongoose / examples / PIC32 / mqtt_client / firmware / src / system_config / mx795_CC3100_e16 / framework / driver / spi / static / src / drv_spi_static.c @ eaef5bd1

History | View | Annotate | Download (14.9 KB)

1
/* clang-format off */
2
/*******************************************************************************
3
  SPI Driver Static implementation
4

5
  Company:
6
    Microchip Technology Inc.
7

8
  File Name:
9
    drv_spi_static.c
10

11
  Summary:
12
    Source code for the SPI driver static implementation.
13

14
  Description:
15
    The SPI device driver provides a simple interface to manage the SPI
16
    modules on Microchip microcontrollers. This file contains static implementation
17
    for the SPI driver.
18

19
  Remarks:
20
    Static interfaces incorporate the driver instance number within the names
21
    of the routines, eliminating the need for an object ID or object handle.
22

23
    Static single-open interfaces also eliminate the need for the open handle.
24
*******************************************************************************/
25

    
26
//DOM-IGNORE-BEGIN
27
/*******************************************************************************
28
Copyright (c) 2015 released Microchip Technology Inc.  All rights reserved.
29

30
Microchip licenses to you the right to use, modify, copy and distribute
31
Software only when embedded on a Microchip microcontroller or digital signal
32
controller that is integrated into your product or third party product
33
(pursuant to the sublicense terms in the accompanying license agreement).
34

35
You should refer to the license agreement accompanying this Software for
36
additional information regarding your rights and obligations.
37

38
SOFTWARE AND DOCUMENTATION ARE PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND,
39
EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF
40
MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE.
41
IN NO EVENT SHALL MICROCHIP OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER
42
CONTRACT, NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR
43
OTHER LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES
44
INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR
45
CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT OF
46
SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES
47
(INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
48
*******************************************************************************/
49
//DOM-IGNORE-END
50

    
51
// *****************************************************************************
52
// *****************************************************************************
53
// Section: Included Files
54
// *****************************************************************************
55
// *****************************************************************************
56

    
57
#include <string.h>
58
#include "system_config.h"
59
#include "system_definitions.h"
60

    
61
// *****************************************************************************
62
// *****************************************************************************
63
// Section: Global Data
64
// *****************************************************************************
65
// *****************************************************************************
66
static uint8_t sDrvSPIQueueArea[DRV_SPI_SYS_QUEUE_BUFFER_SIZE(DRV_SPI_INSTANCES_NUMBER, sizeof(DRV_SPI_JOB_OBJECT), DRV_SPI_INSTANCES_NUMBER * DRV_SPI_ELEMENTS_PER_QUEUE)];
67

    
68
/* This is the Queue manager object . */
69
static DRV_SPI_SYS_QUEUE_MANAGER_SETUP qmInitData = {
70
    sDrvSPIQueueArea,
71
    sizeof(sDrvSPIQueueArea),
72
    DRV_SPI_INSTANCES_NUMBER,
73
    sizeof(DRV_SPI_JOB_OBJECT),
74
    DRV_SPI_SYS_QUEUE_Fifo,
75
};
76

    
77
/* This is the Queue setup object . */
78
static DRV_SPI_SYS_QUEUE_SETUP qInitData =
79
{
80
    0,
81
    10,
82
    0,
83
};
84

    
85
/* This is the Queue Manager handle*/
86
DRV_SPI_SYS_QUEUE_MANAGER_HANDLE  hQueueManager;
87

    
88

    
89
// *****************************************************************************
90
// *****************************************************************************
91
// Section: Instance 0 static driver functions
92
// *****************************************************************************
93
// *****************************************************************************
94
/* This is the driver static object . */
95
DRV_SPI_OBJ  gDrvSPI0Obj ;
96

    
97
SYS_MODULE_OBJ DRV_SPI0_Initialize(void)
98
{
99
    DRV_SPI_OBJ *dObj = (DRV_SPI_OBJ*)NULL;
100

    
101
    dObj = &gDrvSPI0Obj;
102

    
103
    /* Disable the SPI module to configure it*/
104
    PLIB_SPI_Disable ( SPI_ID_1 );
105

    
106
    /* Set up Master or Slave Mode*/
107
    PLIB_SPI_MasterEnable ( SPI_ID_1 );
108
    PLIB_SPI_PinDisable(SPI_ID_1, SPI_PIN_SLAVE_SELECT);
109

    
110
    /* Set up if the SPI is allowed to run while the rest of the CPU is in idle mode*/
111
    PLIB_SPI_StopInIdleEnable( SPI_ID_1 );
112

    
113
    /* Set up clock Polarity and output data phase*/
114
    PLIB_SPI_ClockPolaritySelect( SPI_ID_1, SPI_CLOCK_POLARITY_IDLE_LOW );
115
    PLIB_SPI_OutputDataPhaseSelect( SPI_ID_1, SPI_OUTPUT_DATA_PHASE_ON_IDLE_TO_ACTIVE_CLOCK );
116

    
117
    /* Set up the Input Sample Phase*/
118
    PLIB_SPI_InputSamplePhaseSelect ( SPI_ID_1, SPI_INPUT_SAMPLING_PHASE_IN_MIDDLE);
119

    
120
    /* Communication Width Selection */
121
    PLIB_SPI_CommunicationWidthSelect ( SPI_ID_1, SPI_COMMUNICATION_WIDTH_8BITS );
122

    
123
    /* Baud rate selection */
124
    PLIB_SPI_BaudRateSet( SPI_ID_1 , SYS_CLK_PeripheralFrequencyGet(CLK_BUS_PERIPHERAL_2), 10000000 );
125

    
126
    /* Protocol selection */
127
    PLIB_SPI_FramedCommunicationDisable( SPI_ID_1  );
128
    #if defined (PLIB_SPI_ExistsAudioProtocolControl)
129
            if (PLIB_SPI_ExistsAudioProtocolControl(SPI_ID_1))
130
            {
131
                PLIB_SPI_AudioProtocolDisable(SPI_ID_1);
132
            }
133
    #endif
134

    
135
    /* Buffer type selection */
136
    #if defined (PLIB_SPI_ExistsFIFOControl)
137
        if (PLIB_SPI_ExistsFIFOControl( SPI_ID_1 ))
138
        {
139
            PLIB_SPI_FIFODisable( SPI_ID_1 );
140
        }
141
    #endif
142

    
143
    PLIB_SPI_BufferClear( SPI_ID_1 );
144
    PLIB_SPI_ReceiverOverflowClear ( SPI_ID_1 );
145

    
146
    /* Initialize Queue only once for all instances of SPI driver*/
147
    if (DRV_SPI_SYS_QUEUE_Initialize(&qmInitData, &hQueueManager) != DRV_SPI_SYS_QUEUE_SUCCESS)
148
    {
149
        SYS_ASSERT(false, "\r\nSPI Driver: Could not create queuing system.");
150
        return SYS_MODULE_OBJ_INVALID;
151
    }
152

    
153
    /* Update the Queue parameters. */
154
    qInitData.maxElements = 10; //Queue size
155
    qInitData.reserveElements = 1; //Mininmum number of job queues reserved
156

    
157
    /* Create Queue for this instance of SPI */
158
    if (DRV_SPI_SYS_QUEUE_CreateQueue(hQueueManager, &qInitData, &dObj->queue) != DRV_SPI_SYS_QUEUE_SUCCESS)
159
    {
160
        SYS_ASSERT(false, "\r\nSPI Driver: Could not set up driver instance queue.");
161
        return SYS_MODULE_OBJ_INVALID;
162

    
163
    }
164

    
165
    /* Update the SPI OBJECT parameters. */
166
    dObj->operationStarting = NULL;
167
    dObj->operationEnded = NULL;
168
    dObj->numTrfsSmPolled = 16;
169

    
170
    /* Enable the Module */
171
    PLIB_SPI_Enable(SPI_ID_1);
172

    
173
    return (SYS_MODULE_OBJ)DRV_SPI_INDEX_0 ;
174
}
175

    
176
void DRV_SPI0_Deinitialize ( void )
177
{
178
    /* Disable the SPI Module */
179
    PLIB_SPI_Disable(SPI_ID_1);
180

    
181
    return;
182
}
183

    
184
SYS_STATUS DRV_SPI0_Status ( void )
185
{
186
    /* Return the current status of driver instance */
187
    return SYS_STATUS_READY;
188
}
189

    
190
void DRV_SPI0_Tasks ( void )
191
{
192
    /* Call the respective task routine */
193
    DRV_SPI0_PolledMasterRM8BitTasks(&gDrvSPI0Obj);
194
}
195

    
196
DRV_HANDLE DRV_SPI0_Open ( const SYS_MODULE_INDEX index, const DRV_IO_INTENT intent )
197
{
198
    return (DRV_HANDLE)DRV_SPI_INDEX_0;
199
}
200

    
201
void DRV_SPI0_Close ( void )
202
{
203
    return;
204
}
205

    
206
int32_t DRV_SPI0_ClientConfigure ( const DRV_SPI_CLIENT_DATA * cfgData  )
207
{
208
    DRV_SPI_OBJ *dObj = (DRV_SPI_OBJ*)NULL;
209

    
210
    dObj = &gDrvSPI0Obj;
211

    
212
    if (cfgData == NULL)
213
    {
214
        /* Nothing to do */
215
        return 0;
216
    }
217

    
218
    if (cfgData->operationStarting != NULL)
219
    {
220
        dObj->operationStarting = cfgData->operationStarting;
221
    }
222

    
223
    if (cfgData->operationEnded != NULL)
224
    {
225
        dObj->operationEnded = cfgData->operationEnded;
226
    }
227

    
228
    if (cfgData->baudRate != 0)
229
    {
230

    
231
        PLIB_SPI_BaudRateSet (SPI_ID_1,
232
                              SYS_CLK_PeripheralFrequencyGet(CLK_BUS_PERIPHERAL_2),
233
                              cfgData->baudRate);
234
    }
235

    
236
    return 0;
237
}
238

    
239
DRV_SPI_BUFFER_HANDLE DRV_SPI0_BufferAddRead2 ( void *rxBuffer, size_t size, DRV_SPI_BUFFER_EVENT_HANDLER completeCB, void * context, DRV_SPI_BUFFER_HANDLE * jobHandle)
240
{
241
    DRV_SPI_OBJ *dObj = (DRV_SPI_OBJ*)NULL;
242

    
243
    dObj = &gDrvSPI0Obj;
244

    
245
    DRV_SPI_JOB_OBJECT * pJob = NULL;
246

    
247
    if (DRV_SPI_SYS_QUEUE_AllocElementLock(dObj->queue, (void **)&pJob) != DRV_SPI_SYS_QUEUE_SUCCESS)
248
    {
249
        SYS_ASSERT(false, "\r\nSPI Driver: Error trying to get a free entry.");
250
        return (DRV_SPI_BUFFER_HANDLE)NULL;
251
    }
252

    
253
    memset(pJob, 0, sizeof(DRV_SPI_JOB_OBJECT));
254

    
255
    pJob->rxBuffer = rxBuffer;
256
    pJob->dataLeftToRx = size;
257
    pJob->dummyLeftToTx = size;
258
    pJob->completeCB = completeCB;
259
    pJob->context = context;
260
    pJob->status = DRV_SPI_BUFFER_EVENT_PENDING;
261

    
262
    if (jobHandle != NULL )
263
    {
264
        *jobHandle = (DRV_SPI_BUFFER_HANDLE)pJob;
265
    }
266

    
267
    if (DRV_SPI_SYS_QUEUE_EnqueueLock(dObj->queue, (void*)pJob) != DRV_SPI_SYS_QUEUE_SUCCESS)
268
    {
269
        SYS_ASSERT(false, "\r\nSPI Driver: Error enqueing new job.");
270
        return (DRV_SPI_BUFFER_HANDLE)NULL;
271
    }
272

    
273
    return (DRV_SPI_BUFFER_HANDLE)pJob;
274
}
275

    
276

    
277
DRV_SPI_BUFFER_HANDLE DRV_SPI0_BufferAddWrite2 ( void *txBuffer, size_t size, DRV_SPI_BUFFER_EVENT_HANDLER completeCB, void * context, DRV_SPI_BUFFER_HANDLE * jobHandle )
278
{
279
    DRV_SPI_OBJ *dObj = (DRV_SPI_OBJ*)NULL;
280

    
281
    dObj = &gDrvSPI0Obj;
282

    
283
    DRV_SPI_JOB_OBJECT * pJob = NULL;
284
    if (DRV_SPI_SYS_QUEUE_AllocElementLock(dObj->queue, (void **)&pJob) != DRV_SPI_SYS_QUEUE_SUCCESS)
285
    {
286
        SYS_ASSERT(false, "\r\nSPI Driver: Error trying to get a free entry.");
287
        return (DRV_SPI_BUFFER_HANDLE)NULL;
288
    }
289

    
290
    memset(pJob, 0, sizeof(DRV_SPI_JOB_OBJECT));
291
    pJob->txBuffer = txBuffer;
292
    pJob->dataLeftToTx = size;
293
    pJob->dummyLeftToRx = size;
294
    pJob->completeCB = completeCB;
295
    pJob->context = context;
296
    pJob->status = DRV_SPI_BUFFER_EVENT_PENDING;
297

    
298
    if (jobHandle != NULL )
299
    {
300
        *jobHandle = (DRV_SPI_BUFFER_HANDLE)pJob;
301
    }
302

    
303
    if (DRV_SPI_SYS_QUEUE_EnqueueLock(dObj->queue, (void*)pJob) != DRV_SPI_SYS_QUEUE_SUCCESS)
304
    {
305
        SYS_ASSERT(false, "\r\nSPI Driver: Error enqueing new job.");
306
        return (DRV_SPI_BUFFER_HANDLE)NULL;
307
    }
308

    
309
    return (DRV_SPI_BUFFER_HANDLE)pJob;
310
}
311

    
312

    
313
DRV_SPI_BUFFER_HANDLE DRV_SPI0_BufferAddWriteRead2 ( void *txBuffer, size_t txSize, void *rxBuffer, size_t rxSize, DRV_SPI_BUFFER_EVENT_HANDLER completeCB, void * context, DRV_SPI_BUFFER_HANDLE * jobHandle )
314
{
315
    DRV_SPI_OBJ *dObj = (DRV_SPI_OBJ*)NULL;
316

    
317
    dObj = &gDrvSPI0Obj;
318

    
319
    DRV_SPI_JOB_OBJECT * pJob = NULL;
320
    if (DRV_SPI_SYS_QUEUE_AllocElementLock(dObj->queue, (void **)&pJob) != DRV_SPI_SYS_QUEUE_SUCCESS)
321
    {
322
        SYS_ASSERT(false, "\r\nSPI Driver: Error trying to get a free entry.");
323
        return (DRV_SPI_BUFFER_HANDLE)NULL;
324
    }
325

    
326
    memset(pJob, 0, sizeof(DRV_SPI_JOB_OBJECT));
327
    pJob->txBuffer = txBuffer;
328
    pJob->dataLeftToTx = txSize;
329
    pJob->rxBuffer = rxBuffer;
330
    pJob->dataLeftToRx = rxSize;
331

    
332
    if (jobHandle != NULL )
333
    {
334
        *jobHandle = (DRV_SPI_BUFFER_HANDLE)pJob;
335
    }
336
    if (rxSize > txSize)
337
    {
338
        pJob->dummyLeftToTx = rxSize - txSize;
339
    }
340
    if (txSize > rxSize)
341
    {
342
        pJob->dummyLeftToRx = txSize - rxSize;
343
    }
344
    pJob->completeCB = completeCB;
345
    pJob->context = context;
346
    pJob->status = DRV_SPI_BUFFER_EVENT_PENDING;
347

    
348
    if (DRV_SPI_SYS_QUEUE_EnqueueLock(dObj->queue, (void*)pJob) != DRV_SPI_SYS_QUEUE_SUCCESS)
349
    {
350
        SYS_ASSERT(false, "\r\nSPI Driver: Error enqueing new job.");
351
        return (DRV_SPI_BUFFER_HANDLE)NULL;
352
    }
353

    
354
    return (DRV_SPI_BUFFER_HANDLE)pJob;
355
}
356

    
357

    
358
DRV_SPI_BUFFER_HANDLE DRV_SPI0_BufferAddRead ( void *rxBuffer, size_t size, DRV_SPI_BUFFER_EVENT_HANDLER completeCB, void * context)
359
{
360
    return DRV_SPI0_BufferAddRead2(rxBuffer, size, completeCB, context, NULL);
361
}
362

    
363
DRV_SPI_BUFFER_HANDLE DRV_SPI0_BufferAddWrite ( void *txBuffer, size_t size, DRV_SPI_BUFFER_EVENT_HANDLER completeCB, void * context )
364
{
365
    return DRV_SPI0_BufferAddWrite2(txBuffer, size, completeCB, context, NULL);
366
}
367

    
368
DRV_SPI_BUFFER_EVENT DRV_SPI0_BufferStatus ( DRV_SPI_BUFFER_HANDLE bufferHandle )
369
{
370
    DRV_SPI_JOB_OBJECT * pJob = (DRV_SPI_JOB_OBJECT *)bufferHandle;
371

    
372
    return pJob->status;
373
}
374

    
375

    
376
int32_t DRV_SPI0_PolledErrorTasks(struct DRV_SPI_OBJ * dObj)
377
{
378

    
379
    if (dObj->currentJob == NULL)
380
    {
381
        return 0;
382
    }
383

    
384
    register DRV_SPI_JOB_OBJECT * currentJob = dObj->currentJob;
385

    
386
    if (PLIB_SPI_ReceiverHasOverflowed(SPI_ID_1))
387
    {
388
        currentJob->status = DRV_SPI_BUFFER_EVENT_ERROR;
389
        if (currentJob->completeCB != NULL)
390
        {
391
            (*currentJob->completeCB)(DRV_SPI_BUFFER_EVENT_ERROR, (DRV_SPI_BUFFER_HANDLE)currentJob, currentJob->context);
392
        }
393
        if (dObj->operationEnded != NULL)
394
        {
395
            (*dObj->operationEnded)(DRV_SPI_BUFFER_EVENT_ERROR, (DRV_SPI_BUFFER_HANDLE)currentJob, currentJob->context);
396
        }
397
        if (DRV_SPI_SYS_QUEUE_FreeElementLock(dObj->queue, currentJob) != DRV_SPI_SYS_QUEUE_SUCCESS)
398
        {
399
            SYS_ASSERT(false, "\r\nSPI Driver: Queue free element error.");
400
            return 0;
401
        }
402
        dObj->currentJob = NULL;
403
        PLIB_SPI_BufferClear(SPI_ID_1 );
404
        PLIB_SPI_ReceiverOverflowClear (SPI_ID_1 );
405
    }
406
    return 0;
407
}
408

    
409

    
410
// *********************************************************************************************
411
// *********************************************************************************************
412
// Section: Old static driver compatibility APIs, these will be deprecated.
413
// *********************************************************************************************
414
// *********************************************************************************************
415
bool DRV_SPI0_ReceiverBufferIsFull(void)
416
{
417
    return (PLIB_SPI_ReceiverBufferIsFull(SPI_ID_1));
418
}
419

    
420
bool DRV_SPI0_TransmitterBufferIsFull(void)
421
{
422
    return (PLIB_SPI_TransmitBufferIsFull(SPI_ID_1));
423
}
424

    
425
int32_t DRV_SPI0_BufferAddWriteRead(const void * txBuffer, void * rxBuffer, uint32_t size)
426
{
427
    bool continueLoop;
428
    int32_t txcounter = 0;
429
    int32_t rxcounter = 0;
430
    do {
431
        continueLoop = false;
432
        if(!PLIB_SPI_TransmitBufferIsFull(SPI_ID_1) && txcounter < size)
433
        {
434
            PLIB_SPI_BufferWrite(SPI_ID_1, ((uint8_t*)txBuffer)[txcounter]);
435
            txcounter++;
436
            continueLoop = true;
437
        }
438

    
439
        while (txcounter != rxcounter)
440
        {
441
            while(!PLIB_SPI_ReceiverBufferIsFull(SPI_ID_1));
442
            ((uint8_t*)rxBuffer)[rxcounter] = PLIB_SPI_BufferRead(SPI_ID_1);
443
            rxcounter++;
444
            continueLoop = true;
445
        }
446
        if (txcounter > rxcounter)
447
        {
448
            continueLoop = true;
449
        }
450
    }while(continueLoop);
451
    return txcounter;
452
}
453