]> git.sur5r.net Git - freertos/blob - Demo/CORTEX_LM3S811_IAR/LuminaryCode/ssi.c
Update the Cortex-M3 IAR projects to compile with EWARM 6.20 where necessary.
[freertos] / Demo / CORTEX_LM3S811_IAR / LuminaryCode / ssi.c
1 //*****************************************************************************\r
2 //\r
3 // ssi.c - Driver for Synchronous Serial Interface.\r
4 //\r
5 // Copyright (c) 2005,2006 Luminary Micro, Inc.  All rights reserved.\r
6 //\r
7 // Software License Agreement\r
8 //\r
9 // Luminary Micro, Inc. (LMI) is supplying this software for use solely and\r
10 // exclusively on LMI's Stellaris Family of microcontroller products.\r
11 //\r
12 // The software is owned by LMI and/or its suppliers, and is protected under\r
13 // applicable copyright laws.  All rights are reserved.  Any use in violation\r
14 // of the foregoing restrictions may subject the user to criminal sanctions\r
15 // under applicable laws, as well as to civil liability for the breach of the\r
16 // terms and conditions of this license.\r
17 //\r
18 // THIS SOFTWARE IS PROVIDED "AS IS".  NO WARRANTIES, WHETHER EXPRESS, IMPLIED\r
19 // OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF\r
20 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.\r
21 // LMI SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR\r
22 // CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.\r
23 //\r
24 // This is part of revision 991 of the Stellaris Driver Library.\r
25 //\r
26 //*****************************************************************************\r
27 \r
28 //*****************************************************************************\r
29 //\r
30 //! \addtogroup ssi_api\r
31 //! @{\r
32 //\r
33 //*****************************************************************************\r
34 \r
35 #include "../hw_ints.h"\r
36 #include "../hw_memmap.h"\r
37 #include "../hw_ssi.h"\r
38 #include "../hw_types.h"\r
39 #include "debug.h"\r
40 #include "interrupt.h"\r
41 #include "ssi.h"\r
42 #include "sysctl.h"\r
43 \r
44 //*****************************************************************************\r
45 //\r
46 //! Configures the synchronous serial interface.\r
47 //!\r
48 //! \param ulBase specifies the SSI module base address.\r
49 //! \param ulProtocol specifies the data transfer protocol.\r
50 //! \param ulMode specifies the mode of operation.\r
51 //! \param ulBitRate specifies the clock rate.\r
52 //! \param ulDataWidth specifies number of bits transfered per frame.\r
53 //!\r
54 //! This function configures the synchronous serial interface. It sets\r
55 //! the SSI protocol, mode of operation, bit rate, and data width.\r
56 //!\r
57 //! The parameter \e ulProtocol defines the data frame format. The parameter\r
58 //! \e ulProtocol can be one of the following values: SSI_FRF_MOTO_MODE_0,\r
59 //! SSI_FRF_MOTO_MODE_1, SSI_FRF_MOTO_MODE_2, SSI_FRF_MOTO_MODE_3,\r
60 //! SSI_FRF_TI, or SSI_FRF_NMW. The Motorola frame formats imply the\r
61 //! following polarity and phase configurations:\r
62 //! <pre>\r
63 //! Polarity Phase       Mode\r
64 //!   0       0   SSI_FRF_MOTO_MODE_0\r
65 //!   0       1   SSI_FRF_MOTO_MODE_1\r
66 //!   1       0   SSI_FRF_MOTO_MODE_2\r
67 //!   1       1   SSI_FRF_MOTO_MODE_3\r
68 //! </pre>\r
69 //!\r
70 //! The parameter \e ulMode defines the operating mode of the SSI module. The\r
71 //! SSI module can operate as a master or slave; if a slave, the SSI can be\r
72 //! configured to disable output on its serial output line. The parameter\r
73 //! \e ulMode can be one of the following values: SSI_MODE_MASTER,\r
74 //! SSI_MODE_SLAVE, or SSI_MODE_SLAVE_OD.\r
75 //!\r
76 //! The parameter \e ulBitRate defines the bit rate for the SSI. This bit rate\r
77 //! must satisfy the following clock ratio criteria:\r
78 //! - FSSI >= 2 * bit rate (master mode)\r
79 //! - FSSI >= 12 * bit rate (slave modes)\r
80 //!\r
81 //! where FSSI is the frequency of the clock supplied to the SSI module.\r
82 //!\r
83 //! The parameter \e ulDataWidth defines the width of the data transfers.\r
84 //! The parameter \e ulDataWidth can be a value between 4 and 16, inclusive.\r
85 //!\r
86 //! The SSI clocking is dependent upon the system clock rate returned by\r
87 //! SysCtlClockGet(); if it does not return the correct system clock rate then\r
88 //! the SSI clock rate will be incorrect.\r
89 //!\r
90 //! \return None.\r
91 //\r
92 //*****************************************************************************\r
93 #if defined(GROUP_config) || defined(BUILD_ALL) || defined(DOXYGEN)\r
94 void\r
95 SSIConfig(unsigned long ulBase, unsigned long ulProtocol, unsigned long ulMode,\r
96           unsigned long ulBitRate, unsigned long ulDataWidth)\r
97 {\r
98     unsigned long ulMaxBitRate;\r
99     unsigned long ulRegVal;\r
100     unsigned long ulPreDiv;\r
101     unsigned long ulSCR;\r
102     unsigned long ulSPH_SPO;\r
103     unsigned long ulClock;\r
104 \r
105     //\r
106     // Check the arguments.\r
107     //\r
108     ASSERT(ulBase == SSI_BASE);\r
109     ASSERT((ulProtocol == SSI_FRF_MOTO_MODE_0) ||\r
110            (ulProtocol == SSI_FRF_MOTO_MODE_1) ||\r
111            (ulProtocol == SSI_FRF_MOTO_MODE_2) ||\r
112            (ulProtocol == SSI_FRF_MOTO_MODE_3) ||\r
113            (ulProtocol == SSI_FRF_TI) ||\r
114            (ulProtocol == SSI_FRF_NMW));\r
115     ASSERT((ulMode == SSI_MODE_MASTER) ||\r
116            (ulMode == SSI_MODE_SLAVE) ||\r
117            (ulMode == SSI_MODE_SLAVE_OD));\r
118     ASSERT((ulDataWidth >= 4) && (ulDataWidth <= 16));\r
119 \r
120     //\r
121     // Get the processor clock rate.\r
122     //\r
123     ulClock = SysCtlClockGet();\r
124 \r
125     //\r
126     // Validate the clock speed.\r
127     //\r
128     ASSERT(((ulMode == SSI_MODE_MASTER) && (ulBitRate <= (ulClock / 2))) ||\r
129            ((ulMode != SSI_MODE_MASTER) && (ulBitRate <= (ulClock / 12))));\r
130     ASSERT((ulClock / ulBitRate) <= (254 * 256));\r
131 \r
132     //\r
133     // Set the mode.\r
134     //\r
135     ulRegVal = (ulMode == SSI_MODE_SLAVE_OD) ? SSI_CR1_SOD : 0;\r
136     ulRegVal |= (ulMode == SSI_MODE_MASTER) ? 0 : SSI_CR1_MS;\r
137     HWREG(ulBase + SSI_O_CR1) = ulRegVal;\r
138 \r
139     //\r
140     // Set the clock predivider.\r
141     //\r
142     ulMaxBitRate = ulClock / ulBitRate;\r
143     ulPreDiv = 0;\r
144     do\r
145     {\r
146         ulPreDiv += 2;\r
147         ulSCR = (ulMaxBitRate / ulPreDiv) - 1;\r
148     }\r
149     while(ulSCR > 255);\r
150     HWREG(ulBase + SSI_O_CPSR) = ulPreDiv;\r
151 \r
152     //\r
153     // Set protocol and clock rate.\r
154     //\r
155     ulSPH_SPO = ulProtocol << 6;\r
156     ulProtocol &= SSI_CR0_FRF_MASK;\r
157     ulRegVal = (ulSCR << 8) | ulSPH_SPO | ulProtocol | (ulDataWidth - 1);\r
158     HWREG(ulBase + SSI_O_CR0) = ulRegVal;\r
159 }\r
160 #endif\r
161 \r
162 //*****************************************************************************\r
163 //\r
164 //! Enables the synchronous serial interface.\r
165 //!\r
166 //! \param ulBase specifies the SSI module base address.\r
167 //!\r
168 //! This will enable operation of the synchronous serial interface. It must be\r
169 //! configured before it is enabled.\r
170 //!\r
171 //! \return None.\r
172 //\r
173 //*****************************************************************************\r
174 #if defined(GROUP_enable) || defined(BUILD_ALL) || defined(DOXYGEN)\r
175 void\r
176 SSIEnable(unsigned long ulBase)\r
177 {\r
178     //\r
179     // Check the arguments.\r
180     //\r
181     ASSERT(ulBase == SSI_BASE);\r
182 \r
183     //\r
184     // Read-modify-write the enable bit.\r
185     //\r
186     HWREG(ulBase + SSI_O_CR1) |= SSI_CR1_SSE;\r
187 }\r
188 #endif\r
189 \r
190 //*****************************************************************************\r
191 //\r
192 //! Disables the synchronous serial interface.\r
193 //!\r
194 //! \param ulBase specifies the SSI module base address.\r
195 //!\r
196 //! This will disable operation of the synchronous serial interface.\r
197 //!\r
198 //! \return None.\r
199 //\r
200 //*****************************************************************************\r
201 #if defined(GROUP_disable) || defined(BUILD_ALL) || defined(DOXYGEN)\r
202 void\r
203 SSIDisable(unsigned long ulBase)\r
204 {\r
205     //\r
206     // Check the arguments.\r
207     //\r
208     ASSERT(ulBase == SSI_BASE);\r
209 \r
210     //\r
211     // Read-modify-write the enable bit.\r
212     //\r
213     HWREG(ulBase + SSI_O_CR1) &= ~(SSI_CR1_SSE);\r
214 }\r
215 #endif\r
216 \r
217 //*****************************************************************************\r
218 //\r
219 //! Registers an interrupt handler for the synchronous serial interface.\r
220 //!\r
221 //! \param ulBase specifies the SSI module base address.\r
222 //! \param pfnHandler is a pointer to the function to be called when the\r
223 //! synchronous serial interface interrupt occurs.\r
224 //!\r
225 //! This sets the handler to be called when an SSI interrupt\r
226 //! occurs.  This will enable the global interrupt in the interrupt controller;\r
227 //! specific SSI interrupts must be enabled via SSIIntEnable().  If necessary,\r
228 //! it is the interrupt handler's responsibility to clear the interrupt source\r
229 //! via SSIIntClear().\r
230 //!\r
231 //! \sa IntRegister() for important information about registering interrupt\r
232 //! handlers.\r
233 //!\r
234 //! \return None.\r
235 //\r
236 //*****************************************************************************\r
237 #if defined(GROUP_intregister) || defined(BUILD_ALL) || defined(DOXYGEN)\r
238 void\r
239 SSIIntRegister(unsigned long ulBase, void (*pfnHandler)(void))\r
240 {\r
241     //\r
242     // Check the arguments.\r
243     //\r
244     ASSERT(ulBase == SSI_BASE);\r
245 \r
246     //\r
247     // Register the interrupt handler, returning an error if an error occurs.\r
248     //\r
249     IntRegister(INT_SSI, pfnHandler);\r
250 \r
251     //\r
252     // Enable the synchronous serial interface interrupt.\r
253     //\r
254     IntEnable(INT_SSI);\r
255 }\r
256 #endif\r
257 \r
258 //*****************************************************************************\r
259 //\r
260 //! Unregisters an interrupt handler for the synchronous serial interface.\r
261 //!\r
262 //! \param ulBase specifies the SSI module base address.\r
263 //!\r
264 //! This function will clear the handler to be called when a SSI\r
265 //! interrupt occurs.  This will also mask off the interrupt in the interrupt\r
266 //! controller so that the interrupt handler no longer is called.\r
267 //!\r
268 //! \sa IntRegister() for important information about registering interrupt\r
269 //! handlers.\r
270 //!\r
271 //! \return None.\r
272 //\r
273 //*****************************************************************************\r
274 #if defined(GROUP_intunregister) || defined(BUILD_ALL) || defined(DOXYGEN)\r
275 void\r
276 SSIIntUnregister(unsigned long ulBase)\r
277 {\r
278     //\r
279     // Check the arguments.\r
280     //\r
281     ASSERT(ulBase == SSI_BASE);\r
282 \r
283     //\r
284     // Disable the interrupt.\r
285     //\r
286     IntDisable(INT_SSI);\r
287 \r
288     //\r
289     // Unregister the interrupt handler.\r
290     //\r
291     IntUnregister(INT_SSI);\r
292 }\r
293 #endif\r
294 \r
295 //*****************************************************************************\r
296 //\r
297 //! Enables individual SSI interrupt sources.\r
298 //!\r
299 //! \param ulBase specifies the SSI module base address.\r
300 //! \param ulIntFlags is a bit mask of the interrupt sources to be enabled.\r
301 //!\r
302 //! Enables the indicated SSI interrupt sources.  Only the sources that are\r
303 //! enabled can be reflected to the processor interrupt; disabled sources\r
304 //! have no effect on the processor.  The parameter \e ulIntFlags Can be\r
305 //! any of the SSI_TXFF, SSI_RXFF, SSI_RXTO, or SSI_RXOR values.\r
306 //!\r
307 //! \return None.\r
308 //\r
309 //*****************************************************************************\r
310 #if defined(GROUP_intenable) || defined(BUILD_ALL) || defined(DOXYGEN)\r
311 void\r
312 SSIIntEnable(unsigned long ulBase, unsigned long ulIntFlags)\r
313 {\r
314     //\r
315     // Check the arguments.\r
316     //\r
317     ASSERT(ulBase == SSI_BASE);\r
318 \r
319     //\r
320     // Enable the specified interrupts.\r
321     //\r
322     HWREG(ulBase + SSI_O_IM) |= ulIntFlags;\r
323 }\r
324 #endif\r
325 \r
326 //*****************************************************************************\r
327 //\r
328 //! Disables individual SSI interrupt sources.\r
329 //!\r
330 //! \param ulBase specifies the SSI module base address.\r
331 //! \param ulIntFlags is a bit mask of the interrupt sources to be disabled.\r
332 //!\r
333 //! Disables the indicated SSI interrupt sources. The parameter\r
334 //! \e ulIntFlags Can be any of the SSI_TXFF, SSI_RXFF, SSI_RXTO,\r
335 //! or SSI_RXOR values.\r
336 //!\r
337 //! \return None.\r
338 //\r
339 //*****************************************************************************\r
340 #if defined(GROUP_intdisable) || defined(BUILD_ALL) || defined(DOXYGEN)\r
341 void\r
342 SSIIntDisable(unsigned long ulBase, unsigned long ulIntFlags)\r
343 {\r
344     //\r
345     // Check the arguments.\r
346     //\r
347     ASSERT(ulBase == SSI_BASE);\r
348 \r
349     //\r
350     // Disable the specified interrupts.\r
351     //\r
352     HWREG(ulBase + SSI_O_IM) &= ~(ulIntFlags);\r
353 }\r
354 #endif\r
355 \r
356 //*****************************************************************************\r
357 //\r
358 //! Gets the current interrupt status.\r
359 //!\r
360 //! \param ulBase specifies the SSI module base address.\r
361 //! \param bMasked is false if the raw interrupt status is required and\r
362 //! true if the masked interrupt status is required.\r
363 //!\r
364 //! This returns the interrupt status for the SSI module.\r
365 //! Either the raw interrupt status or the status of interrupts that are\r
366 //! allowed to reflect to the processor can be returned.\r
367 //!\r
368 //! \return The current interrupt status, enumerated as a bit field of\r
369 //! SSI_TXFF, SSI_RXFF, SSI_RXTO, and SSI_RXOR.\r
370 //\r
371 //*****************************************************************************\r
372 #if defined(GROUP_intstatus) || defined(BUILD_ALL) || defined(DOXYGEN)\r
373 unsigned long\r
374 SSIIntStatus(unsigned long ulBase, tBoolean bMasked)\r
375 {\r
376     //\r
377     // Check the arguments.\r
378     //\r
379     ASSERT(ulBase == SSI_BASE);\r
380 \r
381     //\r
382     // Return either the interrupt status or the raw interrupt status as\r
383     // requested.\r
384     //\r
385     if(bMasked)\r
386     {\r
387         return(HWREG(ulBase + SSI_O_MIS));\r
388     }\r
389     else\r
390     {\r
391         return(HWREG(ulBase + SSI_O_RIS));\r
392     }\r
393 }\r
394 #endif\r
395 \r
396 //*****************************************************************************\r
397 //\r
398 //! Clears SSI interrupt sources.\r
399 //!\r
400 //! \param ulBase specifies the SSI module base address.\r
401 //! \param ulIntFlags is a bit mask of the interrupt sources to be cleared.\r
402 //!\r
403 //! The specified SSI interrupt sources are cleared, so that\r
404 //! they no longer assert.  This must be done in the interrupt handler to\r
405 //! keep it from being called again immediately upon exit.\r
406 //! The parameter \e ulIntFlags can consist of either or both the SSI_RXTO\r
407 //! and SSI_RXOR values.\r
408 //!\r
409 //! \return None.\r
410 //\r
411 //*****************************************************************************\r
412 #if defined(GROUP_intclear) || defined(BUILD_ALL) || defined(DOXYGEN)\r
413 void\r
414 SSIIntClear(unsigned long ulBase, unsigned long ulIntFlags)\r
415 {\r
416     //\r
417     // Check the arguments.\r
418     //\r
419     ASSERT(ulBase == SSI_BASE);\r
420 \r
421     //\r
422     // Clear the requested interrupt sources.\r
423     //\r
424     HWREG(ulBase + SSI_O_ICR) = ulIntFlags;\r
425 }\r
426 #endif\r
427 \r
428 //*****************************************************************************\r
429 //\r
430 //! Puts a data element into the SSI transmit FIFO.\r
431 //!\r
432 //! \param ulBase specifies the SSI module base address.\r
433 //! \param ulData data to be transmitted over the SSI interface.\r
434 //!\r
435 //! This function will place the supplied data into the transmit FIFO of\r
436 //! the specified SSI module.\r
437 //!\r
438 //! \note The upper 32 - N bits of the \e ulData will be discarded by the\r
439 //! hardware, where N is the data width as configured by SSIConfig().  For\r
440 //! example, if the interface is configured for 8 bit data width, the upper 24\r
441 //! bits of \e ulData will be discarded.\r
442 //!\r
443 //! \return None.\r
444 //\r
445 //*****************************************************************************\r
446 #if defined(GROUP_dataput) || defined(BUILD_ALL) || defined(DOXYGEN)\r
447 void\r
448 SSIDataPut(unsigned long ulBase, unsigned long ulData)\r
449 {\r
450     //\r
451     // Check the arguments.\r
452     //\r
453     ASSERT(ulBase == SSI_BASE);\r
454     ASSERT((ulData & (0xfffffffe << (HWREG(ulBase + SSI_O_CR0) &\r
455                                      SSI_CR0_DSS))) == 0);\r
456 \r
457     //\r
458     // Wait until there is space.\r
459     //\r
460     while(!(HWREG(ulBase + SSI_O_SR) & SSI_SR_TNF))\r
461     {\r
462     }\r
463 \r
464     //\r
465     // Write the data to the SSI.\r
466     //\r
467     HWREG(ulBase + SSI_O_DR) = ulData;\r
468 }\r
469 #endif\r
470 \r
471 //*****************************************************************************\r
472 //\r
473 //! Puts a data element into the SSI transmit FIFO.\r
474 //!\r
475 //! \param ulBase specifies the SSI module base address.\r
476 //! \param ulData data to be transmitted over the SSI interface.\r
477 //!\r
478 //! This function will place the supplied data into the transmit FIFO of\r
479 //! the specified SSI module. If there is no space in the FIFO, then this\r
480 //! function will return a zero.\r
481 //!\r
482 //! \note The upper 32 - N bits of the \e ulData will be discarded by the\r
483 //! hardware, where N is the data width as configured by SSIConfig().  For\r
484 //! example, if the interface is configured for 8 bit data width, the upper 24\r
485 //! bits of \e ulData will be discarded.\r
486 //!\r
487 //! \return Returns the number of elements written to the SSI transmit FIFO.\r
488 //\r
489 //*****************************************************************************\r
490 #if defined(GROUP_datanonblockingput) || defined(BUILD_ALL) || defined(DOXYGEN)\r
491 long\r
492 SSIDataNonBlockingPut(unsigned long ulBase, unsigned long ulData)\r
493 {\r
494     //\r
495     // Check the arguments.\r
496     //\r
497     ASSERT(ulBase == SSI_BASE);\r
498     ASSERT((ulData & (0xfffffffe << (HWREG(ulBase + SSI_O_CR0) &\r
499                                      SSI_CR0_DSS))) == 0);\r
500 \r
501     //\r
502     // Check for space to write.\r
503     //\r
504     if(HWREG(ulBase + SSI_O_SR) & SSI_SR_TNF)\r
505     {\r
506         HWREG(ulBase + SSI_O_DR) = ulData;\r
507         return(1);\r
508     }\r
509     else\r
510     {\r
511         return(0);\r
512     }\r
513 }\r
514 #endif\r
515 \r
516 //*****************************************************************************\r
517 //\r
518 //! Gets a data element from the SSI receive FIFO.\r
519 //!\r
520 //! \param ulBase specifies the SSI module base address.\r
521 //! \param pulData pointer to a storage location for data that was received\r
522 //! over the SSI interface.\r
523 //!\r
524 //! This function will get received data from the receive FIFO of the specified\r
525 //! SSI module, and place that data into the location specified by the\r
526 //! \e pulData parameter.\r
527 //!\r
528 //! \note Only the lower N bits of the value written to \e pulData will contain\r
529 //! valid data, where N is the data width as configured by SSIConfig().  For\r
530 //! example, if the interface is configured for 8 bit data width, only the\r
531 //! lower 8 bits of the value written to \e pulData will contain valid data.\r
532 //!\r
533 //! \return None.\r
534 //\r
535 //*****************************************************************************\r
536 #if defined(GROUP_dataget) || defined(BUILD_ALL) || defined(DOXYGEN)\r
537 void\r
538 SSIDataGet(unsigned long ulBase, unsigned long *pulData)\r
539 {\r
540     //\r
541     // Check the arguments.\r
542     //\r
543     ASSERT(ulBase == SSI_BASE);\r
544 \r
545     //\r
546     // Wait until there is data to be read.\r
547     //\r
548     while(!(HWREG(ulBase + SSI_O_SR) & SSI_SR_RNE))\r
549     {\r
550     }\r
551 \r
552     //\r
553     // Read data from SSI.\r
554     //\r
555     *pulData = HWREG(ulBase + SSI_O_DR);\r
556 }\r
557 #endif\r
558 \r
559 //*****************************************************************************\r
560 //\r
561 //! Gets a data element from the SSI receive FIFO.\r
562 //!\r
563 //! \param ulBase specifies the SSI module base address.\r
564 //! \param pulData pointer to a storage location for data that was received\r
565 //! over the SSI interface.\r
566 //!\r
567 //! This function will get received data from the receive FIFO of\r
568 //! the specified SSI module, and place that data into the location specified\r
569 //! by the \e ulData parameter. If there is no data in the FIFO, then this\r
570 //! function will return a zero.\r
571 //!\r
572 //! \note Only the lower N bits of the value written to \e pulData will contain\r
573 //! valid data, where N is the data width as configured by SSIConfig().  For\r
574 //! example, if the interface is configured for 8 bit data width, only the\r
575 //! lower 8 bits of the value written to \e pulData will contain valid data.\r
576 //!\r
577 //! \return Returns the number of elements read from the SSI receive FIFO.\r
578 //\r
579 //*****************************************************************************\r
580 #if defined(GROUP_datanonblockingget) || defined(BUILD_ALL) || defined(DOXYGEN)\r
581 long\r
582 SSIDataNonBlockingGet(unsigned long ulBase, unsigned long *pulData)\r
583\r
584    //\r
585     // Check the arguments.\r
586     //\r
587     ASSERT(ulBase == SSI_BASE);\r
588 \r
589     //\r
590     // Check for data to read.\r
591     //\r
592     if(HWREG(ulBase + SSI_O_SR) & SSI_SR_RNE)\r
593     {\r
594         *pulData = HWREG(ulBase + SSI_O_DR);\r
595         return(1);\r
596     }\r
597     else\r
598     {\r
599         return(0);\r
600     }\r
601 }\r
602 #endif\r
603 \r
604 //*****************************************************************************\r
605 //\r
606 // Close the Doxygen group.\r
607 //! @}\r
608 //\r
609 //*****************************************************************************\r