067b602bc85865a4c37b9a34ec7917452e0a154d
[owSlave2.git] / DS2423 - Autosave / DS2423.c
1 // Copyright (c) 2017, Tobias Mueller tm(at)tm3d.de\r
2 // All rights reserved.\r
3 //\r
4 // Redistribution and use in source and binary forms, with or without\r
5 // modification, are permitted provided that the following conditions are\r
6 // met:\r
7 //\r
8 //  * Redistributions of source code must retain the above copyright\r
9 //    notice, this list of conditions and the following disclaimer.\r
10 //  * Redistributions in binary form must reproduce the above copyright\r
11 //    notice, this list of conditions and the following disclaimer in the\r
12 //    documentation and/or other materials provided with the\r
13 //    distribution.\r
14 //  * All advertising materials mentioning features or use of this\r
15 //    software must display the following acknowledgement: This product\r
16 //    includes software developed by tm3d.de and its contributors.\r
17 //  * Neither the name of tm3d.de nor the names of its contributors may\r
18 //    be used to endorse or promote products derived from this software\r
19 //    without specific prior written permission.\r
20 //\r
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
22 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
23 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r
24 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\r
25 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r
26 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r
27 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
28 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
29 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
30 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\r
31 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
32 \r
33 #define _CPULLUP_\r
34 \r
35 #define F_CPU 8000000UL\r
36 #include <avr/io.h>\r
37 #include <avr/interrupt.h>\r
38 #include <util/delay.h>\r
39 #include <avr/wdt.h>\r
40 #include <avr/sleep.h>\r
41 \r
42 \r
43 \r
44 extern void OWINIT();\r
45 \r
46 uint8_t owid[8]={0x1D, 0xA2, 0xD9, 0x84, 0x00, 0x26, 0x02, 0x5C};/**/\r
47 uint8_t config_info[26]={9,13,9,13,9,13,9,13,0x02,19,19,19,19,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; //+2 for CRC\r
48 \r
49         \r
50 \r
51 extern uint8_t mode;\r
52 extern uint8_t gcontrol;\r
53 extern uint8_t reset_indicator;\r
54 \r
55 \r
56 \r
57 \r
58 \r
59 \r
60 typedef union {\r
61         volatile uint8_t bytes[45];\r
62         struct {\r
63                 uint16_t addr;\r
64                 uint8_t status;\r
65                 uint8_t scratch[32];//3\r
66                 uint32_t counter;  //35\r
67                 uint32_t zero;   //39\r
68                 uint16_t crc;  //43\r
69         };\r
70 } counterpack_t;\r
71 counterpack_t pack;\r
72 \r
73 volatile uint8_t lastcps;\r
74 typedef union {\r
75         uint32_t c32[4];\r
76         uint8_t c8[16];\r
77 } counters_t;\r
78 \r
79 volatile counters_t counters;\r
80 \r
81 volatile uint8_t istat;\r
82 volatile uint8_t changefromeeprom;\r
83 \r
84 \r
85 \r
86 #if  defined(__AVR_ATtiny24__)||defined(__AVR_ATtiny44__)  || defined(__AVR_ATtiny84__) || defined(__AVR_ATtiny24A__)||defined(__AVR_ATtiny44A__)  || defined(__AVR_ATtiny84A__)\r
87 #define PCINT_VECTOR PCINT0_vect\r
88 #define PIN_REG PINA\r
89 #define PIN_DDR DDRA\r
90 #define PIN_CH2 (1<<PINA4)\r
91 #define PIN_CH3 (1<<PINA5)\r
92 #define PIN_CH0 (1<<PINA6)\r
93 #define PIN_CH1 (1<<PINA7)\r
94 #define PORT_EE PINA //WARNING have to be the same PORT like PINREG because of istat\r
95 #define PIN_EE (1<<PINA0)\r
96 #define TEST_TIMER  ((TIMSK0 & (1<<TOIE0))==0)\r
97 \r
98 #endif\r
99 \r
100 \r
101 ISR(PCINT0_vect) {\r
102         if (((PIN_REG&PIN_CH2)==0)&&((istat&PIN_CH2)==PIN_CH2)) {       counters.c32[2]++;      }\r
103         if (((PIN_REG&PIN_CH3)==0)&&((istat&PIN_CH3)==PIN_CH3)) {       counters.c32[3]++;      }\r
104         if (((PIN_REG&PIN_CH0)==0)&&((istat&PIN_CH0)==PIN_CH0)) {       counters.c32[0]++;      }\r
105         if (((PIN_REG&PIN_CH1)==0)&&((istat&PIN_CH1)==PIN_CH1)) {       counters.c32[1]++;      }\r
106         istat=PIN_REG;\r
107         changefromeeprom=1;\r
108 }\r
109 \r
110 \r
111 ISR(ANA_COMP_vect) {\r
112         if (changefromeeprom==0) return;\r
113         if ((ACSR&(1<<ACO))!=0) {\r
114                 _delay_ms(5);\r
115                 if ((ACSR&(1<<ACO))!=0) {\r
116                         CLKPR=0x80;//Switch to 4 MHz \r
117                         CLKPR=01;                       \r
118                         \r
119                         PORTB|=(1<<PINB1);\r
120                         EEARH=0;\r
121                         for(uint8_t i=0;i<16;i++) {\r
122                                 uint8_t addr=i^0x0C;\r
123                                 while(EECR & (1<<EEPE));\r
124                                 EECR = (0<<EEPM1)|(0<<EEPM0);\r
125                                 EEARL = i;\r
126                                 EEDR = counters.c8[addr];\r
127                                 EECR |= (1<<EEMPE);\r
128                                 EECR |= (1<<EEPE);\r
129                         }\r
130                         changefromeeprom=0;\r
131                         PORTB&=~(1<<PINB1);\r
132                         CLKPR=0x80;\r
133                         CLKPR=0;\r
134                         GIFR|=(1<<INTF0);\r
135                 }\r
136         }\r
137         \r
138 }\r
139 \r
140 int testSW(void) {\r
141         uint8_t r;\r
142         DDRB&=~(1<<PORTB0);  //Eingang\r
143         __asm__ __volatile__ ("nop");\r
144         PORTB|=(1<<PORTB0); //Pullup\r
145         __asm__ __volatile__ ("nop");\r
146         __asm__ __volatile__ ("nop");\r
147         __asm__ __volatile__ ("nop");\r
148         __asm__ __volatile__ ("nop");\r
149         __asm__ __volatile__ ("nop");\r
150         r=PINB&(1<<PORTB0);\r
151         __asm__ __volatile__ ("nop");\r
152         PORTB&=~(1<<PORTB0);\r
153         __asm__ __volatile__ ("nop");\r
154         DDRB|=(1<<PORTB0);  //Eingang\r
155         return (r==0);\r
156         \r
157         \r
158 }\r
159 \r
160 \r
161 int main(void){\r
162     PRR|=(1<<PRUSI)|(1<<PRADC);  //Switch off usi and adc for save Power\r
163         OWINIT();\r
164         \r
165         pack.zero=0;\r
166         counters.c32[0]=0;\r
167         counters.c32[2]=0;\r
168         counters.c32[1]=0;\r
169         counters.c32[3]=0;\r
170         changefromeeprom=1;\r
171         ACSR|=(1<<ACD);  //Disable Comparator\r
172         ADCSRB|=(1<<ACME); //Disable Analog multiplexer\r
173         MCUCR &=~(1<<PUD); //All Pins Pullup...\r
174         \r
175 #if  defined(__AVR_ATtiny24__)||defined(__AVR_ATtiny44__)  || defined(__AVR_ATtiny84__) || defined(__AVR_ATtiny24A__)||defined(__AVR_ATtiny44A__)  || defined(__AVR_ATtiny84A__)\r
176 \r
177         PORTB|=0xFF-(1<<PINB2); //Make PullUp an all Pins but not OW_PIN\r
178         PORTA|=0xFF;\r
179         PORTA&=~(1<<PINA2); //AIN1 \r
180 #ifndef _CPULLUP_\r
181         PORTA&=~((1<<PINA4)|(1<<PINA5));\r
182         PORTA&=~((1<<PINA6)|(1<<PINA7));\r
183  #endif\r
184 \r
185         GIMSK|=(1<<PCIE0);\r
186         PCMSK0=(1<<PCINT4)|(1<<PCINT5)\r
187                 |(1<<PCINT6)|(1<<PCINT7);\r
188                         \r
189         \r
190         istat=PINB;\r
191 #endif\r
192 \r
193         EEARH=0;\r
194                 \r
195         uint8_t addr;\r
196         \r
197         if (testSW()) {  //Jumper gesetzt ->Ruecksetzen\r
198                 for(uint8_t i=0;i<16;i++) {\r
199                         while(EECR & (1<<EEPE));\r
200                         EECR = (0<<EEPM1)|(0<<EEPM0);\r
201                         EEARL = i;\r
202                         EEDR = 0;\r
203                         EECR |= (1<<EEMPE);\r
204                         EECR |= (1<<EEPE);\r
205                 }       \r
206         }       \r
207         \r
208         \r
209         for(uint8_t i=0;i<16;i++) {\r
210                 addr=i^0x0C;\r
211                 while(EECR & (1<<EEPE));   \r
212                 EEARL=i;\r
213                 EECR |= (1<<EERE);\r
214                 counters.c8[addr]=EEDR;\r
215         }\r
216         changefromeeprom=0;  //Daten neu eingelesen\r
217         for (uint8_t i=0;i<4;i++) {\r
218                 if (counters.c32[i]==0xFFFFFFFF) {\r
219                         counters.c32[i]=0;\r
220                         changefromeeprom=1;  //Daten geaendert\r
221                 }\r
222                         //counters.c32[i]=0;\r
223         }\r
224         \r
225 \r
226                 /*for(uint8_t i=0;i<16;i++) {\r
227                         while(EECR & (1<<EEPE));\r
228                         EECR = (1<<EEPM0);\r
229                         EEARL = i;\r
230                         EECR |= (1<<EEMPE);\r
231                         EECR |= (1<<EEPE);\r
232                 }*/\r
233         \r
234    \r
235 \r
236 \r
237         DIDR0|=(1<<ADC2D)|(1<<ADC1D); // Disable Digital input on Analog AIN0/AIN1  (PINA1 / PINA2)\r
238         ACSR&=~(1<<ACD);\r
239         ACSR|=(1<<ACIE)|(1<<ACIS1)|(1<<ACIS0)|(1<<ACBG); //Enabble comperator interrupt Rising edge....(1<<ACIS0)\r
240 \r
241         sei();\r
242         DDRB|=(1<<PINB1);\r
243         PORTB&=~(1<<PINB1);\r
244     while(1)   {\r
245                 \r
246                 MCUCR|=(1<<SE);\r
247                 MCUCR&=~(1<<SM1); \r
248                 asm("SLEEP");\r
249    }\r
250 }