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