Diff
checker
テキスト
テキスト
画像
ドキュメント
Excel
フォルダ
Legal
Enterprise
デスクトップ
料金
ログイン
Diffchecker デスクトップのダウンロード
テキスト比較
2 つのテキスト ファイルの違いを見つける
ツール
履歴
ライブエディター
未変更行を折りたたむ
折り返しなし
レイアウト
分割
統合
比較精度
スマート
単語
文字
シンタックスハイライト
構文を選択
無視
テキスト変換
最初の差分へ移動
入力を編集
Diffchecker Desktop
Diffcheckerを実行する最も安全な方法。Diffchecker Desktopアプリを入手:あなたの差分はコンピューターから出ることはありません!
Desktopを入手
Untitled diff
作成日
11 年前
差分は期限切れになりません
クリア
エクスポート
共有
説明
21 削除
行
合計
削除
文字
合計
削除
この機能を引き続き使用するには、アップグレードしてください
Diff
checker
Pro
価格を見る
287 行
すべてコピー
26 追加
行
合計
追加
文字
合計
追加
この機能を引き続き使用するには、アップグレードしてください
Diff
checker
Pro
価格を見る
296 行
すべてコピー
コピー
コピー済み
コピー
コピー済み
*
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
コピー
コピー済み
コピー
コピー済み
#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
コピー
コピー済み
コピー
コピー済み
#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
コピー
コピー済み
コピー
コピー済み
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
コピー
コピー済み
コピー
コピー済み
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
コピー
コピー済み
コピー
コピー済み
// Moon
(stock is 1 then 0)
// Moon
#ifdef MODE_MOON
#ifdef MODE_MOON
コピー
コピー済み
コピー
コピー済み
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
コピー
コピー済み
コピー
コピー済み
#ifdef MODE_
1
#ifdef MODE_
LOW
modes[mode_cnt++] = MODE_
1
;
modes[mode_cnt++] = MODE_
LOW
;
#endif
#endif
コピー
コピー済み
コピー
コピー済み
#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;
}
}
コピー
コピー済み
コピー
コピー済み
// 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
}
}
保存された差分
原文
ファイルを開く
*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 }
変更されたテキスト
ファイルを開く
#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 }
違いを見つける