~gabe/flashlight-firmware/anduril2

« back to all changes in this revision

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

  • Committer: Selene Scriven
  • Date: 2015-09-11 01:11:43 UTC
  • Revision ID: ubuntu@toykeeper.net-20150911011143-0qk3qa06vqscgoin
updated meta files to reflect attiny25 support

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//
 
2
// LuxDrv 0.1    DrJones 2011 
 
3
//
 
4
// 630 bytes (with timer)
 
5
//
 
6
// License: Free for private and noncommercial use for members of BudgetLightForum
 
7
 
 
8
 
 
9
//ToDo: 
 
10
//  Batt-ADC (ADC1) with mode down-shifting 
 
11
//  BATT indicator using blinks in beacon-mode
 
12
//  ? Ramping
 
13
//  ? off-time checking; requires adding  diode,R,C
 
14
//  ? blink your name in morse code :)
 
15
 
 
16
 
 
17
 
 
18
 
 
19
#define outpin 1
 
20
 #define PWM OCR0B  //PWM-value
 
21
 
 
22
#define portinit() do{ DDRB=(1<<outpin); PORTB=0xff-(1<<outpin);  }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 are special mode codes handled differently, all other are PWM values
 
34
 
 
35
#define F_CPU 4800000    //CPU: 4.8MHz  PWM: 9.4kHz    // low fuse: 0x75    //+16bytes compared to 1.2MHz 
 
36
PROGMEM byte modes[]={ 255,    6,51,255,    5,6,14,37,98,255,   251,   252,   253  };  // 9kHz modes, 5 is lowest
 
37
//                     dummy   main modes   more levels         strobe,beacon,timer
 
38
 
 
39
 
 
40
//#define F_CPU 1200000  //CPU: 1.2MHz  PWM: 2.35kHz  //low fuse: 0x66
 
41
//PROGMEM byte modes[]={ 255,    2,51,255,    2,5,14,37,98,255,   251,   252,   253  };  //2.35kHz modes, 2 is lowest
 
42
////                     dummy   main modes   more levels         strobe,beacon,timer
 
43
 
 
44
 
 
45
//#define F_CPU 600000   //CPU: 0.6MHz  PWM: 1.18kHz   //low fuse: 0x65
 
46
//PROGMEM byte modes[]={ 255,    2,51,255,    1,5,14,37,98,255,   251,   252,   253  };  //1.18kHz modes, 1 is lowest
 
47
////                     dummy   main modes   more levels         strobe,beacon,timer
 
48
 
 
49
 
 
50
//###########################################################################################
 
51
 
 
52
#include <avr/io.h>
 
53
#include <util/delay.h>
 
54
#include <avr/interrupt.h>
 
55
#include <avr/sleep.h>
 
56
#include <avr/eeprom.h>
 
57
 
 
58
 
 
59
#define WDTIME 0b01000011  //125ms
 
60
 
 
61
#define sleepinit() do{ WDTCR=WDTIME; sei(); MCUCR=(MCUCR &~0b00111000)|0b00100000; }while(0) //WDT-int and Idle-Sleep
 
62
 
 
63
#define pwminit() do{ TCCR0A=0b00100001; TCCR0B=0b00000001; }while(0)  //chan A, phasePWM, clk/1  ->2.35kHz@1.2MHz
 
64
 
 
65
 
 
66
#define SLEEP asm volatile ("SLEEP")
 
67
#define ADCoff ADCSRA&=~(1<<7) //ADC off (enable=0);
 
68
#define ADCon  ADCSRA|=(1<<7)  //ADC on
 
69
#define ACoff  ACSR|=(1<<7)    //AC off (disable=1)
 
70
#define ACon   ACSR&=~(1<<7)   //AC on  (disable=0)
 
71
 
 
72
 
 
73
//_____________________________________________________________________________________________________________________
 
74
 
 
75
 
 
76
//saving a few byte by doing that inline
 
77
inline void eepwrite(byte addr, byte data) {  while(EECR & 2); EEARL=addr; EEDR=data; EECR =4; EECR =6;  }
 
78
inline byte eepread(byte addr)             {  while(EECR & 2); EEARL=addr; EECR=1; return EEDR;  }
 
79
 
 
80
 
 
81
volatile byte mypwm=0;
 
82
volatile byte ticks=0;
 
83
byte mode=1;
 
84
byte pmode=50;
 
85
 
 
86
byte eep[32];  //EEPROM buffer
 
87
byte eepos=0;
 
88
 
 
89
 
 
90
inline void getmode(void) {  //read current mode from EEPROM and write next mode
 
91
 
 
92
  eeprom_read_block(&eep, 0, sizeof(eep));  //+44                //read block 
 
93
  while((eep[eepos]==0) && (eepos<sizeof(eep))) eepos++; //+16   //find mode byte
 
94
  if (eepos<sizeof(eep)) mode=eep[eepos];
 
95
  else eepos=0;   //+6  //not found
 
96
 
 
97
  byte next=1;
 
98
  if (mode & 0x80) {  //last on-time was short
 
99
    mode&=0x7f;   if (mode>=sizeof(modes)) mode=1;
 
100
    next=mode+1;  if (next>=sizeof(modes)) next=1; 
 
101
  } //else next=1;  //previous mode was locked, this one is yet a short on, so restart from 1st mode.
 
102
  eepwrite(eepos,next|0x80); //write next mode, with short-on marker
 
103
}
 
104
 
 
105
inline void savemode(void) {   //lock mode: keep this mode for next time
 
106
  eepwrite(eepos,0);  
 
107
  eepos=(eepos+1)&31;   //+12  //wear leveling, use next cell
 
108
  eepwrite(eepos,mode);
 
109
}
 
110
 
 
111
 
 
112
 
 
113
 
 
114
ISR(WDT_vect) {   //WatchDogTimer Interrupt
 
115
if (ticks<255) ticks++;
 
116
if (ticks==16) savemode();  //lock mode after 2s
 
117
}
 
118
 
 
119
 
 
120
 
 
121
 
 
122
int main(void) {
 
123
 
 
124
  portinit();
 
125
  sleepinit();
 
126
  ACoff;
 
127
  ADCoff;
 
128
  pwminit();
 
129
 
 
130
  getmode();  //get mode# to use
 
131
 
 
132
  pmode=pgm_read_byte(&modes[mode]);  //read actual PWM value/special code
 
133
  byte i;
 
134
 
 
135
  switch(pmode){
 
136
 
 
137
    case 251:  mypwm=255; while(1){ PWM=mypwm; _delay_ms(20); PWM=0; _delay_ms(60); } break;                 //strobe 12.5Hz  //+48
 
138
 
 
139
    case 252:  mypwm=255; while(1){ PWM=mypwm; _delay_ms(20); PWM=0; i=70;do{SLEEP;}while(--i);  } break;  //beacon 10s     //+48
 
140
 
 
141
    case 253:  i=5; do{ byte j=i; do{PWM=255; _delay_ms(20); PWM=8; _delay_ms(300); }while(--j); //blink remaining minutes   
 
142
                             byte k=59;do{_delay_ms(1000);PWM^=8;}while(--k);                      //wait 1 minute
 
143
                         }while(--i);                                                               //for 5 min
 
144
               i=100; do{ PWM=255; _delay_ms(30); PWM=0; _delay_ms(70); }while(--i);              //strobe 10s
 
145
               while(1){PWM^=8;SLEEP;}                                                              //"off"                 //+136
 
146
               break;
 
147
 
 
148
    default:   mypwm=pmode; while(1){PWM=mypwm;SLEEP;}   //all other: PWM value
 
149
 
 
150
   //mypwm: prepared for being ramped down in WDT on low-batt condition.
 
151
 
 
152
  }//switch
 
153
  return 0;
 
154
}//main
 
155