Statistics
| Branch: | Tag: | Revision:

mongoose / examples / PIC32 / http_server / firmware / src / system_config / pic32mx_eth_sk2_encx24j600 / framework / driver / spi / dynamic / drv_spi_api.c @ eaef5bd1

History | View | Annotate | Download (11.7 KB)

1
/* clang-format off */
2
/*******************************************************************************
3
  SPI Driver Interface Implementation
4

5
  Company:
6
    Microchip Technology Inc.
7

8
  File Name:
9
   drv_spi_api.i
10

11
  Summary:
12
 SPI Driver implementation for functions that the client API uses that change
13
 depending on what compile time options there are.
14

15
  Description:
16
    The SPI Driver provides a interface to access the SPI hardware on the PIC32
17
    microcontroller.  This file implements the SPI Driver. This file
18
    should be included in the project if SPI driver functionality is needed.
19
*******************************************************************************/
20

    
21
//DOM-IGNORE-BEGIN
22
/*******************************************************************************
23
Copyright (c) 2014 released Microchip Technology Inc.  All rights reserved.
24

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

30
You should refer to the license agreement accompanying this Software for
31
additional information regarding your rights and obligations.
32

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

    
46
#include "driver/spi/src/dynamic/drv_spi_internal.h"
47

    
48
#define _SPI_DRV_VTABLE_POLLED      0x0000
49
#define _SPI_DRV_VTABLE_ISR         0x0001
50

    
51
#define _SPI_DRV_VTABLE_SLAVE       0x0000
52
#define _SPI_DRV_VTABLE_MASTER      0x0002
53

    
54
#define _SPI_DRV_VTABLE_RM          0x0000
55
#define _SPI_DRV_VTABLE_EBM         0x0004
56

    
57
#define _SPI_DRV_VTABLE_8BIT        0x0008
58
#define _SPI_DRV_VTABLE_16BIT       0x0010
59
#define _SPI_DRV_VTABLE_32BIT       0x0020
60

    
61
#define _SPI_DRV_VTABLE_P_S_R_8 _SPI_DRV_VTABLE_POLLED | _SPI_DRV_VTABLE_SLAVE | _SPI_DRV_VTABLE_RM | _SPI_DRV_VTABLE_8BIT
62
#define _SPI_DRV_VTABLE_P_S_R_16 _SPI_DRV_VTABLE_POLLED | _SPI_DRV_VTABLE_SLAVE | _SPI_DRV_VTABLE_RM | _SPI_DRV_VTABLE_16BIT
63
#define _SPI_DRV_VTABLE_P_S_R_32 _SPI_DRV_VTABLE_POLLED | _SPI_DRV_VTABLE_SLAVE | _SPI_DRV_VTABLE_RM | _SPI_DRV_VTABLE_32BIT
64

    
65
#define _SPI_DRV_VTABLE_P_S_E_8 _SPI_DRV_VTABLE_POLLED | _SPI_DRV_VTABLE_SLAVE | _SPI_DRV_VTABLE_EBM | _SPI_DRV_VTABLE_8BIT
66
#define _SPI_DRV_VTABLE_P_S_E_16 _SPI_DRV_VTABLE_POLLED | _SPI_DRV_VTABLE_SLAVE | _SPI_DRV_VTABLE_EBM | _SPI_DRV_VTABLE_16BIT
67
#define _SPI_DRV_VTABLE_P_S_E_32 _SPI_DRV_VTABLE_POLLED | _SPI_DRV_VTABLE_SLAVE | _SPI_DRV_VTABLE_EBM | _SPI_DRV_VTABLE_32BIT
68

    
69
#define _SPI_DRV_VTABLE_I_S_R_8 _SPI_DRV_VTABLE_ISR | _SPI_DRV_VTABLE_SLAVE | _SPI_DRV_VTABLE_RM | _SPI_DRV_VTABLE_8BIT
70
#define _SPI_DRV_VTABLE_I_S_R_16 _SPI_DRV_VTABLE_ISR | _SPI_DRV_VTABLE_SLAVE | _SPI_DRV_VTABLE_RM | _SPI_DRV_VTABLE_16BIT
71
#define _SPI_DRV_VTABLE_I_S_R_32 _SPI_DRV_VTABLE_ISR | _SPI_DRV_VTABLE_SLAVE | _SPI_DRV_VTABLE_RM | _SPI_DRV_VTABLE_32BIT
72

    
73
#define _SPI_DRV_VTABLE_I_S_E_8 _SPI_DRV_VTABLE_ISR | _SPI_DRV_VTABLE_SLAVE | _SPI_DRV_VTABLE_EBM | _SPI_DRV_VTABLE_8BIT
74
#define _SPI_DRV_VTABLE_I_S_E_16 _SPI_DRV_VTABLE_ISR | _SPI_DRV_VTABLE_SLAVE | _SPI_DRV_VTABLE_EBM | _SPI_DRV_VTABLE_16BIT
75
#define _SPI_DRV_VTABLE_I_S_E_32 _SPI_DRV_VTABLE_ISR | _SPI_DRV_VTABLE_SLAVE | _SPI_DRV_VTABLE_EBM | _SPI_DRV_VTABLE_32BIT
76

    
77
#define _SPI_DRV_VTABLE_P_M_R_8 _SPI_DRV_VTABLE_POLLED | _SPI_DRV_VTABLE_MASTER | _SPI_DRV_VTABLE_RM | _SPI_DRV_VTABLE_8BIT
78
#define _SPI_DRV_VTABLE_P_M_R_16 _SPI_DRV_VTABLE_POLLED | _SPI_DRV_VTABLE_MASTER | _SPI_DRV_VTABLE_RM | _SPI_DRV_VTABLE_16BIT
79
#define _SPI_DRV_VTABLE_P_M_R_32 _SPI_DRV_VTABLE_POLLED | _SPI_DRV_VTABLE_MASTER | _SPI_DRV_VTABLE_RM | _SPI_DRV_VTABLE_32BIT
80

    
81
#define _SPI_DRV_VTABLE_P_M_E_8 _SPI_DRV_VTABLE_POLLED | _SPI_DRV_VTABLE_MASTER | _SPI_DRV_VTABLE_EBM | _SPI_DRV_VTABLE_8BIT
82
#define _SPI_DRV_VTABLE_P_M_E_16 _SPI_DRV_VTABLE_POLLED | _SPI_DRV_VTABLE_MASTER | _SPI_DRV_VTABLE_EBM | _SPI_DRV_VTABLE_16BIT
83
#define _SPI_DRV_VTABLE_P_M_E_32 _SPI_DRV_VTABLE_POLLED | _SPI_DRV_VTABLE_MASTER | _SPI_DRV_VTABLE_EBM | _SPI_DRV_VTABLE_32BIT
84

    
85
#define _SPI_DRV_VTABLE_I_M_R_8 _SPI_DRV_VTABLE_ISR | _SPI_DRV_VTABLE_MASTER | _SPI_DRV_VTABLE_RM | _SPI_DRV_VTABLE_8BIT
86
#define _SPI_DRV_VTABLE_I_M_R_16 _SPI_DRV_VTABLE_ISR | _SPI_DRV_VTABLE_MASTER | _SPI_DRV_VTABLE_RM | _SPI_DRV_VTABLE_16BIT
87
#define _SPI_DRV_VTABLE_I_M_R_32 _SPI_DRV_VTABLE_ISR | _SPI_DRV_VTABLE_MASTER | _SPI_DRV_VTABLE_RM | _SPI_DRV_VTABLE_32BIT
88

    
89
#define _SPI_DRV_VTABLE_I_M_E_8 _SPI_DRV_VTABLE_ISR | _SPI_DRV_VTABLE_MASTER | _SPI_DRV_VTABLE_EBM | _SPI_DRV_VTABLE_8BIT
90
#define _SPI_DRV_VTABLE_I_M_E_16 _SPI_DRV_VTABLE_ISR | _SPI_DRV_VTABLE_MASTER | _SPI_DRV_VTABLE_EBM | _SPI_DRV_VTABLE_16BIT
91
#define _SPI_DRV_VTABLE_I_M_E_32 _SPI_DRV_VTABLE_ISR | _SPI_DRV_VTABLE_MASTER | _SPI_DRV_VTABLE_EBM | _SPI_DRV_VTABLE_32BIT
92

    
93
int32_t DRV_SPI_SetVTable(struct DRV_SPI_DRIVER_OBJECT * driverObject, const DRV_SPI_INIT * const pInit)
94
{
95
    uint8_t mode = 0;
96
    if (pInit->spiMode == DRV_SPI_MODE_MASTER)
97
    {
98
        mode = _SPI_DRV_VTABLE_MASTER;
99
    }
100
    else
101
    {
102
        SYS_ASSERT(false, "\r\nInvalid SPI Configuration.");
103
        return -1;
104
    }
105

    
106
    if (pInit->taskMode == DRV_SPI_TASK_MODE_ISR)
107
    {
108
        mode |= DRV_SPI_TASK_MODE_ISR;
109
    }
110
    else
111
    {
112
        SYS_ASSERT(false, "\r\nInvalid SPI Configuration.");
113
        return -1;
114
    }
115

    
116
    if (pInit->bufferType == DRV_SPI_BUFFER_TYPE_ENHANCED)
117
    {
118
        mode |= _SPI_DRV_VTABLE_EBM;
119
    }
120
    else
121
    {
122
        SYS_ASSERT(false, "\r\nInvalid SPI Configuration.");
123
        return -1;
124
    }
125

    
126
    if (pInit->commWidth == SPI_COMMUNICATION_WIDTH_8BITS)
127
    {
128
        mode |= _SPI_DRV_VTABLE_8BIT;
129
    }
130
    else
131
    {
132
        SYS_ASSERT(false, "\r\nInvalid SPI Configuration.");
133
        return -1;
134
    }
135
    switch (mode)
136
    {
137
    case _SPI_DRV_VTABLE_I_M_E_8:
138
        driverObject->vfMainTask = DRV_SPI_ISRMasterEBM8BitTasks;
139
        break;
140
    default:
141
        SYS_ASSERT(false, "\r\nInvalid SPI Configuration.");
142
        return -1;
143
    }
144
    return 0;
145
}
146

    
147
int32_t DRV_SPI_SetupHardware(struct DRV_SPI_DRIVER_OBJECT * driverObject, const DRV_SPI_INIT * const init)
148
{
149
    const register SPI_MODULE_ID spiId = init->spiId;
150

    
151
/* disable the SPI*/
152
    PLIB_SPI_Disable(spiId);
153

    
154
    /* Set up Master or Slave Mode*/
155
    PLIB_SPI_MasterEnable ( spiId  );
156

    
157
    /* Set up if the SPI is allowed to run while the rest of the CPU is in idle mode*/
158
    if (init->allowIdleRun)
159
    {
160
        PLIB_SPI_StopInIdleDisable( spiId  );
161
    }
162
    else
163
    {
164
        PLIB_SPI_StopInIdleEnable( spiId  );
165
    }
166

    
167
    /* Set up close Polarity and output data phase*/
168
    switch(init->clockMode)
169
    {
170
        case DRV_SPI_CLOCK_MODE_IDLE_LOW_EDGE_RISE:
171
            PLIB_SPI_ClockPolaritySelect( spiId, SPI_CLOCK_POLARITY_IDLE_LOW );
172
            PLIB_SPI_OutputDataPhaseSelect( spiId, SPI_OUTPUT_DATA_PHASE_ON_IDLE_TO_ACTIVE_CLOCK );
173
            break;
174
        case DRV_SPI_CLOCK_MODE_IDLE_LOW_EDGE_FALL:
175
            PLIB_SPI_ClockPolaritySelect( spiId, SPI_CLOCK_POLARITY_IDLE_LOW );
176
            PLIB_SPI_OutputDataPhaseSelect( spiId, SPI_OUTPUT_DATA_PHASE_ON_ACTIVE_TO_IDLE_CLOCK );
177
            break;
178
        case DRV_SPI_CLOCK_MODE_IDLE_HIGH_EDGE_FALL: //TODO: Make sure these are right
179
            PLIB_SPI_ClockPolaritySelect( spiId, SPI_CLOCK_POLARITY_IDLE_HIGH );
180
            PLIB_SPI_OutputDataPhaseSelect( spiId, SPI_OUTPUT_DATA_PHASE_ON_IDLE_TO_ACTIVE_CLOCK );
181
            break;
182
        case DRV_SPI_CLOCK_MODE_IDLE_HIGH_EDGE_RISE:
183
            PLIB_SPI_ClockPolaritySelect( spiId, SPI_CLOCK_POLARITY_IDLE_HIGH );
184
            PLIB_SPI_OutputDataPhaseSelect( spiId, SPI_OUTPUT_DATA_PHASE_ON_ACTIVE_TO_IDLE_CLOCK );
185
            break;
186
        default:
187
             SYS_ASSERT(false, "\r\nInvalid SPI Configuration.");
188
            return -1;
189
    }
190

    
191
    // Set up the  Input Sample Phase
192
    PLIB_SPI_InputSamplePhaseSelect ( spiId, init->inputSamplePhase);
193

    
194
    //Enable the SSx Pin on slave side if needed
195
    if(init->spiMode == DRV_SPI_MODE_SLAVE && (init->spiProtocolType == DRV_SPI_PROTOCOL_TYPE_FRAMED || init->spiSlaveSSPin))
196
    {
197
        PLIB_SPI_PinEnable(spiId, SPI_PIN_SLAVE_SELECT);
198
    }
199
    else
200
    {
201
        PLIB_SPI_PinDisable(spiId, SPI_PIN_SLAVE_SELECT);
202
    }
203

    
204
    /* Communication Width Selection */
205
    PLIB_SPI_CommunicationWidthSelect ( spiId, init->commWidth );
206

    
207
    /* Baudrate selection */
208
    PLIB_SPI_BaudRateSet( spiId , SYS_CLK_PeripheralFrequencyGet(init->spiClk), init->baudRate );
209
    driverObject->currentBaudRate = init->baudRate;
210
    driverObject->baudRate = init->baudRate;
211

    
212
    switch (init->spiProtocolType)
213
    {
214
        case DRV_SPI_PROTOCOL_TYPE_STANDARD:
215
             PLIB_SPI_FramedCommunicationDisable( spiId  );
216
             break;
217

    
218
        case DRV_SPI_PROTOCOL_TYPE_FRAMED:
219

    
220
            #if defined (PLIB_SPI_ExistsFrameSyncPulseDirection)
221
                if (PLIB_SPI_ExistsFrameSyncPulseDirection(spiId))
222
                {
223
                    PLIB_SPI_FrameSyncPulseDirectionSelect(spiId, init->framePulseDirection);
224
                }
225
            #endif
226
            #if defined (PLIB_SPI_ExistsFrameSyncPulsePolarity)
227
                if (PLIB_SPI_ExistsFrameSyncPulsePolarity(spiId))
228
                {
229
                    PLIB_SPI_FrameSyncPulsePolaritySelect(spiId, init->framePulsePolarity);
230
                }
231
            #endif
232
            #if defined (PLIB_SPI_ExistsFrameSyncPulseEdge)
233
                if (PLIB_SPI_ExistsFrameSyncPulseEdge(spiId))
234
                {
235
                    PLIB_SPI_FrameSyncPulseEdgeSelect(spiId, init->framePulseEdge);
236
                }
237
            #endif
238
            #if defined (PLIB_SPI_ExistsFrameSyncPulseWidth)
239
                if (PLIB_SPI_ExistsFrameSyncPulseWidth(spiId))
240
                {
241
                    PLIB_SPI_FrameSyncPulseWidthSelect(spiId, init->framePulseWidth);
242
                }
243
            #endif
244
            #if defined (PLIB_SPI_ExistsFrameSyncPulseCounter)
245
                if (PLIB_SPI_ExistsFrameSyncPulseCounter(spiId))
246
                {
247
                    PLIB_SPI_FrameSyncPulseCounterSelect(spiId, init->frameSyncPulse);
248
                }
249
            #endif
250

    
251

    
252
            PLIB_SPI_FramedCommunicationEnable( spiId  );
253
            break;
254

    
255
        case DRV_SPI_PROTOCOL_TYPE_AUDIO:
256
             PLIB_SPI_FramedCommunicationDisable( spiId  );
257

    
258
             {
259
                 SYS_ASSERT(false, "\r\nInvalid SPI Configuration.");
260
                return -1;
261
             }
262
             break;
263
        default:
264
             SYS_ASSERT(false, "\r\nInvalid SPI Configuration.");
265
            return -1;
266
    }
267

    
268
    PLIB_SPI_FIFOEnable( spiId  );
269
    PLIB_SPI_FIFOInterruptModeSelect(spiId, SPI_FIFO_INTERRUPT_WHEN_TRANSMIT_BUFFER_IS_COMPLETELY_EMPTY);
270
    PLIB_SPI_FIFOInterruptModeSelect(spiId, SPI_FIFO_INTERRUPT_WHEN_RECEIVE_BUFFER_IS_NOT_EMPTY);
271

    
272
    PLIB_SPI_BufferClear( spiId );
273
    PLIB_SPI_ReceiverOverflowClear ( spiId );
274

    
275
    // Note: We do not enable the SPI here, that will be done by the first client.
276
    return 0;
277
}
278

    
279