Diff
checker
Text
Text
Images
Documents
Excel
Folders
Legal
Enterprise
Desktop
Pricing
Sign in
Download Diffchecker Desktop
Compare text
Find the difference between two text files
Tools
History
Real-time editor
Hide unchanged lines
Disable line wrap
Layout
Split
Unified
Diff precision
Smart
Word
Char
Syntax highlighting
Choose syntax
Ignore
Transform text
Go to first change
Edit input
Diffchecker Desktop
The most secure way to run Diffchecker. Get the Diffchecker Desktop app: your diffs never leave your computer!
Get Desktop
Untitled diff
Created
11 years ago
Diff never expires
Clear
Export
Share
Explain
21 removals
Lines
Total
Removed
Characters
Total
Removed
To continue using this feature, upgrade to
Diff
checker
Pro
View Pricing
287 lines
Copy
26 additions
Lines
Total
Added
Characters
Total
Added
To continue using this feature, upgrade to
Diff
checker
Pro
View Pricing
296 lines
Copy
Copy
Copied
Copy
Copied
*
Settings to modify per driver
#define F_CPU 4800000UL
/*
* =========================================================================
*
Settings to modify per driver
*/
*/
#define VOLTAGE_MON // Comment out to disable
#define VOLTAGE_MON // Comment out to disable
Copy
Copied
Copy
Copied
#define MODE_MOON
1
// Can comment out to remove mode, but should be set through soldering stars
#define MODE_MOON
8
// Can comment out to remove mode, but should be set through soldering stars
#define MODE_
1
8
// Can comment out to remove mode
#define MODE_
LOW
14
// Can comment out to remove mode
#define MODE_
2
75
// Can comment out to remove mode
#define MODE_
MED
39 // Can comment out to remove mode
#define MODE_HIGH_W_TURBO 110 // MODE_HIGH value when turbo is enabled
#define MODE_HIGH 120
// Can comment out to remove mode
#define MODE_TURBO 255 // Can comment out to remove mode
#define MODE_TURBO 255 // Can comment out to remove mode
Copy
Copied
Copy
Copied
#define TURBO_TIMEOUT
37
// How many WTD ticks before before dropping down (.5 sec each)
#define TURBO_TIMEOUT
240
// How many WTD ticks before before dropping down (.5 sec each)
#define WDT_TIMEOUT 2 // Number of WTD ticks before mode is saved (.5 sec each)
#define WDT_TIMEOUT 2 // Number of WTD ticks before mode is saved (.5 sec each)
#define ADC_LOW 130 // When do we start ramping
#define ADC_LOW 130 // When do we start ramping
#define ADC_CRIT 120 // When do we shut the light off
#define ADC_CRIT 120 // When do we shut the light off
/*
/*
* =========================================================================
* =========================================================================
*/
*/
#ifdef MODE_TURBO
#ifdef MODE_TURBO
#undef MODE_HIGH
#undef MODE_HIGH
#define MODE_HIGH MODE_HIGH_W_TURBO
#define MODE_HIGH MODE_HIGH_W_TURBO
#endif
#endif
//#include <avr/pgmspace.h>
//#include <avr/pgmspace.h>
#include <avr/io.h>
#include <avr/io.h>
#include <util/delay.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <avr/interrupt.h>
#include <avr/wdt.h>
#include <avr/wdt.h>
#include <avr/eeprom.h>
#include <avr/eeprom.h>
#include <avr/sleep.h>
#include <avr/sleep.h>
//#include <avr/power.h>
//#include <avr/power.h>
#define STAR2_PIN PB0
#define STAR2_PIN PB0
#define STAR3_PIN PB4
#define STAR3_PIN PB4
#define STAR4_PIN PB3
#define STAR4_PIN PB3
#define PWM_PIN PB1
#define PWM_PIN PB1
#define VOLTAGE_PIN PB2
#define VOLTAGE_PIN PB2
#define ADC_CHANNEL 0x01 // MUX 01 corresponds with PB2
#define ADC_CHANNEL 0x01 // MUX 01 corresponds with PB2
#define ADC_DIDR ADC1D // Digital input disable bit corresponding with PB2
#define ADC_DIDR ADC1D // Digital input disable bit corresponding with PB2
#define ADC_PRSCL 0x06 // clk/64
#define ADC_PRSCL 0x06 // clk/64
#define PWM_LVL OCR0B // OCR0B is the output compare register for PB1
#define PWM_LVL OCR0B // OCR0B is the output compare register for PB1
/*
/*
* global variables
* global variables
*/
*/
// Mode storage
// Mode storage
uint8_t eepos = 0;
uint8_t eepos = 0;
uint8_t eep[32];
uint8_t eep[32];
uint8_t memory = 0;
uint8_t memory = 0;
// Modes (gets set when the light starts up based on stars)
// Modes (gets set when the light starts up based on stars)
static uint8_t modes[10]; // Don't need 10, but keeping it high enough to handle all
static uint8_t modes[10]; // Don't need 10, but keeping it high enough to handle all
volatile uint8_t mode_idx = 0;
volatile uint8_t mode_idx = 0;
int mode_dir = 0; // 1 or -1. Determined when checking stars. Do we increase or decrease the idx when moving up to a higher mode.
int mode_dir = 0; // 1 or -1. Determined when checking stars. Do we increase or decrease the idx when moving up to a higher mode.
uint8_t mode_cnt = 0;
uint8_t mode_cnt = 0;
uint8_t lowbatt_cnt = 0;
uint8_t lowbatt_cnt = 0;
void store_mode_idx(uint8_t lvl) { //central method for writing (with wear leveling)
void store_mode_idx(uint8_t lvl) { //central method for writing (with wear leveling)
uint8_t oldpos=eepos;
uint8_t oldpos=eepos;
eepos=(eepos+1)&31; //wear leveling, use next cell
eepos=(eepos+1)&31; //wear leveling, use next cell
// Write the current mode
// Write the current mode
EEARL=eepos; EEDR=lvl; EECR=32+4; EECR=32+4+2; //WRITE //32:write only (no erase) 4:enable 2:go
EEARL=eepos; EEDR=lvl; EECR=32+4; EECR=32+4+2; //WRITE //32:write only (no erase) 4:enable 2:go
while(EECR & 2); //wait for completion
while(EECR & 2); //wait for completion
// Erase the last mode
// Erase the last mode
EEARL=oldpos; EECR=16+4; EECR=16+4+2; //ERASE //16:erase only (no write) 4:enable 2:go
EEARL=oldpos; EECR=16+4; EECR=16+4+2; //ERASE //16:erase only (no write) 4:enable 2:go
}
}
inline void read_mode_idx() {
inline void read_mode_idx() {
eeprom_read_block(&eep, 0, 32);
eeprom_read_block(&eep, 0, 32);
while((eep[eepos] == 0xff) && (eepos < 32)) eepos++;
while((eep[eepos] == 0xff) && (eepos < 32)) eepos++;
if (eepos < 32) mode_idx = eep[eepos];//&0x10; What the?
if (eepos < 32) mode_idx = eep[eepos];//&0x10; What the?
else eepos=0;
else eepos=0;
}
}
inline void next_mode() {
inline void next_mode() {
if (mode_idx == 0 && mode_dir == -1) {
if (mode_idx == 0 && mode_dir == -1) {
// Wrap around
// Wrap around
mode_idx = mode_cnt - 1;
mode_idx = mode_cnt - 1;
} else {
} else {
mode_idx += mode_dir;
mode_idx += mode_dir;
if (mode_idx > (mode_cnt - 1)) {
if (mode_idx > (mode_cnt - 1)) {
// Wrap around
// Wrap around
mode_idx = 0;
mode_idx = 0;
}
}
}
}
}
}
inline void WDT_on() {
inline void WDT_on() {
// Setup watchdog timer to only interrupt, not reset, every 500ms.
// Setup watchdog timer to only interrupt, not reset, every 500ms.
cli(); // Disable interrupts
cli(); // Disable interrupts
wdt_reset(); // Reset the WDT
wdt_reset(); // Reset the WDT
WDTCR |= (1<<WDCE) | (1<<WDE); // Start timed sequence
WDTCR |= (1<<WDCE) | (1<<WDE); // Start timed sequence
WDTCR = (1<<WDTIE) | (1<<WDP2) | (1<<WDP0); // Enable interrupt every 500ms
WDTCR = (1<<WDTIE) | (1<<WDP2) | (1<<WDP0); // Enable interrupt every 500ms
sei(); // Enable interrupts
sei(); // Enable interrupts
}
}
inline void WDT_off()
inline void WDT_off()
{
{
cli(); // Disable interrupts
cli(); // Disable interrupts
wdt_reset(); // Reset the WDT
wdt_reset(); // Reset the WDT
MCUSR &= ~(1<<WDRF); // Clear Watchdog reset flag
MCUSR &= ~(1<<WDRF); // Clear Watchdog reset flag
WDTCR |= (1<<WDCE) | (1<<WDE); // Start timed sequence
WDTCR |= (1<<WDCE) | (1<<WDE); // Start timed sequence
WDTCR = 0x00; // Disable WDT
WDTCR = 0x00; // Disable WDT
sei(); // Enable interrupts
sei(); // Enable interrupts
}
}
inline void ADC_on() {
inline void ADC_on() {
ADMUX = (1 << REFS0) | (1 << ADLAR) | ADC_CHANNEL; // 1.1v reference, left-adjust, ADC1/PB2
ADMUX = (1 << REFS0) | (1 << ADLAR) | ADC_CHANNEL; // 1.1v reference, left-adjust, ADC1/PB2
DIDR0 |= (1 << ADC_DIDR); // disable digital input on ADC pin to reduce power consumption
DIDR0 |= (1 << ADC_DIDR); // disable digital input on ADC pin to reduce power consumption
ADCSRA = (1 << ADEN ) | (1 << ADSC ) | ADC_PRSCL; // enable, start, prescale
ADCSRA = (1 << ADEN ) | (1 << ADSC ) | ADC_PRSCL; // enable, start, prescale
}
}
inline void ADC_off() {
inline void ADC_off() {
ADCSRA &= ~(1<<7); //ADC off
ADCSRA &= ~(1<<7); //ADC off
}
}
#ifdef VOLTAGE_MON
#ifdef VOLTAGE_MON
uint8_t low_voltage(uint8_t voltage_val) {
uint8_t low_voltage(uint8_t voltage_val) {
// Start conversion
// Start conversion
ADCSRA |= (1 << ADSC);
ADCSRA |= (1 << ADSC);
// Wait for completion
// Wait for completion
while (ADCSRA & (1 << ADSC));
while (ADCSRA & (1 << ADSC));
// See if voltage is lower than what we were looking for
// See if voltage is lower than what we were looking for
if (ADCH < voltage_val) {
if (ADCH < voltage_val) {
// See if it's been low for a while
// See if it's been low for a while
if (++lowbatt_cnt > 8) {
if (++lowbatt_cnt > 8) {
lowbatt_cnt = 0;
lowbatt_cnt = 0;
return 1;
return 1;
}
}
} else {
} else {
lowbatt_cnt = 0;
lowbatt_cnt = 0;
}
}
return 0;
return 0;
}
}
#endif
#endif
ISR(WDT_vect) {
ISR(WDT_vect) {
static uint8_t ticks = 0;
static uint8_t ticks = 0;
if (ticks < 255) ticks++;
if (ticks < 255) ticks++;
if (ticks == WDT_TIMEOUT) {
if (ticks == WDT_TIMEOUT) {
if (memory) {
if (memory) {
store_mode_idx(mode_idx);
store_mode_idx(mode_idx);
} else {
} else {
// Reset the mode to the start for next time
// Reset the mode to the start for next time
store_mode_idx((mode_dir == 1) ? 0 : (mode_cnt - 1));
store_mode_idx((mode_dir == 1) ? 0 : (mode_cnt - 1));
}
}
#ifdef MODE_TURBO
#ifdef MODE_TURBO
//} else if (ticks == TURBO_TIMEOUT && modes[mode_idx] == MODE_TURBO) { // Doesn't make any sense why this doesn't work
//} else if (ticks == TURBO_TIMEOUT && modes[mode_idx] == MODE_TURBO) { // Doesn't make any sense why this doesn't work
} else if (ticks == TURBO_TIMEOUT && mode_idx == (mode_cnt - 1)) {
} else if (ticks == TURBO_TIMEOUT && mode_idx == (mode_cnt - 1)) {
// Turbo mode is always at end
// Turbo mode is always at end
Copy
Copied
Copy
Copied
PWM_LVL =
185
;
PWM_LVL =
modes[--mode_idx]
;
#endif
#endif
}
}
}
}
int main(void)
int main(void)
{
{
// All ports default to input, but turn pull-up resistors on for the stars (not the ADC input! Made that mistake already)
// All ports default to input, but turn pull-up resistors on for the stars (not the ADC input! Made that mistake already)
PORTB = (1 << STAR2_PIN) | (1 << STAR3_PIN) | (1 << STAR4_PIN);
PORTB = (1 << STAR2_PIN) | (1 << STAR3_PIN) | (1 << STAR4_PIN);
// Set PWM pin to output
// Set PWM pin to output
DDRB = (1 << PWM_PIN);
DDRB = (1 << PWM_PIN);
// Set timer to do PWM for correct output pin and set prescaler timing
// Set timer to do PWM for correct output pin and set prescaler timing
Copy
Copied
Copy
Copied
TCCR0A = 0x2
1
; // phase corrected PWM is 0x21 for PB1, fast-PWM is 0x23
TCCR0A = 0x2
3
; // phase corrected PWM is 0x21 for PB1, fast-PWM is 0x23
TCCR0B = 0x01; // pre-scaler for timer (1 => 1, 2 => 8, 3 => 64...)
TCCR0B = 0x01; // pre-scaler for timer (1 => 1, 2 => 8, 3 => 64...)
// Turn features on or off as needed
// Turn features on or off as needed
#ifdef VOLTAGE_MON
#ifdef VOLTAGE_MON
ADC_on();
ADC_on();
#else
#else
ADC_off();
ADC_off();
#endif
#endif
ACSR |= (1<<7); //AC off
ACSR |= (1<<7); //AC off
// Load up the modes based on stars
// Load up the modes based on stars
// Always load up the modes array in order of lowest to highest mode
// Always load up the modes array in order of lowest to highest mode
// 0 being low for soldered, 1 for pulled-up for not soldered
// 0 being low for soldered, 1 for pulled-up for not soldered
Copy
Copied
Copy
Copied
// Moon
(stock is 1 then 0)
// Moon
#ifdef MODE_MOON
#ifdef MODE_MOON
Copy
Copied
Copy
Copied
if ((PINB & (1 << STAR2_PIN))
>
0)
{ // Stock is ==, ( > for moon default to on, soldering star will disable moon)
if ((PINB & (1 << STAR2_PIN))
==
0)
{
modes[mode_cnt++] = MODE_MOON;
modes[mode_cnt++] = MODE_MOON;
}
}
#endif
#endif
Copy
Copied
Copy
Copied
#ifdef MODE_
1
#ifdef MODE_
LOW
modes[mode_cnt++] = MODE_
1
;
modes[mode_cnt++] = MODE_
LOW
;
#endif
#endif
Copy
Copied
Copy
Copied
#ifdef MODE_
2
#ifdef MODE_
MED
modes[mode_cnt++] = MODE_
2
;
modes[mode_cnt++] = MODE_
MED;
#endif
#ifdef MODE_HIGH
modes[mode_cnt++] = MODE_HIGH
;
#endif
#endif
#ifdef MODE_TURBO
#ifdef MODE_TURBO
modes[mode_cnt++] = MODE_TURBO;
modes[mode_cnt++] = MODE_TURBO;
#endif
#endif
if ((PINB & (1 << STAR3_PIN)) == 0) {
if ((PINB & (1 << STAR3_PIN)) == 0) {
// High to Low
// High to Low
mode_dir = -1;
mode_dir = -1;
} else {
} else {
mode_dir = 1;
mode_dir = 1;
}
}
Copy
Copied
Copy
Copied
// Not soldered (1) should
disable
memory
// Not soldered (1) should
enable
memory
memory = ((PINB & (1 << STAR4_PIN)) > 0
) ?
0 : 1; //to disable momory without soldering star use ? 0: 1; (stock is ?
1 : 0;
)
memory = ((PINB & (1 << STAR4_PIN)) > 0
) ?
1 : 0;
// Enable sleep mode set to Idle that will be triggered by the sleep_mode() command.
// Enable sleep mode set to Idle that will be triggered by the sleep_mode() command.
// Will allow us to go idle between WDT interrupts
// Will allow us to go idle between WDT interrupts
set_sleep_mode(SLEEP_MODE_IDLE);
set_sleep_mode(SLEEP_MODE_IDLE);
// Determine what mode we should fire up
// Determine what mode we should fire up
// Read the last mode that was saved
// Read the last mode that was saved
read_mode_idx();
read_mode_idx();
if (mode_idx&0x10) {
if (mode_idx&0x10) {
// Indicates we did a short press last time, go to the next mode
// Indicates we did a short press last time, go to the next mode
// Remove short press indicator first
// Remove short press indicator first
mode_idx &= 0x0f;
mode_idx &= 0x0f;
next_mode(); // Will handle wrap arounds
next_mode(); // Will handle wrap arounds
} else {
} else {
// Didn't have a short press, keep the same mode
// Didn't have a short press, keep the same mode
}
}
// Store mode with short press indicator
// Store mode with short press indicator
store_mode_idx(mode_idx|0x10);
store_mode_idx(mode_idx|0x10);
WDT_on();
WDT_on();
// Now just fire up the mode
// Now just fire up the mode
PWM_LVL = modes[mode_idx];
PWM_LVL = modes[mode_idx];
uint8_t i = 0;
uint8_t i = 0;
uint8_t hold_pwm;
uint8_t hold_pwm;
while(1) {
while(1) {
#ifdef VOLTAGE_MON
#ifdef VOLTAGE_MON
if (low_voltage(ADC_LOW)) {
if (low_voltage(ADC_LOW)) {
// We need to go to a lower level
// We need to go to a lower level
if (mode_idx == 0 && PWM_LVL <= modes[mode_idx]) {
if (mode_idx == 0 && PWM_LVL <= modes[mode_idx]) {
// Can't go any lower than the lowest mode
// Can't go any lower than the lowest mode
// Wait until we hit the critical level before flashing 10 times and turning off
// Wait until we hit the critical level before flashing 10 times and turning off
while (!low_voltage(ADC_CRIT));
while (!low_voltage(ADC_CRIT));
i = 0;
i = 0;
while (i++<10) {
while (i++<10) {
PWM_LVL = 0;
PWM_LVL = 0;
_delay_ms(250);
_delay_ms(250);
PWM_LVL = modes[0];
PWM_LVL = modes[0];
_delay_ms(500);
_delay_ms(500);
}
}
// Turn off the light
// Turn off the light
PWM_LVL = 0;
PWM_LVL = 0;
// Disable WDT so it doesn't wake us up
// Disable WDT so it doesn't wake us up
WDT_off();
WDT_off();
// Power down as many components as possible
// Power down as many components as possible
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep_mode();
sleep_mode();
} else {
} else {
// Flash 3 times before lowering
// Flash 3 times before lowering
hold_pwm = PWM_LVL;
hold_pwm = PWM_LVL;
i = 0;
i = 0;
while (i++<3) {
while (i++<3) {
PWM_LVL = 0;
PWM_LVL = 0;
_delay_ms(250);
_delay_ms(250);
PWM_LVL = hold_pwm;
PWM_LVL = hold_pwm;
_delay_ms(500);
_delay_ms(500);
}
}
// Lower the mode by half, but don't go below lowest level
// Lower the mode by half, but don't go below lowest level
if ((PWM_LVL >> 1) < modes[0]) {
if ((PWM_LVL >> 1) < modes[0]) {
PWM_LVL = modes[0];
PWM_LVL = modes[0];
mode_idx = 0;
mode_idx = 0;
} else {
} else {
PWM_LVL = (PWM_LVL >> 1);
PWM_LVL = (PWM_LVL >> 1);
}
}
// See if we should change the current mode level if we've gone under the current mode.
// See if we should change the current mode level if we've gone under the current mode.
if (PWM_LVL < modes[mode_idx]) {
if (PWM_LVL < modes[mode_idx]) {
// Lower our recorded mode
// Lower our recorded mode
mode_idx--;
mode_idx--;
}
}
}
}
// Wait 3 seconds before lowering the level again
// Wait 3 seconds before lowering the level again
_delay_ms(3000);
_delay_ms(3000);
}
}
#endif
#endif
sleep_mode();
sleep_mode();
}
}
return 0; // Standard Return Code
return 0; // Standard Return Code
}
}
Saved diffs
Original text
Open file
*Settings to modify per driver */ #define VOLTAGE_MON // Comment out to disable #define MODE_MOON 1 // Can comment out to remove mode, but should be set through soldering stars #define MODE_1 8 // Can comment out to remove mode #define MODE_2 75 // Can comment out to remove mode #define MODE_TURBO 255 // Can comment out to remove mode #define TURBO_TIMEOUT 37 // How many WTD ticks before before dropping down (.5 sec each) #define WDT_TIMEOUT 2 // Number of WTD ticks before mode is saved (.5 sec each) #define ADC_LOW 130 // When do we start ramping #define ADC_CRIT 120 // When do we shut the light off /* * ========================================================================= */ #ifdef MODE_TURBO #undef MODE_HIGH #define MODE_HIGH MODE_HIGH_W_TURBO #endif //#include <avr/pgmspace.h> #include <avr/io.h> #include <util/delay.h> #include <avr/interrupt.h> #include <avr/wdt.h> #include <avr/eeprom.h> #include <avr/sleep.h> //#include <avr/power.h> #define STAR2_PIN PB0 #define STAR3_PIN PB4 #define STAR4_PIN PB3 #define PWM_PIN PB1 #define VOLTAGE_PIN PB2 #define ADC_CHANNEL 0x01 // MUX 01 corresponds with PB2 #define ADC_DIDR ADC1D // Digital input disable bit corresponding with PB2 #define ADC_PRSCL 0x06 // clk/64 #define PWM_LVL OCR0B // OCR0B is the output compare register for PB1 /* * global variables */ // Mode storage uint8_t eepos = 0; uint8_t eep[32]; uint8_t memory = 0; // Modes (gets set when the light starts up based on stars) static uint8_t modes[10]; // Don't need 10, but keeping it high enough to handle all volatile uint8_t mode_idx = 0; int mode_dir = 0; // 1 or -1. Determined when checking stars. Do we increase or decrease the idx when moving up to a higher mode. uint8_t mode_cnt = 0; uint8_t lowbatt_cnt = 0; void store_mode_idx(uint8_t lvl) { //central method for writing (with wear leveling) uint8_t oldpos=eepos; eepos=(eepos+1)&31; //wear leveling, use next cell // Write the current mode EEARL=eepos; EEDR=lvl; EECR=32+4; EECR=32+4+2; //WRITE //32:write only (no erase) 4:enable 2:go while(EECR & 2); //wait for completion // Erase the last mode EEARL=oldpos; EECR=16+4; EECR=16+4+2; //ERASE //16:erase only (no write) 4:enable 2:go } inline void read_mode_idx() { eeprom_read_block(&eep, 0, 32); while((eep[eepos] == 0xff) && (eepos < 32)) eepos++; if (eepos < 32) mode_idx = eep[eepos];//&0x10; What the? else eepos=0; } inline void next_mode() { if (mode_idx == 0 && mode_dir == -1) { // Wrap around mode_idx = mode_cnt - 1; } else { mode_idx += mode_dir; if (mode_idx > (mode_cnt - 1)) { // Wrap around mode_idx = 0; } } } inline void WDT_on() { // Setup watchdog timer to only interrupt, not reset, every 500ms. cli(); // Disable interrupts wdt_reset(); // Reset the WDT WDTCR |= (1<<WDCE) | (1<<WDE); // Start timed sequence WDTCR = (1<<WDTIE) | (1<<WDP2) | (1<<WDP0); // Enable interrupt every 500ms sei(); // Enable interrupts } inline void WDT_off() { cli(); // Disable interrupts wdt_reset(); // Reset the WDT MCUSR &= ~(1<<WDRF); // Clear Watchdog reset flag WDTCR |= (1<<WDCE) | (1<<WDE); // Start timed sequence WDTCR = 0x00; // Disable WDT sei(); // Enable interrupts } inline void ADC_on() { ADMUX = (1 << REFS0) | (1 << ADLAR) | ADC_CHANNEL; // 1.1v reference, left-adjust, ADC1/PB2 DIDR0 |= (1 << ADC_DIDR); // disable digital input on ADC pin to reduce power consumption ADCSRA = (1 << ADEN ) | (1 << ADSC ) | ADC_PRSCL; // enable, start, prescale } inline void ADC_off() { ADCSRA &= ~(1<<7); //ADC off } #ifdef VOLTAGE_MON uint8_t low_voltage(uint8_t voltage_val) { // Start conversion ADCSRA |= (1 << ADSC); // Wait for completion while (ADCSRA & (1 << ADSC)); // See if voltage is lower than what we were looking for if (ADCH < voltage_val) { // See if it's been low for a while if (++lowbatt_cnt > 8) { lowbatt_cnt = 0; return 1; } } else { lowbatt_cnt = 0; } return 0; } #endif ISR(WDT_vect) { static uint8_t ticks = 0; if (ticks < 255) ticks++; if (ticks == WDT_TIMEOUT) { if (memory) { store_mode_idx(mode_idx); } else { // Reset the mode to the start for next time store_mode_idx((mode_dir == 1) ? 0 : (mode_cnt - 1)); } #ifdef MODE_TURBO //} else if (ticks == TURBO_TIMEOUT && modes[mode_idx] == MODE_TURBO) { // Doesn't make any sense why this doesn't work } else if (ticks == TURBO_TIMEOUT && mode_idx == (mode_cnt - 1)) { // Turbo mode is always at end PWM_LVL =185; #endif } } int main(void) { // All ports default to input, but turn pull-up resistors on for the stars (not the ADC input! Made that mistake already) PORTB = (1 << STAR2_PIN) | (1 << STAR3_PIN) | (1 << STAR4_PIN); // Set PWM pin to output DDRB = (1 << PWM_PIN); // Set timer to do PWM for correct output pin and set prescaler timing TCCR0A = 0x21; // phase corrected PWM is 0x21 for PB1, fast-PWM is 0x23 TCCR0B = 0x01; // pre-scaler for timer (1 => 1, 2 => 8, 3 => 64...) // Turn features on or off as needed #ifdef VOLTAGE_MON ADC_on(); #else ADC_off(); #endif ACSR |= (1<<7); //AC off // Load up the modes based on stars // Always load up the modes array in order of lowest to highest mode // 0 being low for soldered, 1 for pulled-up for not soldered // Moon (stock is 1 then 0) #ifdef MODE_MOON if ((PINB & (1 << STAR2_PIN))> 0) { // Stock is ==, ( > for moon default to on, soldering star will disable moon) modes[mode_cnt++] = MODE_MOON; } #endif #ifdef MODE_1 modes[mode_cnt++] = MODE_1; #endif #ifdef MODE_2 modes[mode_cnt++] = MODE_2; #endif #ifdef MODE_TURBO modes[mode_cnt++] = MODE_TURBO; #endif if ((PINB & (1 << STAR3_PIN)) == 0) { // High to Low mode_dir = -1; } else { mode_dir = 1; } // Not soldered (1) should disable memory memory = ((PINB & (1 << STAR4_PIN)) > 0 ) ? 0 : 1; //to disable momory without soldering star use ? 0: 1; (stock is ? 1 : 0;) // Enable sleep mode set to Idle that will be triggered by the sleep_mode() command. // Will allow us to go idle between WDT interrupts set_sleep_mode(SLEEP_MODE_IDLE); // Determine what mode we should fire up // Read the last mode that was saved read_mode_idx(); if (mode_idx&0x10) { // Indicates we did a short press last time, go to the next mode // Remove short press indicator first mode_idx &= 0x0f; next_mode(); // Will handle wrap arounds } else { // Didn't have a short press, keep the same mode } // Store mode with short press indicator store_mode_idx(mode_idx|0x10); WDT_on(); // Now just fire up the mode PWM_LVL = modes[mode_idx]; uint8_t i = 0; uint8_t hold_pwm; while(1) { #ifdef VOLTAGE_MON if (low_voltage(ADC_LOW)) { // We need to go to a lower level if (mode_idx == 0 && PWM_LVL <= modes[mode_idx]) { // Can't go any lower than the lowest mode // Wait until we hit the critical level before flashing 10 times and turning off while (!low_voltage(ADC_CRIT)); i = 0; while (i++<10) { PWM_LVL = 0; _delay_ms(250); PWM_LVL = modes[0]; _delay_ms(500); } // Turn off the light PWM_LVL = 0; // Disable WDT so it doesn't wake us up WDT_off(); // Power down as many components as possible set_sleep_mode(SLEEP_MODE_PWR_DOWN); sleep_mode(); } else { // Flash 3 times before lowering hold_pwm = PWM_LVL; i = 0; while (i++<3) { PWM_LVL = 0; _delay_ms(250); PWM_LVL = hold_pwm; _delay_ms(500); } // Lower the mode by half, but don't go below lowest level if ((PWM_LVL >> 1) < modes[0]) { PWM_LVL = modes[0]; mode_idx = 0; } else { PWM_LVL = (PWM_LVL >> 1); } // See if we should change the current mode level if we've gone under the current mode. if (PWM_LVL < modes[mode_idx]) { // Lower our recorded mode mode_idx--; } } // Wait 3 seconds before lowering the level again _delay_ms(3000); } #endif sleep_mode(); } return 0; // Standard Return Code }
Changed text
Open file
#define F_CPU 4800000UL /* * ========================================================================= * Settings to modify per driver */ #define VOLTAGE_MON // Comment out to disable #define MODE_MOON 8 // Can comment out to remove mode, but should be set through soldering stars #define MODE_LOW 14 // Can comment out to remove mode #define MODE_MED 39 // Can comment out to remove mode #define MODE_HIGH_W_TURBO 110 // MODE_HIGH value when turbo is enabled #define MODE_HIGH 120 // Can comment out to remove mode #define MODE_TURBO 255 // Can comment out to remove mode #define TURBO_TIMEOUT 240 // How many WTD ticks before before dropping down (.5 sec each) #define WDT_TIMEOUT 2 // Number of WTD ticks before mode is saved (.5 sec each) #define ADC_LOW 130 // When do we start ramping #define ADC_CRIT 120 // When do we shut the light off /* * ========================================================================= */ #ifdef MODE_TURBO #undef MODE_HIGH #define MODE_HIGH MODE_HIGH_W_TURBO #endif //#include <avr/pgmspace.h> #include <avr/io.h> #include <util/delay.h> #include <avr/interrupt.h> #include <avr/wdt.h> #include <avr/eeprom.h> #include <avr/sleep.h> //#include <avr/power.h> #define STAR2_PIN PB0 #define STAR3_PIN PB4 #define STAR4_PIN PB3 #define PWM_PIN PB1 #define VOLTAGE_PIN PB2 #define ADC_CHANNEL 0x01 // MUX 01 corresponds with PB2 #define ADC_DIDR ADC1D // Digital input disable bit corresponding with PB2 #define ADC_PRSCL 0x06 // clk/64 #define PWM_LVL OCR0B // OCR0B is the output compare register for PB1 /* * global variables */ // Mode storage uint8_t eepos = 0; uint8_t eep[32]; uint8_t memory = 0; // Modes (gets set when the light starts up based on stars) static uint8_t modes[10]; // Don't need 10, but keeping it high enough to handle all volatile uint8_t mode_idx = 0; int mode_dir = 0; // 1 or -1. Determined when checking stars. Do we increase or decrease the idx when moving up to a higher mode. uint8_t mode_cnt = 0; uint8_t lowbatt_cnt = 0; void store_mode_idx(uint8_t lvl) { //central method for writing (with wear leveling) uint8_t oldpos=eepos; eepos=(eepos+1)&31; //wear leveling, use next cell // Write the current mode EEARL=eepos; EEDR=lvl; EECR=32+4; EECR=32+4+2; //WRITE //32:write only (no erase) 4:enable 2:go while(EECR & 2); //wait for completion // Erase the last mode EEARL=oldpos; EECR=16+4; EECR=16+4+2; //ERASE //16:erase only (no write) 4:enable 2:go } inline void read_mode_idx() { eeprom_read_block(&eep, 0, 32); while((eep[eepos] == 0xff) && (eepos < 32)) eepos++; if (eepos < 32) mode_idx = eep[eepos];//&0x10; What the? else eepos=0; } inline void next_mode() { if (mode_idx == 0 && mode_dir == -1) { // Wrap around mode_idx = mode_cnt - 1; } else { mode_idx += mode_dir; if (mode_idx > (mode_cnt - 1)) { // Wrap around mode_idx = 0; } } } inline void WDT_on() { // Setup watchdog timer to only interrupt, not reset, every 500ms. cli(); // Disable interrupts wdt_reset(); // Reset the WDT WDTCR |= (1<<WDCE) | (1<<WDE); // Start timed sequence WDTCR = (1<<WDTIE) | (1<<WDP2) | (1<<WDP0); // Enable interrupt every 500ms sei(); // Enable interrupts } inline void WDT_off() { cli(); // Disable interrupts wdt_reset(); // Reset the WDT MCUSR &= ~(1<<WDRF); // Clear Watchdog reset flag WDTCR |= (1<<WDCE) | (1<<WDE); // Start timed sequence WDTCR = 0x00; // Disable WDT sei(); // Enable interrupts } inline void ADC_on() { ADMUX = (1 << REFS0) | (1 << ADLAR) | ADC_CHANNEL; // 1.1v reference, left-adjust, ADC1/PB2 DIDR0 |= (1 << ADC_DIDR); // disable digital input on ADC pin to reduce power consumption ADCSRA = (1 << ADEN ) | (1 << ADSC ) | ADC_PRSCL; // enable, start, prescale } inline void ADC_off() { ADCSRA &= ~(1<<7); //ADC off } #ifdef VOLTAGE_MON uint8_t low_voltage(uint8_t voltage_val) { // Start conversion ADCSRA |= (1 << ADSC); // Wait for completion while (ADCSRA & (1 << ADSC)); // See if voltage is lower than what we were looking for if (ADCH < voltage_val) { // See if it's been low for a while if (++lowbatt_cnt > 8) { lowbatt_cnt = 0; return 1; } } else { lowbatt_cnt = 0; } return 0; } #endif ISR(WDT_vect) { static uint8_t ticks = 0; if (ticks < 255) ticks++; if (ticks == WDT_TIMEOUT) { if (memory) { store_mode_idx(mode_idx); } else { // Reset the mode to the start for next time store_mode_idx((mode_dir == 1) ? 0 : (mode_cnt - 1)); } #ifdef MODE_TURBO //} else if (ticks == TURBO_TIMEOUT && modes[mode_idx] == MODE_TURBO) { // Doesn't make any sense why this doesn't work } else if (ticks == TURBO_TIMEOUT && mode_idx == (mode_cnt - 1)) { // Turbo mode is always at end PWM_LVL = modes[--mode_idx]; #endif } } int main(void) { // All ports default to input, but turn pull-up resistors on for the stars (not the ADC input! Made that mistake already) PORTB = (1 << STAR2_PIN) | (1 << STAR3_PIN) | (1 << STAR4_PIN); // Set PWM pin to output DDRB = (1 << PWM_PIN); // Set timer to do PWM for correct output pin and set prescaler timing TCCR0A = 0x23; // phase corrected PWM is 0x21 for PB1, fast-PWM is 0x23 TCCR0B = 0x01; // pre-scaler for timer (1 => 1, 2 => 8, 3 => 64...) // Turn features on or off as needed #ifdef VOLTAGE_MON ADC_on(); #else ADC_off(); #endif ACSR |= (1<<7); //AC off // Load up the modes based on stars // Always load up the modes array in order of lowest to highest mode // 0 being low for soldered, 1 for pulled-up for not soldered // Moon #ifdef MODE_MOON if ((PINB & (1 << STAR2_PIN)) == 0) { modes[mode_cnt++] = MODE_MOON; } #endif #ifdef MODE_LOW modes[mode_cnt++] = MODE_LOW; #endif #ifdef MODE_MED modes[mode_cnt++] = MODE_MED; #endif #ifdef MODE_HIGH modes[mode_cnt++] = MODE_HIGH; #endif #ifdef MODE_TURBO modes[mode_cnt++] = MODE_TURBO; #endif if ((PINB & (1 << STAR3_PIN)) == 0) { // High to Low mode_dir = -1; } else { mode_dir = 1; } // Not soldered (1) should enable memory memory = ((PINB & (1 << STAR4_PIN)) > 0) ? 1 : 0; // Enable sleep mode set to Idle that will be triggered by the sleep_mode() command. // Will allow us to go idle between WDT interrupts set_sleep_mode(SLEEP_MODE_IDLE); // Determine what mode we should fire up // Read the last mode that was saved read_mode_idx(); if (mode_idx&0x10) { // Indicates we did a short press last time, go to the next mode // Remove short press indicator first mode_idx &= 0x0f; next_mode(); // Will handle wrap arounds } else { // Didn't have a short press, keep the same mode } // Store mode with short press indicator store_mode_idx(mode_idx|0x10); WDT_on(); // Now just fire up the mode PWM_LVL = modes[mode_idx]; uint8_t i = 0; uint8_t hold_pwm; while(1) { #ifdef VOLTAGE_MON if (low_voltage(ADC_LOW)) { // We need to go to a lower level if (mode_idx == 0 && PWM_LVL <= modes[mode_idx]) { // Can't go any lower than the lowest mode // Wait until we hit the critical level before flashing 10 times and turning off while (!low_voltage(ADC_CRIT)); i = 0; while (i++<10) { PWM_LVL = 0; _delay_ms(250); PWM_LVL = modes[0]; _delay_ms(500); } // Turn off the light PWM_LVL = 0; // Disable WDT so it doesn't wake us up WDT_off(); // Power down as many components as possible set_sleep_mode(SLEEP_MODE_PWR_DOWN); sleep_mode(); } else { // Flash 3 times before lowering hold_pwm = PWM_LVL; i = 0; while (i++<3) { PWM_LVL = 0; _delay_ms(250); PWM_LVL = hold_pwm; _delay_ms(500); } // Lower the mode by half, but don't go below lowest level if ((PWM_LVL >> 1) < modes[0]) { PWM_LVL = modes[0]; mode_idx = 0; } else { PWM_LVL = (PWM_LVL >> 1); } // See if we should change the current mode level if we've gone under the current mode. if (PWM_LVL < modes[mode_idx]) { // Lower our recorded mode mode_idx--; } } // Wait 3 seconds before lowering the level again _delay_ms(3000); } #endif sleep_mode(); } return 0; // Standard Return Code }
Find difference