Commit 287f589e authored by Jan Kasprzak's avatar Jan Kasprzak
Browse files

Added missing source files battery.c and buttons.c

parent 887aa3ba
#include <avr/io.h>
#include "lights.h"
#define BATTERY_ADC_SHIFT 2
#define RESISTOR_HI 1500 // kOhm
#define RESISTOR_LO 100 // kOhm
/*
* The internal 1.1V reference has tolerance from 1.0 to 1.2V
* (datasheet, section 19.6). We have to measure the actual value
* of our part.
*/
#define AREF_1100MV 1060 // mV
static volatile uint16_t battery_adcval;
static unsigned char initial_readings = 0;
void init_battery()
{
battery_adcval = 0;
initial_readings = 5;
}
unsigned char battery_100mv()
{
/*
* This is tricky: we need to maintain precision, so we first
* multiply adcval by as big number as possible to fit uint16_t,
* then divide to get the final value,
* and finally type-cast it to unsigned char.
* We don't do running average, as the required precision
* is coarse (0.1 V).
*/
return (unsigned char)
((uint16_t)(
(battery_adcval >> BATTERY_ADC_SHIFT)
* (11 // 1.1V
* (RESISTOR_HI+RESISTOR_LO)/RESISTOR_LO // resistor ratio
/ 4)) >> 8); // divide by 1024
}
void battery_adc(uint16_t adcval)
{
if (initial_readings) {
initial_readings--;
battery_adcval = adcval << BATTERY_ADC_SHIFT;
} else if (battery_adcval == 0) {
battery_adcval = adcval << BATTERY_ADC_SHIFT;
} else { // running average
battery_adcval += (adcval
- (battery_adcval >> BATTERY_ADC_SHIFT));
}
#if 0
log_byte(battery_100mv());
log_flush();
#endif
}
unsigned char battery_gauge()
{
unsigned char b8 = battery_100mv();
unsigned char rv;
if (b8 < 70) {
rv = 1;
} else if (b8 < 75) {
rv = 2;
} else if (b8 < 80) {
rv = 3;
} else if (b8 < 85) {
rv = 4;
} else if (b8 < 90) {
rv = 5;
} else if (b8 < 95) {
rv = 6;
} else {
rv = 7;
}
if (rv == 1 && !initial_readings)
set_error(ERR_BATTERY);
#if 0
log_byte(0xbb);
log_byte(rv);
log_flush();
#endif
return rv;
}
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
#include <util/delay.h>
#include <stdlib.h> // for NULL
#include "lights.h"
#define WAKEUP_LIMIT 5 // times 100 ms
#define SHORT_PRESS_MIN 10 // in jiffies (100 Hz ticks)
#define SHORT_PRESS_MAX 50
#define LONG_PRESS_MIN 100
static uint16_t button_start;
static unsigned char prev_state;
void status_led_on_off(unsigned char mode)
{
if (mode)
PORTB |= _BV(PORTB0);
else
PORTB &= ~_BV(PORTB0);
}
void init_buttons()
{
DDRB &= ~_BV(DDB1);
DDRB |= _BV(DDB0);
PORTB |= _BV(PORTB1); // enable internal pull-up
PORTB &= ~_BV(PORTB0); // status led off
GIMSK &= ~_BV(PCIE); // disable pin-change IRQs
PCMSK = 0; // disable pin-change IRQs on all pins of port B
button_start = 0;
prev_state = 0;
}
void susp_buttons()
{
DDRB &= ~(_BV(DDB1)); // set as input
PORTB |= _BV(PORTB1); // enable internal pull-up
PORTB &= ~_BV(PORTB0); // set to zero
GIMSK |= _BV(PCIE);
PCMSK = _BV(PCINT1);
// disable pin-change IRQs on all pins except PB1
}
void timer_check_buttons()
{
unsigned char cur = !(PINB & _BV(PINB1));
unsigned char prev = prev_state;
prev_state = cur;
if (cur && !prev) { // --- just pressed ---
button_start = jiffies;
// set_status_led(button, NULL);
} else if (cur && prev) { // --- is still pressed ---
uint16_t duration = jiffies - button_start;
if (duration > LONG_PRESS_MIN) {
long_press_start();
// acknowledge long press
}
} else if (!cur && prev) { // --- just released ---
uint16_t duration = jiffies - button_start;
if (duration > SHORT_PRESS_MIN && duration < SHORT_PRESS_MAX) {
short_press();
} else if (duration > LONG_PRESS_MIN) {
// set_status_led(button, NULL);
long_press();
}
// ignore other button-press durations
}
}
#if 0
static void handle_brake(unsigned char cur, unsigned char prev)
{
if (cur && !prev) { // --- just pressed ---
button_start[2] = jiffies;
} else if (!cur && prev) { // --- just released ---
button_start[2] = jiffies;
} else { // --- no change ---
uint16_t duration = jiffies - button_start[2];
if (duration > 6) {
if (cur) {
if (button_state.brake_working
&& !button_state.brake_reported) {
button_state.brake_reported = 1;
brake_on();
}
} else {
button_state.brake_working = 1;
if (button_state.brake_reported) {
button_state.brake_reported = 0;
brake_off();
}
}
button_start[2] = jiffies - 7; // avoid overflow
}
}
}
#endif
unsigned char buttons_wait_for_release()
{
uint16_t wake_count = 0;
unsigned char pin;
do {
if (wake_count++ > WAKEUP_LIMIT)
status_led_on_off(1); // inform the user
_delay_ms(100);
pin = PINB & _BV(PINB1);
} while (!(pin & _BV(PINB1)));
status_led_on_off(0);
return wake_count > WAKEUP_LIMIT;
}
ISR(PCINT0_vect)
{
// empty - let it wake us from sleep, but do nothing else
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment