~gabe/flashlight-firmware/anduril2

« back to all changes in this revision

Viewing changes to DrJones/luxdrv/luxdrv-022.c

  • Committer: Selene Scriven
  • Date: 2017-09-12 23:34:36 UTC
  • mto: (188.1.3 trunk)
  • mto: This revision was merged to the branch mainline in revision 331.
  • Revision ID: bzr@toykeeper.net-20170912233436-d3w6nln0ts1subue
Added Flintrock's Bistro-HD 1.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//
 
2
// LuxDrv 0.22    DrJones 2011 
 
3
//
 
4
// 878 bytes with ramping, 696 bytes without   (both with new timer)  
 
5
//
 
6
// License: Free for private and noncommercial use for members of BudgetLightForum
 
7
//
 
8
// changes:
 
9
// 0.1  first version: levels,strobe,beacon,timer(136)   (638bytes)
 
10
// 0.2  ramping(200), improved timer(180), skip mode1 as next mode if already in mode 1     (898bytes)
 
11
// 0.21 changed EEPROM handling to reduce power-off-while-writing glitches -->eepsave(byte)  (874bytes)
 
12
// 0.22 bugfix in ramping; mode not stored on (very) short tap   (878bytes)
 
13
 
 
14
 
 
15
 
 
16
#define outpin 1
 
17
 #define PWM OCR0B  //PWM-value
 
18
 
 
19
#define adcpin 2
 
20
 #define adcchn 1
 
21
 
 
22
#define portinit() do{ DDRB=(1<<outpin); PORTB=0xff-(1<<outpin)-(1<<adcpin);  }while(0)
 
23
 
 
24
 
 
25
 
 
26
#include <avr/pgmspace.h>
 
27
#define byte uint8_t
 
28
#define word uint16_t
 
29
 
 
30
 
 
31
//########################################################################################### MODE/PWM SETUP 
 
32
 
 
33
//251, 252, 253, 254 are special mode codes handled differently, all other are PWM values
 
34
 
 
35
#define F_CPU 4800000    //CPU: 4.8MHz  PWM: 9.4kHz       ####### use low fuse: 0x75  #######   
 
36
PROGMEM byte modes[]={ 0,      6,51,255,    254,                   251,    252,    253 };  // with ramping
 
37
//                     dummy   main modes   ramping, ramped mode,  strobe, beacon, timer
 
38
#define TIMER 5     //use timer (5 min, max 6 in this setup)
 
39
#define RAMPING     //use ramping
 
40
#define MINPWM   5  //needed for ramping
 
41
#define RAMPMODE 4  //the number of the ramping mode (254) in the modes[] order; e.g. ramping is 4th mode -> 4; not counting dummy
 
42
 
 
43
 
 
44
//PROGMEM byte modes[]={ 0,      6,51,255,    5,6,14,37,98,255,   251,   252,   253  };  // 9kHz modes, 5 is lowest, no ramping
 
45
////                     dummy   main modes   more levels         strobe,beacon,timer
 
46
 
 
47
 
 
48
//###########################################################################################
 
49
 
 
50
#include <avr/io.h>
 
51
#include <util/delay.h>
 
52
#include <avr/interrupt.h>
 
53
#include <avr/sleep.h>
 
54
#include <avr/eeprom.h>
 
55
 
 
56
 
 
57
 
 
58
#define WDTIME 0b01000011  //125ms
 
59
 
 
60
#define sleepinit() do{ WDTCR=WDTIME; sei(); MCUCR=(MCUCR &~0b00111000)|0b00100000; }while(0) //WDT-int and Idle-Sleep
 
61
 
 
62
#define SLEEP asm volatile ("SLEEP")
 
63
 
 
64
#define pwminit() do{ TCCR0A=0b00100001; TCCR0B=0b00000001; }while(0)  //chan A, phasePWM, clk/1  ->2.35kHz@1.2MHz
 
65
 
 
66
 
 
67
 
 
68
#define ADCoff ADCSRA&=~(1<<7) //ADC off (enable=0);
 
69
#define ADCon  ADCSRA|=(1<<7)  //ADC on
 
70
#define ACoff  ACSR|=(1<<7)    //AC off (disable=1)
 
71
#define ACon   ACSR&=~(1<<7)   //AC on  (disable=0)
 
72
 
 
73
 
 
74
//_____________________________________________________________________________________________________________________
 
75
 
 
76
 
 
77
volatile byte mypwm=0;
 
78
volatile byte ticks=0;
 
79
byte mode=1;
 
80
byte pmode=50;
 
81
 
 
82
byte eep[32];  //EEPROM buffer
 
83
byte eepos=0;
 
84
 
 
85
#ifdef RAMPING
 
86
  byte ramped=0;
 
87
#endif
 
88
 
 
89
 
 
90
 
 
91
 
 
92
void eepsave(byte data) {  //central method for writing (with wear leveling)
 
93
  byte oldpos=eepos;
 
94
  eepos=(eepos+1)&31;  //wear leveling, use next cell
 
95
  EEARL=eepos; EEDR=data; EECR=32+4; EECR=32+4+2;  //WRITE  //32:write only (no erase)  4:enable  2:go
 
96
  while(EECR & 2); //wait for completion
 
97
  EEARL=oldpos;           EECR=16+4; EECR=16+4+2;  //ERASE  //16:erase only (no write)  4:enable  2:go
 
98
}
 
99
 
 
100
 
 
101
 
 
102
inline void getmode(void) {  //read current mode from EEPROM and write next mode
 
103
 
 
104
  eeprom_read_block(&eep, 0, 32);  //+44                //read block 
 
105
  while((eep[eepos]==0xff) && (eepos<32)) eepos++; //+16   //find mode byte
 
106
  if (eepos<32) mode=eep[eepos];
 
107
  else eepos=0;   //+6  //not found
 
108
 
 
109
  byte next=1;
 
110
  if (mode==1) next=2;  //+10
 
111
 
 
112
#ifdef RAMPING  
 
113
  if (mode & 0x40) {   //RAMPING
 
114
    ramped=1;
 
115
    if (mode & 0x80)  { next=RAMPMODE+1; mode&=0x7f; } //mode: for savemode
 
116
    //else next=1
 
117
  }else              //ENDRAMPING
 
118
#endif
 
119
 
 
120
  if (mode & 0x80) {  //last on-time was short
 
121
    mode&=0x7f;   if (mode>=sizeof(modes)) mode=1;
 
122
    next=mode+1;  if (next>=sizeof(modes)) next=1; 
 
123
  } //else next=1;  //previous mode was locked, this one is yet a short-on, so set to restart from 1st mode.
 
124
 
 
125
  eepsave(next|0x80); //write next mode, with short-on marker
 
126
}
 
127
 
 
128
 
 
129
 
 
130
 
 
131
 
 
132
ISR(WDT_vect) {  //WatchDogTimer interrupt
 
133
if (ticks<255) ticks++;
 
134
if (ticks==16) eepsave(mode);  //lock mode after 2s
 
135
//code to check voltage and ramp down goes here: do ADC; average?; if (value<threshold) mypwm=(mypwm>>1)+3; 
 
136
}
 
137
 
 
138
 
 
139
 
 
140
 
 
141
 
 
142
 
 
143
int main(void) {
 
144
 
 
145
  portinit();
 
146
  sleepinit();
 
147
  ACoff;
 
148
  ADCoff;
 
149
  pwminit();
 
150
 
 
151
  getmode();  //get current mode number from EEPROM
 
152
 
 
153
  byte i=0;
 
154
 
 
155
#ifdef RAMPING
 
156
  byte p,j=0,dn=1;  //for ramping
 
157
 
 
158
  if (ramped) {  //use the ramped mode
 
159
     pmode=255; i=30-MINPWM-(mode&0x3f); while(i--){pmode=pmode-(pmode>>3)-1;}  //get PWM value  //never gives 250..254
 
160
  } else
 
161
#endif
 
162
 
 
163
  pmode=pgm_read_byte(&modes[mode]);  //get actual PWM value (or special mode code)
 
164
 
 
165
 
 
166
  switch(pmode){
 
167
 
 
168
    case 251:  mypwm=255; while(1){ PWM=mypwm; _delay_ms(20); PWM=0; _delay_ms(60); } break; //strobe 12.5Hz  //+48
 
169
 
 
170
    case 252:  mypwm=255; while(1){ PWM=mypwm; _delay_ms(20); PWM=0; i=70;do{SLEEP;}while(--i);  } break;  //beacon 10s //+48
 
171
 
 
172
#ifdef TIMER
 
173
    case 253:  i=TIMER; do{                   //+180
 
174
                 byte j=i; do{PWM=255; _delay_ms(20); PWM=0; _delay_ms(300); }while(--j); //blink remaining minutes   
 
175
                 byte k=30; do{ byte m=0; do{                                             //wait 1 minute
 
176
                   if (m<i) {_delay_ms(233);PWM=8;_delay_ms(90);PWM=0;}
 
177
                   else      _delay_ms(333);
 
178
                 }while(++m<6);    }while(--k);
 
179
               }while(--i);                                                               //for TIMER min
 
180
               i=100; do{ PWM=255; _delay_ms(30); PWM=0; _delay_ms(70); }while(--i);             //strobe 10s
 
181
               while(1){PWM^=8;SLEEP;}                                                           //"off"
 
182
               break;
 
183
#endif
 
184
 
 
185
#ifdef RAMPING
 
186
    case 254:  ticks=100; //crude way to deactivate the 2s-lock       //RAMPING
 
187
               while(EECR & 2); //wait for completion of getmode's write
 
188
               while(1){ p=255; i=30-MINPWM-j; while(i--){p=p-(p>>3)-1;}   //ramp up
 
189
                         PWM=p;
 
190
                         eepsave(192+j);    
 
191
                         SLEEP;
 
192
                         if (dn) {if (j          ) j--; else {dn=0;SLEEP;SLEEP;} } 
 
193
                         else    {if (j<30-MINPWM) j++; else {dn=1;SLEEP;SLEEP;} } //wear leveling
 
194
               } break;
 
195
#endif
 
196
 
 
197
    default:   mypwm=pmode; while(1){PWM=mypwm;SLEEP;}  //all other: us as PWM value
 
198
 
 
199
   //mypwm: prepared for being ramped down in WDT on low-batt condition.
 
200
 
 
201
  }//switch
 
202
  return 0;
 
203
}//main
 
204