3
* MGdriver - Off-time MultiGroup Driver by odd, based on luxdrv030 by DrJones
6
* License: CC-BY-NC-SA (non-commercial use only, derivative works must be under the same license)
9
* Main differences to luxdrvß30:
10
* - REMOVED: Ramping mode
11
* - REMOVED: Wear leveling
12
* - CHANGED: OFFTime memory instead of ONTime memory
13
* - ADDED: Multiple groups
14
* - ADDED: Memory or nomemory selectable for each group
15
* - ADDED: Simple UI for switching groups
19
#include <avr/pgmspace.h>
21
#include <util/delay_basic.h>
22
#include <avr/interrupt.h>
23
#include <avr/sleep.h>
24
#include <avr/eeprom.h>
31
#define NOINIT __attribute__ ((section (".noinit")))
34
#define MODES_0 NOMEM, 255, 0 , 0, 0 , 0 // Fill unused modes with pwm level 0
35
#define MODES_1 MEM, 25, 255 , 0 , 0 , 0
36
#define MODES_2 NOMEM, 25, 255 , 0 , 0 , 0
37
#define MODES_3 MEM, 255, 25 , 0 , 0 , 0
38
#define MODES_4 NOMEM, 255, 25 , 0 , 0 , 0
39
#define MODES_5 MEM, 25, 64 , 255 , 0 , 0
40
#define MODES_6 NOMEM, 25, 64 , 255 , 0 , 0
41
#define MODES_7 MEM, 255, 64 , 25 , 0 , 0
42
#define MODES_8 NOMEM, 255, 64 , 25 , 0 , 0
43
#define MODES_9 NOMEM, 6, 25 , 64 , 255 , 0
44
#define MODES_10 NOMEM, 25, 64 , 255 , STROBE , 0
45
#define MODES_11 NOMEM, 6 , 25 , 64 ,BEACON, STROBE
46
#define LENGTH_MODES 6 // 5 modes per group +1 for memory seletion
47
#define NUM_GROUPS 12 // 12 groups
48
PROGMEM const byte groups[NUM_GROUPS][LENGTH_MODES]={
49
{MODES_0} , {MODES_1} , //delete or add groups here
50
{MODES_2} , {MODES_3} ,
51
{MODES_4} , {MODES_5} ,
52
{MODES_6} , {MODES_7} ,
53
{MODES_8} , {MODES_9} ,
54
{MODES_10}, {MODES_11} };
63
#define portinit() do{ DDRB=(1<<outpin); PORTB=0xff-(1<<outpin)-(1<<adcpin); }while(0)
65
#define WDTIME 0b01000011 //125ms
67
#define sleepinit() do{ WDTCR=WDTIME; sei(); MCUCR=(MCUCR &~0b00111000)|0b00100000; }while(0)
69
#define SLEEP asm volatile ("SLEEP")
71
#define pwminit() do{ TCCR0A=0b00100001; TCCR0B=0b00000001; }while(0)
73
#define adcinit() do{ ADMUX =0b01100000|adcchn; ADCSRA=0b11000100; }while(0)
74
#define adcread() do{ ADCSRA|=64; while (ADCSRA&64); }while(0)
75
#define adcresult ADCH
77
#define ADCoff ADCSRA&=~(1<<7)
78
#define ADCon ADCSRA|=(1<<7)
79
#define ACoff ACSR|=(1<<7)
80
#define ACon ACSR&=~(1<<7)
83
EEMEM byte eemode = 1; //Saving mode and group in EEPROM, no wear leveling
84
EEMEM byte eegroup = 1;
86
volatile byte ticks = 0;
92
byte decay NOINIT; //Using the NOINIT section of the RAM
93
byte shortcounter NOINIT;
94
byte lowbattcounter = 0;
99
if (ticks == RESETTIME)
100
shortcounter=0; // Setting back the counter for repeated shortpresses, so we
101
// never enter programming mode by accident
107
if (adcresult < BATTMON) {
108
if (++lowbattcounter > 40) {
109
mypwm = (mypwm >> 1) + 3;
118
void _delay_ms(uint16_t n) {
120
while(n-- > 0) _delay_loop_2(950);
124
inline void getmode(void) {
126
mode=eeprom_read_byte(&eemode); //reading mode and group from EEPROM
127
group=eeprom_read_byte(&eegroup);
128
memory=pgm_read_byte(&groups[group][0]); // reading memory from the 2D-array stored in flash
129
if (!decay) { // fast press
131
//wrap around if it is last mode of the group or a unused mode
132
if ((mode > LENGTH_MODES) || (!(pgm_read_byte(&groups[group][mode]))))
135
shortcounter += 1; //count number of short-presses
138
if (memory == NOMEM) {
142
shortcounter = 0; //Set back the counter for repeated shortpresses
144
decay=0; //Set back decay for long/shortpress detection
146
eeprom_write_byte(&eemode, mode);
169
pmode= pgm_read_byte(&groups[group][mode]);
171
if (shortcounter>15) { // 15 or more short presses, enter programming mode
174
_delay_ms(2000); // to switch to the next group, press switch when light
175
shortcounter = 0; // goes off after 2sec, or wait until it turn on again to cancel
176
// switching the group
178
if (group >= NUM_GROUPS)
181
eeprom_write_byte(&eegroup, group);
182
eeprom_write_byte(&eemode, 1);
188
group = (NUM_GROUPS-1);
189
eeprom_write_byte(&eegroup, group);
209
break; //strobe 12.5Hz //+48
218
while (i > BATTMON) {
220
SLEEP; //SLEEP instead of delay_ms saves a few bytes here
239
break; //beacon 10s //+48
b'\\ No newline at end of file'