?lang_form? ?lang_select? ?lang_submit? ?lang_endform?
{HEADER END}
{BLAME START}

library

?curdirlinks? -

Blame information for rev 32

Line No. Rev Author Line
1 32 kaklik /******************************************************************************
2  
3 MRF24WB0M Driver SPI interface routines
4 Module for Microchip TCP/IP Stack
5  
6 *******************************************************************************
7 FileName: WF_Spi.c
8 Dependencies: TCP/IP Stack header files
9 Processor: PIC18, PIC24F, PIC24H, dsPIC30F, dsPIC33F, PIC32
10 Compiler: Microchip C32 v1.10b or higher
11 Microchip C30 v3.22 or higher
12 Microchip C18 v3.34 or higher
13 Company: Microchip Technology, Inc.
14  
15 Software License Agreement
16  
17 Copyright (C) 2002-2010 Microchip Technology Inc. All rights reserved.
18  
19 Microchip licenses to you the right to use, modify, copy, and distribute:
20 (i) the Software when embedded on a Microchip microcontroller or digital
21 signal controller product ("Device") which is integrated into
22 Licensee's product; or
23 (ii) ONLY the Software driver source files ENC28J60.c, ENC28J60.h,
24 ENCX24J600.c and ENCX24J600.h ported to a non-Microchip device used in
25 conjunction with a Microchip ethernet controller for the sole purpose
26 of interfacing with the ethernet controller.
27  
28 You should refer to the license agreement accompanying this Software for
29 additional information regarding your rights and obligations.
30  
31 THE SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
32 KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY WARRANTY
33 OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
34 NON-INFRINGEMENT. IN NO EVENT SHALL MICROCHIP BE LIABLE FOR ANY INCIDENTAL,
35 SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST
36 OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS BY
37 THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), ANY CLAIMS
38 FOR INDEMNITY OR CONTRIBUTION, OR OTHER SIMILAR COSTS, WHETHER ASSERTED ON
39 THE BASIS OF CONTRACT, TORT (INCLUDING NEGLIGENCE), BREACH OF WARRANTY, OR
40 OTHERWISE.
41  
42  
43 Author Date Comment
44 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
45 Zero G Sep 2008 Initial version
46 KO 31 Oct 2008 Port to PIC24F and PIC32 for TCP/IP stack v4.52
47 ******************************************************************************/
48  
49 /*
50 *********************************************************************************************************
51 * INCLUDES
52 *********************************************************************************************************
53 */
54  
55 #include "TCPIP Stack/WFMac.h"
56  
57 #if defined(WF_CS_TRIS)
58  
59 /*
60 *********************************************************************************************************
61 * DEFINES
62 *********************************************************************************************************
63 */
64  
65 /* used for assertions */
66 #ifdef WF_DEBUG
67 #define WF_MODULE_NUMBER WF_MODULE_WF_SPI
68 #endif
69  
70 /* Indicate here if the MRF24WB0M is sharing the SPI bus with another device. For the */
71 /* Microchip demos only the PIC18 on the PICDEM.net 2 board shares the SPI bus. */
72 #if defined(__18CXX)
73 #define SPI_IS_SHARED
74 #endif
75  
76 #if defined (SPI_IS_SHARED)
77 /* SPI context save variables */
78 static BYTE SPIONSave;
79 #if defined( __18CXX)
80 static BYTE SPICON1Save;
81 static BYTE SPISTATSave;
82 #elif defined( __C30__ )
83 static WORD SPICON1Save;
84 static WORD SPICON2Save;
85 static WORD SPISTATSave;
86 #elif defined( __PIC32MX__ )
87 static DWORD SPICON1Save;
88 static DWORD SPISTATSave;
89 #else
90 #error Cannot define SPI context save variables.
91 #endif
92 #endif /* SPI_IS_SHARED */
93  
94 //============================================================================
95 // SPI Definitions
96 //============================================================================
97  
98 #if defined (__18CXX)
99 #define ClearSPIDoneFlag() {WF_SPI_IF = 0;}
100 #define WaitForDataByte() {while(!WF_SPI_IF); WF_SPI_IF = 0;}
101 #define SPI_ON_BIT (WF_SPICON1bits.SSPEN)
102 #elif defined(__C30__)
103 #define ClearSPIDoneFlag()
104 static inline __attribute__((__always_inline__)) void WaitForDataByte( void )
105 {
106 while ((WF_SPISTATbits.SPITBF == 1) || (WF_SPISTATbits.SPIRBF == 0));
107 }
108  
109 #define SPI_ON_BIT (WF_SPISTATbits.SPIEN)
110 #elif defined( __PIC32MX__ )
111 #define ClearSPIDoneFlag()
112 static inline __attribute__((__always_inline__)) void WaitForDataByte( void )
113 {
114 while (!WF_SPISTATbits.SPITBE || !WF_SPISTATbits.SPIRBF);
115 }
116  
117 #define SPI_ON_BIT (WF_SPICON1bits.ON)
118 #else
119 #error Determine SPI flag mechanism
120 #endif
121  
122 /*
123 *********************************************************************************************************
124 * LOCAL FUNCTION PROTOTYPES
125 *********************************************************************************************************
126 */
127  
128 #if defined (SPI_IS_SHARED)
129 static void SaveSpiContext(void);
130 static void RestoreSpiContext(void);
131 #endif
132 static void ConfigureSpiMRF24WB0M(void);
133  
134  
135 /*****************************************************************************
136 Function:
137 void WF_SpiInit(void)
138  
139 Summary:
140 Initializes the SPI interface to the MRF24WB0M device.
141  
142 Description:
143 Configures the SPI interface for communications with the MRF24WB0M.
144  
145 Precondition:
146 None
147  
148 Parameters:
149 None
150  
151 Returns:
152 None
153  
154 Remarks:
155 This function is called by WFHardwareInit.
156 *****************************************************************************/
157 void WF_SpiInit(void)
158 {
159 /* disable the spi interrupt */
160 #if defined( __PIC32MX__ )
161 WF_SPI_IE_CLEAR = WF_SPI_INT_BITS;
162 #else
163 WF_SPI_IE = 0;
164 #endif
165 #if defined( __18CXX)
166 WF_SPI_IP = 0;
167 #endif
168  
169 // Set up the SPI module on the PIC for communications with the MRF24WB0M
170 WF_CS_IO = 1;
171 WF_CS_TRIS = 0; // Drive SPI MRF24WB0M chip select pin
172 #if defined( __18CXX)
173 WF_SCK_TRIS = 0; /* SPI Clock is an output */
174 WF_SDO_TRIS = 0; /* SPI Data Out is an output */
175 WF_SDI_TRIS = 1; /* SPI Data In is an input */
176 #else
177 // We'll let the module control the pins.
178 #endif
179  
180 #if !defined( SPI_IS_SHARED )
181 ConfigureSpiMRF24WB0M();
182 #endif
183  
184 /* clear the completion flag */
185 ClearSPIDoneFlag();
186 }
187  
188  
189 /*
190 Fsck = Fpb
191 ------------------
192 2 * (SPIxBRG + 1)
193  
194 Note that the maximum possible baud rate is
195 Fpb/2 (SPIXBRG = 0) and the minimum possible baud
196 rate is FPB /1024.
197 */
198  
199  
200 /*****************************************************************************
201 Function:
202 void ConfigureSpiMRF24WB0M(void)
203  
204 Summary:
205 Configures the SPI interface to the MRF24WB0M.
206  
207 Description:
208 Configures the SPI interface for communications with the MRF24WB0M.
209  
210 Precondition:
211 None
212  
213 Parameters:
214 None
215  
216 Returns:
217 None
218  
219 Remarks:
220 If the SPI bus is shared with other peripherals this function is called
221 each time an SPI transaction occurs by WF_SpiEnableChipSelect. Otherwise it
222 is called once during initialization by WF_SpiInit.
223 *****************************************************************************/
224 static void ConfigureSpiMRF24WB0M(void)
225 {
226 /*----------------------------------------------------------------*/
227 /* After we save context, configure SPI for MRF24WB0M communications */
228 /*----------------------------------------------------------------*/
229 /* enable the SPI clocks */
230 /* set as master */
231 /* clock idles high */
232 /* ms bit first */
233 /* 8 bit tranfer length */
234 /* data changes on falling edge */
235 /* data is sampled on rising edge */
236 /* set the clock divider */
237 #if defined(__18CXX)
238 WF_SPICON1 = 0x30; // SSPEN bit is set, SPI in master mode, (0x30 is for FOSC/4),
239 // IDLE state is high level (0x32 is for FOSC/64)
240 WF_SPISTATbits.CKE = 0; // Transmit data on falling edge of clock
241 WF_SPISTATbits.SMP = 1; // Input sampled at end? of data output time
242 #elif defined(__C30__)
243 WF_SPICON1 = 0x027B; // Fcy Primary prescaler 1:1, secondary prescaler 2:1, CKP=1, CKE=0, SMP=1
244 WF_SPICON2 = 0x0000;
245 WF_SPISTAT = 0x8000; // Enable the module
246 #elif defined( __PIC32MX__ )
247 WF_SPI_BRG = (GetPeripheralClock()-1ul)/2ul/WF_MAX_SPI_FREQ;
248 WF_SPICON1 = 0x00000260; // sample at end, data change idle to active, clock idle high, master
249 WF_SPICON1bits.ON = 1;
250 #else
251 #error Configure SPI for the selected processor
252 #endif
253 }
254  
255 /*****************************************************************************
256 Function:
257 void WF_SpiEnableChipSelect(void)
258  
259 Summary:
260 Enables the MRF24WB0M SPI chip select.
261  
262 Description:
263 Enables the MRF24WB0M SPI chip select as part of the sequence of SPI
264 communications.
265  
266 Precondition:
267 None
268  
269 Parameters:
270 None
271  
272 Returns:
273 None
274  
275 Remarks:
276 If the SPI bus is shared with other peripherals then the current SPI context
277 is saved.
278 *****************************************************************************/
279 void WF_SpiEnableChipSelect(void)
280 {
281 #if defined(__18CXX)
282 static volatile UINT8 dummy;
283 #endif
284  
285 #if defined(SPI_IS_SHARED)
286 SaveSpiContext();
287 ConfigureSpiMRF24WB0M();
288 #endif
289  
290 /* set Slave Select low (enable SPI chip select on MRF24WB0M) */
291 WF_CS_IO = 0;
292  
293 /* clear any pending interrupts */
294 #if defined(__18CXX)
295 dummy = WF_SSPBUF;
296 ClearSPIDoneFlag();
297 #endif
298  
299  
300 }
301  
302 /*****************************************************************************
303 Function:
304 void WF_SpiDisableChipSelect(void)
305  
306 Summary:
307 Disables the MRF24WB0M SPI chip select.
308  
309 Description:
310 Disables the MRF24WB0M SPI chip select as part of the sequence of SPI
311 communications.
312  
313 Precondition:
314 None
315  
316 Parameters:
317 None
318  
319 Returns:
320 None
321  
322 Remarks:
323 If the SPI bus is shared with other peripherals then the current SPI context
324 is restored.
325 *****************************************************************************/
326 void WF_SpiDisableChipSelect(void)
327 {
328 /* Disable the interrupt */
329 #if defined( __PIC32MX__ )
330 WF_SPI_IE_CLEAR = WF_SPI_INT_BITS;
331 #else
332 WF_SPI_IE = 0;
333 #endif
334  
335 /* set Slave Select high ((disable SPI chip select on MRF24WB0M) */
336 WF_CS_IO = 1;
337  
338 #if defined(SPI_IS_SHARED)
339 RestoreSpiContext();
340 #endif
341 }
342  
343 /*****************************************************************************
344 Function:
345 void WFSpiTxRx(void)
346  
347 Summary:
348 Transmits and receives SPI bytes
349  
350 Description:
351 Transmits and receives N bytes of SPI data.
352  
353 Precondition:
354 None
355  
356 Parameters:
357 p_txBuf - pointer to SPI tx data
358 txLen - number of bytes to Tx
359 p_rxBuf - pointer to where SPI rx data will be stored
360 rxLen - number of SPI rx bytes caller wants copied to p_rxBuf
361  
362 Returns:
363 None
364  
365 Remarks:
366 Will clock out the larger of txLen or rxLen, and pad if necessary.
367 *****************************************************************************/
368 void WFSpiTxRx(UINT8 *p_txBuf,
369 UINT16 txLen,
370 UINT8 *p_rxBuf,
371 UINT16 rxLen)
372 {
373 #if defined(__18CXX)
374 static UINT16 byteCount; /* avoid local variables in functions called from interrupt routine */
375 static UINT16 i;
376 static UINT8 rxTrash;
377 #else
378 UINT16 byteCount;
379 UINT16 i;
380 UINT8 rxTrash;
381 #endif
382  
383  
384 #ifdef WF_DEBUG
385 /* Cannot communicate with MRF24WB0M when it is in hibernate mode */
386 {
387 static UINT8 state; /* avoid local vars in functions called from interrupt */
388 WF_GetPowerSaveState(&state);
389 WF_ASSERT(state != WF_PS_HIBERNATE);
390 }
391 #endif
392  
393 /* total number of byte to clock is whichever is larger, txLen or rxLen */
394 byteCount = (txLen >= rxLen)?txLen:rxLen;
395  
396 for (i = 0; i < byteCount; ++i)
397 {
398 /* if still have bytes to transmit from tx buffer */
399 if (txLen > 0)
400 {
401 WF_SSPBUF = *p_txBuf++;
402 --txLen;
403 }
404 /* else done writing bytes out from tx buffer */
405 else
406 {
407 WF_SSPBUF = 0xff; /* clock out a "don't care" byte */
408 }
409  
410 /* wait until tx/rx byte to completely clock out */
411 WaitForDataByte();
412  
413 /* if still have bytes to read into rx buffer */
414 if (rxLen > 0)
415 {
416 *p_rxBuf++ = WF_SSPBUF;
417 --rxLen;
418 }
419 /* else done reading bytes into rx buffer */
420 else
421 {
422 rxTrash = WF_SSPBUF; /* read and throw away byte */
423 }
424 } /* end for loop */
425  
426 }
427  
428 #if defined(__18CXX)
429 /*****************************************************************************
430 Function:
431 void WFSpiTxRx_Rom(void)
432  
433 Summary:
434 Transmits and receives SPI bytes
435  
436 Description:
437 Specific to the PIC18, transmits bytes from ROM storage and receives SPI data
438 bytes.
439  
440 Precondition:
441 None
442  
443 Parameters:
444 p_txBuf - pointer to SPI ROM tx data
445 txLen - number of bytes to Tx
446 p_rxBuf - pointer to where SPI rx data will be stored
447 rxLen - number of SPI rx bytes caller wants copied to p_rxBuf
448  
449 Returns:
450 None
451  
452 Remarks:
453 Will clock out the larger of txLen or rxLen, and pad if necessary.
454 *****************************************************************************/
455 void WFSpiTxRx_Rom(ROM UINT8 *p_txBuf,
456 UINT16 txLen,
457 UINT8 *p_rxBuf,
458 UINT16 rxLen)
459 {
460 static UINT16 byteCount; /* avoid local variables in functions called from interrupt routine */
461 static UINT16 i;
462 static UINT8 rxTrash;
463  
464 /* total number of byte to clock is whichever is larger, txLen or rxLen */
465 byteCount = (txLen >= rxLen)?txLen:rxLen;
466  
467 for (i = 0; i < byteCount; ++i)
468 {
469 /* if still have bytes to transmit from tx buffer */
470 if (txLen > 0)
471 {
472 WF_SSPBUF = *p_txBuf++;
473 --txLen;
474 }
475 /* else done writing bytes out from tx buffer */
476 else
477 {
478 WF_SSPBUF = 0xff; /* clock out a "don't care" byte */
479 }
480  
481 // wait until tx/rx byte completely clocked out
482 WaitForDataByte();
483  
484 /* if still have bytes to read into rx buffer */
485 if (rxLen > 0)
486 {
487 *p_rxBuf++ = WF_SSPBUF;
488 --rxLen;
489 }
490 /* else done reading bytes into rx buffer */
491 else
492 {
493 rxTrash = WF_SSPBUF; /* read and throw away byte */
494 }
495 } /* end for loop */
496 }
497 #endif
498  
499 #if defined (SPI_IS_SHARED)
500 /*****************************************************************************
501 Function:
502 void SaveSpiContext(void)
503  
504 Summary:
505 Saves SPI context.
506  
507 Description:
508 Saves the SPI context (mainly speed setting) before using the SPI to
509 access MRF24WB0M. Turn off the SPI module before reconfiguring it.
510 We only need this function if SPI lines are shared.
511  
512 Precondition:
513 None
514  
515 Parameters:
516 None
517  
518 Returns:
519 None
520  
521 Remarks:
522 Only called if SPI_IS_SHARED is defined
523 *****************************************************************************/
524 static void SaveSpiContext(void)
525 {
526 // Save SPI state (clock speed)
527 SPICON1Save = WF_SPICON1;
528 #if defined( __C30__ )
529 SPICON2Save = WF_SPICON2;
530 #endif
531 SPISTATSave = WF_SPISTAT;
532 SPIONSave = SPI_ON_BIT;
533 SPI_ON_BIT = 0;
534 }
535  
536 /*****************************************************************************
537 Function:
538 void RestoreSpiContext(void)
539  
540 Summary:
541 Restores SPI context.
542  
543 Description:
544 Restores the SPI context (mainly speed setting) after using the SPI to
545 access MRF24WB0M. Turn off the SPI module before reconfiguring it.
546 We only need this function if SPI lines are shared.
547  
548 Precondition:
549 None
550  
551 Parameters:
552 None
553  
554 Returns:
555 None
556  
557 Remarks:
558 Only called if SPI_IS_SHARED is defined
559 *****************************************************************************/
560 static void RestoreSpiContext(void)
561 {
562 SPI_ON_BIT = 0;
563 WF_SPICON1 = SPICON1Save;
564 #if defined( __C30__ )
565 WF_SPICON2 = SPICON2Save;
566 #endif
567 WF_SPISTAT = SPISTATSave;
568 SPI_ON_BIT = SPIONSave;
569 }
570 #endif /* SPI_IS_SHARED */
571  
572  
573  
574 #else
575 // dummy func to keep compiler happy when module has no executeable code
576 void MCHP_Spi_EmptyFunc(void)
577 {
578 }
579 #endif /* WF_CS_TRIS */
580  
{BLAME END}
{FOOTER START}

Powered by WebSVN v2.8.3