Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Jan Kasprzak
tinyboard
Commits
e207868d
Commit
e207868d
authored
Apr 29, 2013
by
Jan Kasprzak
Browse files
pwmled.c: only one pwmled
parent
8ebf32f3
Changes
3
Hide whitespace changes
Inline
Side-by-side
projects/step-up/adc.c
View file @
e207868d
...
...
@@ -202,7 +202,7 @@ ISR(ADC_vect) { // IRQ handler
switch
(
current_adc
)
{
case
0
:
// pwmled_adc(current_adc, adc_sum);
pwmled_adc
(
1
,
adc_sum
);
pwmled_adc
(
adc_sum
);
break
;
}
...
...
projects/step-up/lights.h
View file @
e207868d
...
...
@@ -44,8 +44,8 @@ void susp_tmr();
/* pwmled.c */
void
init_pwmled
();
void
pwmled_adc
(
unsigned
char
n
,
uint16_t
adcval
);
void
pwmled_set_mode
(
unsigned
char
n
,
unsigned
char
mode
);
void
pwmled_adc
(
uint16_t
adcval
);
void
pwmled_set_mode
(
unsigned
char
mode
);
/* gpio.c */
void
init_gpio
();
...
...
projects/step-up/pwmled.c
View file @
e207868d
...
...
@@ -2,18 +2,11 @@
#include
"lights.h"
typedef
struct
{
uint16_t
target
,
pwm
;
int16_t
err_sum
;
unsigned
char
mode
,
state
;
union
{
unsigned
char
probe_steady
,
mode_changed
;
};
uint16_t
mode_pwm
[
N_PWMLED_MODES
];
int16_t
err_sums
[
N_PWMLED_MODES
];
}
pwmled_t
;
pwmled_t
pwmleds
[
N_PWMLEDS
];
static
uint16_t
target
;
static
uint16_t
pwm_val
;
static
int16_t
err_sum
;
static
unsigned
char
state
;
unsigned
char
mode_changed
;
#define SENSE_MOHM 3000
/* 1 Ohm */
/*
...
...
@@ -21,29 +14,20 @@ pwmled_t pwmleds[N_PWMLEDS];
* ADC module returns sum of 1 << PWMLED_ADC_SHIFT measurements
* Voltage in uV measured is current in mA * sense resistance in mOhm
*/
#define MA_
GAIN_
TO_ADC(ma
, gain
) ((uint16_t) \
#define MA_TO_ADC(ma) ((uint16_t) \
((uint32_t)(ma) \
* (SENSE_MOHM) \
* (1 << (PWMLED_ADC_SHIFT)) \
* 1024 \
/
(
1100000
/(gain))
))
/ 1100000))
static
uint16_t
adc_max
[
N_PWMLEDS
]
=
{
MA_GAIN_TO_ADC
(
30
,
1
),
MA_GAIN_TO_ADC
(
30
,
1
),
};
static
uint16_t
adc_max
=
MA_TO_ADC
(
30
);
static
uint16_t
adc_vals
[
N_PWMLEDS
*
N_PWMLED_MODES
]
=
{
/* pwmled0 */
MA_GAIN_TO_ADC
(
2
,
1
),
MA_GAIN_TO_ADC
(
5
,
1
),
MA_GAIN_TO_ADC
(
10
,
1
),
MA_GAIN_TO_ADC
(
20
,
1
),
/* pwmled1 */
MA_GAIN_TO_ADC
(
2
,
1
),
MA_GAIN_TO_ADC
(
8
,
1
),
MA_GAIN_TO_ADC
(
14
,
1
),
MA_GAIN_TO_ADC
(
20
,
1
),
static
uint16_t
targets
[
N_PWMLED_MODES
]
=
{
MA_TO_ADC
(
2
),
MA_TO_ADC
(
8
),
MA_TO_ADC
(
14
),
MA_TO_ADC
(
20
),
};
#define ST_DISABLED 0
...
...
@@ -56,159 +40,75 @@ static uint16_t adc_vals[N_PWMLEDS*N_PWMLED_MODES] = {
void
init_pwmled
()
{
unsigned
char
i
,
j
;
for
(
i
=
0
;
i
<
N_PWMLEDS
;
i
++
)
{
pwmled_t
*
led
=
pwmleds
+
i
;
led
->
err_sum
=
0
;
led
->
target
=
adc_vals
[
i
*
N_PWMLED_MODES
];
led
->
pwm
=
0
;
led
->
mode
=
1
;
led
->
state
=
ST_PROBING
;
led
->
probe_steady
=
0
;
for
(
j
=
0
;
j
<
N_PWMLED_MODES
;
j
++
)
{
led
->
mode_pwm
[
j
]
=
0
;
led
->
err_sums
[
j
]
=
0
;
}
}
pwmleds
[
0
].
state
=
ST_DISABLED
;
pwm_val
=
0
;
err_sum
=
0
;
target
=
targets
[
0
];
state
=
ST_OFF
;
}
void
pwmled_set_mode
(
unsigned
char
n
,
unsigned
char
mode
)
void
pwmled_set_mode
(
unsigned
char
mode
)
{
pwmled_t
*
led
=
pwmleds
+
n
;
if
(
!
ST_CAN_SET_MODE
(
led
->
state
))
if
(
!
ST_CAN_SET_MODE
(
state
))
return
;
if
(
led
->
mode
)
{
// save the previous state
led
->
mode_pwm
[
led
->
mode
-
1
]
=
led
->
pwm
;
led
->
err_sums
[
led
->
mode
-
1
]
=
led
->
err_sum
;
}
led
->
mode
=
mode
;
if
(
mode
>
0
&&
mode
<=
N_PWMLED_MODES
)
{
led
->
target
=
adc_vals
[
n
*
N_PWMLED_MODES
+
mode
-
1
];
led
->
state
=
ST_ON
;
led
->
pwm
=
led
->
mode_pwm
[
mode
-
1
];
led
->
err_sum
=
led
->
err_sums
[
mode
-
1
];
led
->
mode_changed
=
1
;
pwm_set
(
led
->
pwm
);
}
else
{
led
->
state
=
ST_OFF
;
pwm_off
();
}
}
#define PWMLED_PROBE_STEADY_COUNT 10
static
inline
unsigned
char
pwmled_probed_ok
(
unsigned
char
n
,
uint16_t
old_pwm
)
{
pwmled_t
*
led
=
pwmleds
+
n
;
if
(
led
->
pwm
==
old_pwm
)
{
if
(
led
->
probe_steady
<
PWMLED_PROBE_STEADY_COUNT
)
led
->
probe_steady
++
;
}
else
{
led
->
probe_steady
=
0
;
}
if
(
led
->
probe_steady
<
PWMLED_PROBE_STEADY_COUNT
&&
old_pwm
<=
led
->
pwm
)
return
0
;
// probed OK
led
->
mode_pwm
[
led
->
mode
-
1
]
=
led
->
pwm
;
led
->
err_sums
[
led
->
mode
-
1
]
=
0
;
// next mode to probe?
if
(
led
->
mode
<
N_PWMLED_MODES
)
{
led
->
probe_steady
=
0
;
led
->
err_sum
=
0
;
led
->
mode
++
;
led
->
target
=
adc_vals
[
n
*
N_PWMLED_MODES
+
led
->
mode
-
1
];
return
0
;
if
(
mode
)
{
target
=
targets
[
mode
-
1
];
state
=
ST_ON
;
mode_changed
=
1
;
pwm_set
(
pwm_val
);
}
else
{
unsigned
char
i
;
led
->
state
=
ST_OFF
;
state
=
ST_OFF
;
pwm_off
();
log_byte
(
0xF0
);
log_byte
(
n
);
// log_word(jiffies);
for
(
i
=
0
;
i
<
N_PWMLED_MODES
;
i
++
)
log_word
(
led
->
mode_pwm
[
i
]);
log_flush
();
// pattern_reload();
// pwmled_set_mode(n, 2);
return
1
;
}
}
static
inline
void
pwmled_err
(
unsigned
char
n
)
static
inline
void
pwmled_err
()
{
pwmleds
[
n
].
state
=
ST_DISABLED
;
state
=
ST_DISABLED
;
pwm_off
();
log_byte
(
0xF1
);
log_byte
(
n
);
// log_word(jiffies);
log_flush
();
}
void
pwmled_adc
(
unsigned
char
n
,
uint16_t
adcval
)
void
pwmled_adc
(
uint16_t
adcval
)
{
pwmled_t
*
led
=
pwmleds
+
n
;
uint16_t
old_pwm
;
int32_t
sum
;
unsigned
char
shift
;
if
(
!
ST_IS_ON
(
led
->
state
))
if
(
!
ST_IS_ON
(
state
))
return
;
if
(
led
->
state
==
ST_ON
&&
led
->
mode_changed
)
{
led
->
mode_changed
--
;
// skip the first reading after mode change
if
(
state
==
ST_ON
&&
mode_changed
)
{
mode_changed
--
;
return
;
}
// FIXME: test for maximum adcval value (adc_max[n])
old_pwm
=
led
->
pwm
;
if
(
adcval
>
adc_max
)
{
pwmled_err
();
return
;
}
shift
=
led
->
state
==
ST_PROBING
?
3
:
8
;
shift
=
5
;
sum
=
((
int32_t
)
led
->
pwm
<<
shift
)
+
led
->
err_sum
+
led
->
target
-
adcval
;
sum
=
((
int32_t
)
pwm_val
<<
shift
)
+
err_sum
+
target
-
adcval
;
if
(
sum
<
0
)
sum
=
0
;
led
->
pwm
=
sum
>>
shift
;
sum
-=
led
->
pwm
<<
shift
;
led
->
err_sum
=
sum
;
pwm_val
=
sum
>>
shift
;
sum
-=
pwm_val
<<
shift
;
err_sum
=
sum
;
if
(
led
->
pwm
>=
PWM_MAX
||
(
led
->
pwm
>
(
2
*
PWM_MAX
/
3
)
&&
adcval
<
0x08
))
{
pwmled_err
(
n
);
if
(
pwm_val
>=
PWM_MAX
||
(
pwm_val
>
(
2
*
PWM_MAX
/
3
)
&&
adcval
<
0x08
))
{
pwmled_err
();
return
;
}
if
(
led
->
state
==
ST_PROBING
)
if
(
pwmled_probed_ok
(
n
,
old_pwm
))
return
;
if
(
led
->
pwm
==
old_pwm
)
return
;
pwm_set
(
led
->
pwm
);
pwm_set
(
pwm_val
);
}
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment