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
37d45fd9
Commit
37d45fd9
authored
May 01, 2013
by
Jan Kasprzak
Browse files
Merge branch 'master' of
ssh://anxur.fi.muni.cz/~kas/html/git/tinyboard
parents
3079ccda
b02a7f77
Changes
5
Show whitespace changes
Inline
Side-by-side
projects/step-up/Makefile
View file @
37d45fd9
PROGRAM
=
lights
SRC
=
main.c logging.c pwm.c adc.c pwmled.c
SRC
=
main.c logging.c pwm.c adc.c pwmled.c
pattern.c
OBJ
=
$(SRC:.c=.o)
...
...
projects/step-up/adc.c
View file @
37d45fd9
...
...
@@ -5,32 +5,13 @@
#include
"lights.h"
#define BATTERY_ADC (N_PWMLEDS + 0)
#define BUTTON_ADC (N_PWMLEDS + 1)
#define ZERO_ADC (N_PWMLEDS + 2)
#define ZERO_ADC 1
//#define NUM_ADCS ZERO_ADC
#define NUM_ADCS 1
struct
{
unsigned
char
read_zero_log
:
2
;
unsigned
char
read_drop_log
:
2
;
unsigned
char
read_keep_log
:
4
;
}
adc_params
[
NUM_ADCS
]
=
{
{
0
,
1
,
PWMLED_ADC_SHIFT
},
// pwmled 1
#if 0
{ 0, 1, PWMLED_ADC_SHIFT }, // pwmled 2
{ 0, 1, PWMLED_ADC_SHIFT }, // pwmled 3
{ 0, 1, AMBIENT_ADC_SHIFT }, // ambient
{ 0, 1, 0 }, // battery
{ 0, 1, 0 }, // gain20
{ 0, 1, 0 }, // buttons
#endif
};
volatile
static
unsigned
char
current_adc
,
current_slow_adc
;
static
uint16_t
adc_sum
,
zero_count
,
drop_count
,
read_count
,
n_reads_log
;
static
uint16_t
adc_sum
,
read_zero
,
drop_count
,
read_count
,
n_reads_log
;
static
void
setup_mux
(
unsigned
char
n
)
{
...
...
@@ -73,23 +54,14 @@ void start_next_adc()
#endif
adc_sum
=
0
;
// we use the last iteration of zero_count to set up the MUX
// to its final destination, hence the "1 +" below:
if
(
adc_params
[
current_adc
].
read_zero_log
)
zero_count
=
1
+
(
1
<<
(
adc_params
[
current_adc
].
read_zero_log
-
1
));
else
zero_count
=
1
;
read_zero
=
0
;
drop_count
=
1
;
if
(
adc_params
[
current_adc
].
read_drop_log
)
drop_count
=
1
<<
(
adc_params
[
current_adc
].
read_drop_log
-
1
);
else
drop_count
=
0
;
read_count
=
1
<<
adc_params
[
current_adc
].
read_keep_log
;
n_reads_log
=
adc_params
[
current_adc
].
read_keep_log
;
read_count
=
1
<<
PWMLED_ADC_SHIFT
;
n_reads_log
=
PWMLED_ADC_SHIFT
;
// set up mux, start one-shot conversion
if
(
zero_count
>
1
)
if
(
read_zero
)
setup_mux
(
ZERO_ADC
);
else
setup_mux
(
current_adc
);
...
...
@@ -97,6 +69,7 @@ void start_next_adc()
ADCSRA
|=
_BV
(
ADSC
);
}
#if 0
void timer_start_slow_adcs()
{
if (current_slow_adc > N_PWMLEDS) { // Don't start if in progress
...
...
@@ -106,6 +79,7 @@ void timer_start_slow_adcs()
// TODO: kick the watchdog here
}
}
#endif
/*
* Single synchronous ADC conversion.
...
...
@@ -129,7 +103,6 @@ static uint16_t read_adc_sync()
void
init_adc
()
{
unsigned
char
i
;
current_slow_adc
=
NUM_ADCS
;
current_adc
=
0
;
...
...
@@ -171,19 +144,26 @@ static void adc1_gain20_adc(uint16_t adcsum)
}
#endif
static
void
inline
adc_based_timer
()
{
static
uint16_t
pattern_counter
;
if
(
++
pattern_counter
>
250
)
{
pattern_counter
=
0
;
patterns_next_tick
();
}
}
ISR
(
ADC_vect
)
{
// IRQ handler
uint16_t
adcval
=
ADCW
;
if
(
zero_count
)
{
if
(
zero_count
>
1
)
{
ADCSRA
|=
_BV
(
ADSC
);
zero_count
--
;
return
;
}
else
{
adc_based_timer
();
if
(
read_zero
)
{
setup_mux
(
current_adc
);
zero_count
=
0
;
/* fall through */
}
read_zero
=
0
;
ADCSRA
|=
_BV
(
ADSC
);
// drop this one, start the next
return
;
}
if
(
drop_count
)
{
...
...
@@ -193,7 +173,7 @@ ISR(ADC_vect) { // IRQ handler
}
if
(
read_count
)
{
ADCSRA
|=
_BV
(
ADSC
);
ADCSRA
|=
_BV
(
ADSC
);
// immediately start the next conversion
adc_sum
+=
adcval
;
read_count
--
;
return
;
...
...
@@ -206,7 +186,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 @
37d45fd9
...
...
@@ -3,8 +3,6 @@
#define TESTING_FW 1
#define N_LEDS 7
#define N_PWMLEDS 2
#define N_PWMLED_MODES 4
#define N_BUTTONS 2
...
...
@@ -44,8 +42,9 @@ 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_target
(
unsigned
char
mode
);
void
pwmled_on_off
(
unsigned
char
on
);
/* gpio.c */
void
init_gpio
();
...
...
projects/step-up/pattern.c
View file @
37d45fd9
...
...
@@ -3,29 +3,10 @@
#include
"lights.h"
#define N_LEDS 1
static
unsigned
char
led_counters
[
N_LEDS
];
static
pattern_t
*
led_patterns
[
N_LEDS
];
static
pattern_t
boot_pattern
[]
=
{
{
1
,
0x6
},
{
0
,
0x6
},
{
1
,
0x3
},
{
0
,
0x3
},
{
1
,
0x2
},
{
0
,
0x2
},
{
1
,
0x1
},
{
0
,
0x1
},
{
1
,
0x1
},
{
0
,
0x1
},
{
1
,
0x1
},
{
0
,
0x1
},
{
1
,
0x1
},
{
0
,
0x1
},
{
1
,
0x10
},
{
0
,
0x10
},
PATTERN_END
};
static
pattern_t
pattern_num
[]
=
{
{
0
,
0x5
},
{
1
,
0x1
},
/* 10 */
...
...
@@ -81,12 +62,20 @@ pattern_t off_pattern[] = {
PATTERN_END
};
pattern_t
on1_pattern
[]
=
{
{
1
,
1
},
{
0
,
2
},
{
1
,
1
},
{
0
,
8
},
{
1
,
1
},
{
0
,
8
},
PATTERN_END
};
static
void
led_set_mode
(
unsigned
char
n
,
unsigned
char
mode
)
{
if
(
n
<
N_PWMLEDS
)
{
pwmled_set_mode
(
n
,
mode
);
}
else
if
(
n
<
N_LEDS
)
{
gpio_set
(
n
-
N_PWMLEDS
,
mode
);
if
(
n
==
0
)
{
pwmled_on_off
(
mode
);
}
}
...
...
@@ -107,8 +96,6 @@ void init_pattern()
for
(
i
=
0
;
i
<
N_LEDS
;
i
++
)
led_set_pattern
(
i
,
NULL
);
led_set_pattern
(
N_PWMLEDS
+
1
,
boot_pattern
);
}
pattern_t
*
number_pattern
(
unsigned
char
num
,
unsigned
char
inv
)
...
...
@@ -129,13 +116,21 @@ pattern_t *number_pattern(unsigned char num, unsigned char inv)
static
pattern_t
*
pattern_select
(
unsigned
char
n
)
{
static
unsigned
char
count
;
static
unsigned
char
mode
;
switch
(
n
)
{
case
0
:
return
pwmled0_pattern_select
();
case
1
:
return
pwmled1_pattern_select
();
case
2
:
return
pwmled2_pattern_select
();
case
3
:
return
status_led_pattern_select
();
case
4
:
return
illumination_led_pattern_select
();
case
6
:
return
laser_pattern_select
();
case
0
:
if
(
++
count
>
2
)
{
count
=
0
;
if
(
mode
==
0
)
{
mode
=
3
;
}
else
{
mode
=
0
;
}
pwmled_set_target
(
mode
);
}
return
number_pattern
(
mode
?
2
:
3
,
0
);
default:
return
NULL
;
}
}
...
...
@@ -154,14 +149,10 @@ static void inline pattern_finished(unsigned char n)
led_patterns
[
n
]
=
NULL
;
if
(
n
<
N_PWMLEDS
)
{
for
(
i
=
0
;
i
<
N_PWMLEDS
;
i
++
)
if
(
led_patterns
[
i
])
return
;
/* all pwmleds finished; restart them */
for
(
i
=
0
;
i
<
N_PWMLEDS
;
i
++
)
led_set_pattern
(
i
,
pattern_select
(
i
));
if
(
n
==
0
)
{
led_set_pattern
(
0
,
pattern_select
(
0
));
}
#if 0
} else if (n == 3) {
if (!led_patterns[4])
led_set_pattern(4, pattern_select(4));
...
...
@@ -171,6 +162,7 @@ static void inline pattern_finished(unsigned char n)
} else {
led_set_pattern(n, pattern_select(n));
}
#endif
}
void
patterns_next_tick
()
...
...
projects/step-up/pwmled.c
View file @
37d45fd9
...
...
@@ -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,80 @@ 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_
target
(
unsigned
char
mode
)
{
pwmled_t
*
led
=
pwmleds
+
n
;
if
(
!
ST_CAN_SET_MODE
(
led
->
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
();
}
target
=
targets
[
mode
];
mode_changed
=
1
;
}
#define PWMLED_PROBE_STEADY_COUNT 10
static
inline
unsigned
char
pwmled_probed_ok
(
unsigned
char
n
,
uint16_t
old_pwm
)
void
pwmled_on_off
(
unsigned
char
mode
)
{
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
];
if
(
!
ST_CAN_SET_MODE
(
state
))
return
;
return
0
;
if
(
mode
)
{
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