1 //*****************************************************************************
2 //
3 // fan.c - Driver for the FAN controller.
4 //
5 // Copyright (c) 2010-2011 Texas Instruments Incorporated. All rights reserved.
6 // Software License Agreement
7 //
8 // Texas Instruments (TI) is supplying this software for use solely and
9 // exclusively on TI's microcontroller products. The software is owned by
10 // TI and/or its suppliers, and is protected under applicable copyright
11 // laws. You may not combine this software with "viral" open-source
12 // software in order to form a larger program.
13 //
14 // THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
15 // NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
16 // NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
17 // A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
18 // CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
19 // DAMAGES, FOR ANY REASON WHATSOEVER.
20 //
21 // This is part of revision 8264 of the Stellaris Peripheral Driver Library.
22 //
23 //*****************************************************************************
24
25 #include "inc/hw_types.h"
26 #include "inc/hw_memmap.h"
27 #include "inc/hw_fan.h"
28 #include "inc/hw_ints.h"
29 #include "driverlib/fan.h"
30 #include "driverlib/debug.h"
31 #include "driverlib/interrupt.h"
32
33 //*****************************************************************************
34 //
35 //! \addtogroup fan_api
36 //! @{
37 //
38 //*****************************************************************************
39
40 //*****************************************************************************
41 //
42 //! Enables a FAN channel for operation.
43 //!
44 //! \param ulBase is the base address of the FAN module.
45 //! \param ulChannel is the FAN channel to enable.
46 //!
47 //! This function enables the specified FAN channel for operation.
48 //!
49 //! \return None.
50 //
51 //*****************************************************************************
52 void
FanChannelEnable(unsigned long ulBase,unsigned long ulChannel)53 FanChannelEnable(unsigned long ulBase, unsigned long ulChannel)
54 {
55 //
56 // Check the arguments.
57 //
58 ASSERT(ulBase == FAN0_BASE);
59 ASSERT(ulChannel <= 5);
60
61 //
62 // Enable the requested channel
63 //
64 HWREG(ulBase + FAN_O_CTL) |= 1 << ulChannel;
65 }
66
67 //*****************************************************************************
68 //
69 //! Disables a FAN channel for operation.
70 //!
71 //! \param ulBase is the base address of the FAN module.
72 //! \param ulChannel is the FAN channel to disable.
73 //!
74 //! This function disables the specified FAN channel for operation.
75 //!
76 //! \return None.
77 //
78 //*****************************************************************************
79 void
FanChannelDisable(unsigned long ulBase,unsigned long ulChannel)80 FanChannelDisable(unsigned long ulBase, unsigned long ulChannel)
81 {
82 //
83 // Check the arguments.
84 //
85 ASSERT(ulBase == FAN0_BASE);
86 ASSERT(ulChannel <= 5);
87
88 //
89 // Disable the requested channel
90 //
91 HWREG(ulBase + FAN_O_CTL) &= ~(1 << ulChannel);
92 }
93
94 //*****************************************************************************
95 //
96 //! Gets the status of a FAN channel.
97 //!
98 //! \param ulBase is the base address of the FAN module.
99 //! \param ulChannel is the FAN channel to query for status.
100 //!
101 //! This function queries and returns the status of the specified channel.
102 //! The returned value is one of:
103 //!
104 //! - \b FAN_STATUS_STALLED if the cooling fan is stalled
105 //! - \b FAN_STATUS_CHANGING if the fan is changing to the commanded speed
106 //! - \b FAN_STATUS_LOCKED if the fan is locked at the commanded speed
107 //! - \b FAN_STATUS_NOATTAIN if the fan cannot achieve the commanded speed
108 //!
109 //! \return Returns the status of the specified FAN channel.
110 //
111 //*****************************************************************************
112 unsigned long
FanChannelStatus(unsigned long ulBase,unsigned long ulChannel)113 FanChannelStatus(unsigned long ulBase, unsigned long ulChannel)
114 {
115 //
116 // Check the arguments.
117 //
118 ASSERT(ulBase == FAN0_BASE);
119 ASSERT(ulChannel <= 5);
120
121 //
122 // Read and return the status for the specified fan channel
123 //
124 return((HWREG(ulBase + FAN_O_STS) >> (ulChannel * 2)) & FAN_STS_ST0_M);
125 }
126
127 //*****************************************************************************
128 //
129 //! Configures a FAN channel for manual operation.
130 //!
131 //! \param ulBase is the base address of the FAN module.
132 //! \param ulChannel is the FAN channel to configure.
133 //! \param ulConfig is the logical OR of manual configuration flags.
134 //!
135 //! This function configures a specific FAN channel to operate in manual
136 //! mode. The \e ulConfig parameter is the logical OR of several choices of
137 //! configuration flags as follows:
138 //!
139 //! One of the following to select the number of tachometer pulses used for
140 //! speed averaging:
141 //!
142 //! - \b FAN_CONFIG_AVG_NONE to disable fan speed averaging
143 //! - \b FAN_CONFIG_AVG_2 to select 2 pulses for speed averaging
144 //! - \b FAN_CONFIG_AVG_4 to select 4 pulses for speed averaging
145 //! - \b FAN_CONFIG_AVG_8 to select 8 pulses for speed averaging
146 //!
147 //! One of the following to select the tachometer pulses per revolution:
148 //!
149 //! - \b FAN_CONFIG_TACH_1 to select 1 pulse per revolution
150 //! - \b FAN_CONFIG_TACH_2 to select 2 pulses per revolution
151 //! - \b FAN_CONFIG_TACH_4 to select 4 pulses per revolution
152 //! - \b FAN_CONFIG_TACH_8 to select 8 pulses per revolution
153 //!
154 //! \return None.
155 //
156 //*****************************************************************************
157 void
FanChannelConfigManual(unsigned long ulBase,unsigned long ulChannel,unsigned long ulConfig)158 FanChannelConfigManual(unsigned long ulBase, unsigned long ulChannel,
159 unsigned long ulConfig)
160 {
161 //
162 // Check the arguments.
163 //
164 ASSERT(ulBase == FAN0_BASE);
165 ASSERT(ulChannel <= 5);
166
167 //
168 // Program the fan channel for manual mode with parameters.
169 //
170 HWREG(ulBase + FAN_O_CH0 + (ulChannel * 0x10)) = FAN_CH0_MAN | ulConfig;
171 }
172
173 //*****************************************************************************
174 //
175 //! Configures a FAN channel for automatic operation.
176 //!
177 //! \param ulBase is the base address of the FAN module.
178 //! \param ulChannel is the FAN channel to configure.
179 //! \param ulConfig is the logical OR of configuration flags.
180 //!
181 //! This function configures a specific FAN channel to operate in automatic
182 //! mode. The \e ulConfig parameter is the logical OR of several choices of
183 //! configuration flags as follows:
184 //!
185 //! One of the following to select the automatic restart mode:
186 //!
187 //! - \b FAN_CONFIG_RESTART to enable automatic restart after stall
188 //! - \b FAN_CONFIG_NORESTART to disable automatic restart after stall
189 //!
190 //! One of the following to select the acceleration rate when changing speed:
191 //!
192 //! - \b FAN_CONFIG_ACCEL_FAST to select fast acceleration
193 //! - \b FAN_CONFIG_ACCEL_SLOW to select slow acceleration
194 //!
195 //! One of the following to select the number of tachometer pulses to use
196 //! for the hysteresis count:
197 //! \b FAN_CONFIG_HYST_1, \b FAN_CONFIG_HYST_2, \b FAN_CONFIG_HYST_4,
198 //! \b FAN_CONFIG_HYST_8, \b FAN_CONFIG_HYST_16, \b FAN_CONFIG_HYST_32,
199 //! \b FAN_CONFIG_HYST_64, or \b FAN_CONFIG_HYST_128
200 //!
201 //! One of the following to select the start period as the number of tachometer
202 //! pulses. The start period is the amount of time that a starting PWM duty
203 //! cycle is used after the FAN channel is commended to a certain speed:
204 //! \b FAN_CONFIG_START_2, \b FAN_CONFIG_START_4, \b FAN_CONFIG_START_8,
205 //! \b FAN_CONFIG_START_16, \b FAN_CONFIG_START_32, \b FAN_CONFIG_START_64,
206 //! \b FAN_CONFIG_START_128, or \b FAN_CONFIG_START_256
207 //!
208 //! One of the following to specify the duty cycle that is used when the FAN
209 //! channel is starting, during the starting period (above):
210 //!
211 //! - \b FAN_CONFIG_START_DUTY_OFF to disable the use of startup duty cycle
212 //! - \b FAN_CONFIG_START_DUTY_50 to select 50% startup duty cycle
213 //! - \b FAN_CONFIG_START_DUTY_75 to select 75% startup duty cycle
214 //! - \b FAN_CONFIG_START_DUTY_100 to select 100% startup duty cycle
215 //!
216 //! One of the following to select the number of tachometer pulses used for
217 //! speed averaging:
218 //!
219 //! - \b FAN_CONFIG_AVG_NONE to disable fan speed averaging
220 //! - \b FAN_CONFIG_AVG_2 to select 2 pulses for speed averaging
221 //! - \b FAN_CONFIG_AVG_4 to select 4 pulses for speed averaging
222 //! - \b FAN_CONFIG_AVG_8 to select 8 pulses for speed averaging
223 //!
224 //! One of the following to select the tachometer pulses per revolution:
225 //!
226 //! - \b FAN_CONFIG_TACH_1 to select 1 pulse per revolution
227 //! - \b FAN_CONFIG_TACH_2 to select 2 pulses per revolution
228 //! - \b FAN_CONFIG_TACH_4 to select 4 pulses per revolution
229 //! - \b FAN_CONFIG_TACH_8 to select 8 pulses per revolution
230 //!
231 //! \return None.
232 //
233 //*****************************************************************************
234 void
FanChannelConfigAuto(unsigned long ulBase,unsigned long ulChannel,unsigned long ulConfig)235 FanChannelConfigAuto(unsigned long ulBase, unsigned long ulChannel,
236 unsigned long ulConfig)
237 {
238 //
239 // Check the arguments.
240 //
241 ASSERT(ulBase == FAN0_BASE);
242 ASSERT(ulChannel <= 5);
243
244 //
245 // Program the fan channel for automatic mode with parameters.
246 //
247 HWREG(ulBase + FAN_O_CH0 + (ulChannel * 0x10)) = ~FAN_CH0_MAN & ulConfig;
248 }
249
250 //*****************************************************************************
251 //
252 //! Sets the duty cycle of a FAN channel when in manual mode.
253 //!
254 //! \param ulBase is the base address of the FAN module.
255 //! \param ulChannel is the FAN channel to program the duty cycle.
256 //! \param ulDuty is the duty cycle in clocks from 0-511.
257 //!
258 //! This function sets the duty cycle of a FAN channel if the channel is
259 //! configured for manual mode. The duty cycle is specified in clocks from
260 //! 0-511 out of a 512 clock PWM period.
261 //!
262 //! \return None.
263 //
264 //*****************************************************************************
265 void
FanChannelDutySet(unsigned long ulBase,unsigned long ulChannel,unsigned long ulDuty)266 FanChannelDutySet(unsigned long ulBase, unsigned long ulChannel,
267 unsigned long ulDuty)
268 {
269 //
270 // Check the arguments.
271 //
272 ASSERT(ulBase == FAN0_BASE);
273 ASSERT(ulChannel <= 5);
274 ASSERT(ulDuty < 512);
275
276 //
277 // Program the specified duty cycle for the specified channel
278 //
279 HWREG(ulBase + FAN_O_CMD0 + (ulChannel * 0x10)) =
280 (ulDuty << FAN_CMD0_DC_S) & FAN_CMD0_DC_M;
281 }
282
283 //*****************************************************************************
284 //
285 //! Reads the duty cycle of a FAN channel.
286 //!
287 //! \param ulBase is the base address of the FAN module.
288 //! \param ulChannel is the FAN channel to query for duty cycle.
289 //!
290 //! This function gets the duty cycle of a FAN channel. If the channel is in
291 //! manual mode, then this is the value that was programmed. If the FAN
292 //! channel is configured for automatic mode, then this is the value that is
293 //! calculated by the Fan Control peripheral.
294 //!
295 //! \return Returns the FAN channel duty cycle as a number of clocks from
296 //! 0-511, out of a 512 clock PWM period.
297 //
298 //*****************************************************************************
299 unsigned long
FanChannelDutyGet(unsigned long ulBase,unsigned long ulChannel)300 FanChannelDutyGet(unsigned long ulBase, unsigned long ulChannel)
301 {
302 unsigned long ulDuty;
303
304 //
305 // Check the arguments.
306 //
307 ASSERT(ulBase == FAN0_BASE);
308 ASSERT(ulChannel <= 5);
309
310 //
311 // Read the duty cycle field from the command register and shift to
312 // lower bits for return value.
313 //
314 ulDuty = HWREG(ulBase + FAN_O_CMD0 + (ulChannel * 0x10)) & FAN_CMD0_DC_M;
315 ulDuty >>= FAN_CMD0_DC_S;
316
317 //
318 // Return the duty cycle for the specified channel.
319 //
320 return(ulDuty);
321 }
322
323 //*****************************************************************************
324 //
325 //! Sets the RPM of a FAN channel when in automatic mode.
326 //!
327 //! \param ulBase is the base address of the FAN module.
328 //! \param ulChannel is the FAN channel to program the RPM.
329 //! \param ulRPM is the RPM as a value from 0-8191.
330 //!
331 //! This function sets the RPM of the fan channel if the fan channel is
332 //! configured for automatic mode. If configured for manual mode, then this
333 //! function has no effect.
334 //!
335 //! \return None.
336 //
337 //*****************************************************************************
338 void
FanChannelRPMSet(unsigned long ulBase,unsigned long ulChannel,unsigned long ulRPM)339 FanChannelRPMSet(unsigned long ulBase, unsigned long ulChannel,
340 unsigned long ulRPM)
341 {
342 //
343 // Check the arguments.
344 //
345 ASSERT(ulBase == FAN0_BASE);
346 ASSERT(ulChannel <= 5);
347 ASSERT(ulRPM < 8192);
348
349 //
350 // Program the specified RPM for the specified channel
351 //
352 HWREG(ulBase + FAN_O_CMD0 + (ulChannel * 0x10)) = ulRPM;
353 }
354
355 //*****************************************************************************
356 //
357 //! Reads the RPM of a FAN channel.
358 //!
359 //! \param ulBase is the base address of the FAN module.
360 //! \param ulChannel is the FAN channel to query for RPM.
361 //!
362 //! This function gets the RPM of a FAN channel.
363 //!
364 //! \return Returns the FAN channel RPM as a number from 0-4095.
365 //
366 //*****************************************************************************
367 unsigned long
FanChannelRPMGet(unsigned long ulBase,unsigned long ulChannel)368 FanChannelRPMGet(unsigned long ulBase, unsigned long ulChannel)
369 {
370 //
371 // Check the arguments.
372 //
373 ASSERT(ulBase == FAN0_BASE);
374 ASSERT(ulChannel <= 5);
375
376 //
377 // Read and return the RPM for the specified channel.
378 //
379 return(HWREG(ulBase + FAN_O_CST0 + (ulChannel * 0x10)) & FAN_CST0_RPM_M);
380 }
381
382 //*****************************************************************************
383 //
384 //! Enables FAN module interrupts.
385 //!
386 //! \param ulBase is the base address of the FAN module.
387 //! \param ulFlags is the logical OR of all the interrupts to be enabled.
388 //!
389 //! This function enables one or more interrupts from the FAN module. The
390 //! \e ulFlags parameter is the logical OR of all the possible interrupts that
391 //! can be enabled. For each channel, the following interrupt flags are
392 //! available:
393 //!
394 //! - \b FAN_CHn_INT_STALL means that a stall was detected (in either mode).
395 //! - \b FAN_CHn_INT_AUTO_SPEED_ERROR means that in automatic mode, the cooling
396 //! fan cannot attain the commanded speed.
397 //! - \b FAN_CHn_INT_AUTO_SPEED_OK means that in automatic mode, the cooling
398 //! fan has attained the commanded speed.
399 //!
400 //! In the above flag names, the \b CHn placeholder should be replaced with
401 //! the actual channel number, 0-5 (for example, CH1).
402 //!
403 //! The interrupt flags have a different meaning if the FAN channel is
404 //! configured for manual mode. The following alternate set of flag names is
405 //! available for convenience to use in manual mode:
406 //!
407 //! - \b FAN_CHn_INT_MANUAL_SPEED_UPDATE means that in manual mode, the speed
408 //! was calculated.
409 //! - \b FAN_CHn_INT_MANUAL_SPEED_CHANGE means that in manual mode, the speed
410 //! changed.
411 //!
412 //! Note that even though the names are different for manual mode, the values
413 //! are the same. For example \b _AUTO_SPEED_ERROR is the same value as
414 //! \b _MANUAL_SPEED_UPDATE. The different names are provided just to make it
415 //! easier to associate a meaning with each interrupt flag.
416 //!
417 //! \return None.
418 //
419 //*****************************************************************************
420 void
FanIntEnable(unsigned long ulBase,unsigned long ulFlags)421 FanIntEnable(unsigned long ulBase, unsigned long ulFlags)
422 {
423 //
424 // Check the arguments.
425 //
426 ASSERT(ulBase == FAN0_BASE);
427
428 //
429 // Enable the requested interrupt sources.
430 //
431 HWREG(ulBase + FAN_O_IM) |= ulFlags;
432 }
433
434 //*****************************************************************************
435 //
436 //! Disables FAN module interrupts.
437 //!
438 //! \param ulBase is the base address of the FAN module.
439 //! \param ulFlags is the logical OR of all the interrupts to be disabled.
440 //!
441 //! This function disables one or more interrupts from the FAN module. The
442 //! \e ulFlags parameter is the logical OR of all the possible interrupts that
443 //! can be enabled. For a list of possible interrupt flags, refer to the
444 //! documentation for the function FanIntEnable().
445 //!
446 //! \return None.
447 //
448 //*****************************************************************************
449 void
FanIntDisable(unsigned long ulBase,unsigned long ulFlags)450 FanIntDisable(unsigned long ulBase, unsigned long ulFlags)
451 {
452 //
453 // Check the arguments.
454 //
455 ASSERT(ulBase == FAN0_BASE);
456
457 //
458 // Disable the requested interrupt sources.
459 //
460 HWREG(ulBase + FAN_O_IM) &= ~ulFlags;
461 }
462
463 //*****************************************************************************
464 //
465 //! Gets the FAN module interrupt status.
466 //!
467 //! \param ulBase is the base address of the FAN module.
468 //! \param bMasked is set \b true to get the masked interrupt status, or
469 //! \b false to get the raw interrupt status.
470 //!
471 //! This function returns the interrupt status of the FAN module. It can
472 //! return either the raw or masked interrupt status.
473 //!
474 //! \return Returns the masked or raw FAN interrupt status, as a bit field
475 //! of multiple FAN interrupt flags. For a list of all the possible interrupt
476 //! flags, refer to the documentation for the function FanIntEnable().
477 //
478 //*****************************************************************************
479 unsigned long
FanIntStatus(unsigned long ulBase,tBoolean bMasked)480 FanIntStatus(unsigned long ulBase, tBoolean bMasked)
481 {
482 //
483 // Check the arguments.
484 //
485 ASSERT(ulBase == FAN0_BASE);
486
487 //
488 // Return either the interrupt status or the raw interrupt status as
489 // requested.
490 //
491 if(bMasked)
492 {
493 return(HWREG(ulBase + FAN_O_MIS));
494 }
495 else
496 {
497 return(HWREG(ulBase + FAN_O_RIS));
498 }
499 }
500
501 //*****************************************************************************
502 //
503 //! Clears pending FAN module interrupts.
504 //!
505 //! \param ulBase is the base address of the FAN module.
506 //! \param ulFlags is the logical OR of all the interrupts to be cleared.
507 //!
508 //! This function clears one or more interrupts from the FAN module. The
509 //! \e ulFlags parameter is the logical OR of all the possible interrupts that
510 //! can be cleared. For a list of possible interrupt flags, refer to the
511 //! documentation for the function FanIntEnable().
512 //!
513 //! \return None.
514 //
515 //*****************************************************************************
516 void
FanIntClear(unsigned long ulBase,unsigned long ulFlags)517 FanIntClear(unsigned long ulBase, unsigned long ulFlags)
518 {
519 //
520 // Check the arguments.
521 //
522 ASSERT(ulBase == FAN0_BASE);
523
524 //
525 // Clear the requested pending interrupts
526 //
527 HWREG(ulBase + FAN_O_IC) = ulFlags;
528 }
529
530 //*****************************************************************************
531 //
532 //! Registers an interrupt handler for the FAN module.
533 //!
534 //! \param ulBase is the base address of the FAN module.
535 //! \param pfnHandler is a pointer to the function to be called when the
536 //! interrupt is activated.
537 //!
538 //! This function sets and enables the handler to be called when the FAN module
539 //! generates an interrupt. Specific FAN interrupts must still be enabled
540 //! with the FanIntEnable() function.
541 //!
542 //! \sa IntRegister() for important information about registering interrupt
543 //! handlers.
544 //!
545 //! \return None.
546 //
547 //*****************************************************************************
548 void
FanIntRegister(unsigned long ulBase,void (* pfnHandler)(void))549 FanIntRegister(unsigned long ulBase, void (*pfnHandler)(void))
550 {
551 //
552 // Check the arguments.
553 //
554 ASSERT(ulBase == FAN0_BASE);
555 ASSERT(pfnHandler);
556
557 //
558 // Register the interrupt handler.
559 //
560 IntRegister(INT_FAN0, pfnHandler);
561
562 //
563 // Enable the FAN peripheral interrupt.
564 //
565 IntEnable(INT_FAN0);
566 }
567
568 //*****************************************************************************
569 //
570 //! Unregisters an interrupt handler for the FAN module.
571 //!
572 //! \param ulBase is the base address of the FAN module.
573 //!
574 //! This function disables and clears the handler to be called when the
575 //! FAN module interrupt occurs.
576 //!
577 //! \sa IntRegister() for important information about registering interrupt
578 //! handlers.
579 //!
580 //! \return None.
581 //
582 //*****************************************************************************
583 void
FanIntUnregister(unsigned long ulBase)584 FanIntUnregister(unsigned long ulBase)
585 {
586 //
587 // Check the arguments.
588 //
589 ASSERT(ulBase == FAN0_BASE);
590
591 //
592 // Disable the FAN peripheral interrupt.
593 //
594 IntDisable(INT_FAN0);
595
596 //
597 // Unregister the interrupt handler.
598 //
599 IntUnregister(INT_FAN0);
600 }
601
602 //*****************************************************************************
603 //
604 //! Gets the number of supported FAN channels.
605 //!
606 //! \param ulBase is the base address of the FAN module.
607 //!
608 //! This function gets the number of FAN channels that are supported by the
609 //! Fan Control peripheral.
610 //!
611 //! \return Returns the number of FAN channels.
612 //
613 //*****************************************************************************
614 unsigned long
FanChannelsGet(unsigned long ulBase)615 FanChannelsGet(unsigned long ulBase)
616 {
617 //
618 // Check the arguments.
619 //
620 ASSERT(ulBase == FAN0_BASE);
621
622 //
623 // Read and return the fan channel count
624 //
625 return(HWREG(ulBase + FAN_O_PP) & FAN_PP_CHAN_M);
626 }
627
628 //*****************************************************************************
629 //
630 // Close the Doxygen group.
631 //! @}
632 //
633 //*****************************************************************************
634