Fix reference to README.devlib in header.
[bertos.git] / drv / buzzerled_dsp56k.h
1 /*!
2  * \file
3  * <!--
4  * Copyright 2004 Develer S.r.l. (http://www.develer.com/)
5  * Copyright 2004 Giovanni Bajo
6  * This file is part of DevLib - See README.devlib for information.
7  * -->
8  *
9  * \brief Hardware support for buzzers and leds in DSP56K-based boards
10  *
11  * \version $Id$
12  *
13  * \author Giovanni Bajo <rasky@develer.com>
14  */
15
16 /*#*
17  *#* $Log$
18  *#* Revision 1.6  2005/11/04 16:20:02  bernie
19  *#* Fix reference to README.devlib in header.
20  *#*
21  *#* Revision 1.5  2005/04/11 19:10:27  bernie
22  *#* Include top-level headers from cfg/ subdir.
23  *#*
24  *#* Revision 1.4  2004/11/16 21:54:43  bernie
25  *#* Changes for SC Monoboard support.
26  *#*
27  *#* Revision 1.3  2004/08/25 14:12:08  rasky
28  *#* Aggiornato il comment block dei log RCS
29  *#*
30  *#* Revision 1.2  2004/06/03 11:27:09  bernie
31  *#* Add dual-license information.
32  *#*
33  *#* Revision 1.1  2004/05/23 18:36:05  bernie
34  *#* Import buzzerled driver.
35  *#*
36  *#*/
37
38 #ifndef DRV_BUZZERLED_DSP56K_H
39 #define DRV_BUZZERLED_DSP56K_H
40
41 #include <cfg/compiler.h>
42 #include <hw.h>
43 #include "pwm.h"
44
45 #if ARCH & ARCH_HECO
46
47 /*!
48  * \name Connection of the leds to the DSP:
49  * <pre>
50  *   Led       Line    DSP Pin
51  *   ---------------------------
52  *   YELLOW    T2      HOME1/TB3
53  *   GREEN     T3      INDX1/TB2
54  *   RED       T4      PHB1/TB1
55  * </pre>
56  */
57
58 INLINE bool bld_is_inverted_intensity(enum BLD_DEVICE device)
59 {
60         return (device == BLD_GREEN_LED
61                 || device == BLD_YELLOW_LED
62                 || device == BLD_RED_LED);
63 }
64
65 INLINE bool bld_is_pwm(enum BLD_DEVICE device)
66 {
67         // Only the buzzer is connected to a PWM
68         return (device == BLD_BUZZER || device == BLD_READY_LED);
69 }
70
71 INLINE bool bld_is_timer(enum BLD_DEVICE device)
72 {
73         // LEDs are connected to timers
74         return (device == BLD_GREEN_LED || device == BLD_YELLOW_LED || device == BLD_RED_LED);
75 }
76
77 INLINE uint16_t bld_get_pwm(enum BLD_DEVICE device)
78 {
79         switch (device)
80         {
81         default: ASSERT(0);
82         case BLD_BUZZER: return 5;  // PWMA5
83         case BLD_READY_LED:  return 9;   // PWMB3
84         }
85 }
86
87
88 INLINE struct REG_TIMER_STRUCT* bld_get_timer(enum BLD_DEVICE device)
89 {
90         switch (device)
91         {
92         default: ASSERT(0);
93         case BLD_GREEN_LED: return &REG_TIMER_B[2];
94         case BLD_RED_LED: return &REG_TIMER_B[1];
95         case BLD_YELLOW_LED: return &REG_TIMER_B[3];
96         }
97 }
98
99 INLINE void bld_hw_init(void)
100 {
101 }
102
103 INLINE void bld_hw_set(enum BLD_DEVICE device, bool enable)
104 {
105         if (bld_is_inverted_intensity(device))
106                 enable = !enable;
107
108         // Handle a BLD connected to a PWM
109         if (bld_is_pwm(device))
110         {
111                 struct PWM* pwm = pwm_get_handle(bld_get_pwm(device));
112
113                 pwm_set_enable(pwm, false);
114                 pwm_set_dutycycle_percent(pwm, (enable ? 50 : 0));
115                 pwm_set_enable(pwm, true);
116         }
117         else if (bld_is_timer(device))
118         {
119                 struct REG_TIMER_STRUCT* timer = bld_get_timer(device);
120
121                 // Check that the timer is currently stopped, and the OFLAG is not
122                 //  controlled by another timer. Otherwise, the led is already 
123                 //  controlled by the timer, and we cannot correctly set it 
124                 //  on/off without reprogramming the timer.
125                 ASSERT((timer->CTRL & REG_TIMER_CTRL_MODE_MASK) == REG_TIMER_CTRL_MODE_STOP);
126                 ASSERT(!(timer->SCR & REG_TIMER_SCR_EEOF));
127
128                 // Check also that polarity is correct
129                 ASSERT(!(timer->SCR & REG_TIMER_SCR_OPS));
130
131                 // Without programming the timer, we have a way to manually force a certain
132                 //  value on the external pin. We also need to enable the output pin.
133                 timer->SCR &= ~REG_TIMER_SCR_VAL_1;
134                 timer->SCR |= REG_TIMER_SCR_OEN |
135                               REG_TIMER_SCR_FORCE |
136                               (!enable ? REG_TIMER_SCR_VAL_0 : REG_TIMER_SCR_VAL_1);
137         }
138         else
139                 ASSERT(0);
140 }
141
142 #elif ARCH & ARCH_SC
143
144 // We do not need inline functions here, because constant propagation is not big deal here
145 void bld_hw_init(void);
146 void bld_hw_set(enum BLD_DEVICE device, bool enable);
147
148 #endif
149
150 #endif /* DRV_BUZZERLED_DSP56K_H */