b1c63325a361758b66efe2928f67db7ac5dd900c
[owSlave2.git] / DS2423_komische platine / DS2423.c
1 \r
2 // Copyright (c) 2016, Tobias Mueller tm(at)tm3d.de\r
3 // All rights reserved.\r
4 //\r
5 // Redistribution and use in source and binary forms, with or without\r
6 // modification, are permitted provided that the following conditions are\r
7 // met:\r
8 //\r
9 //  * Redistributions of source code must retain the above copyright\r
10 //    notice, this list of conditions and the following disclaimer.\r
11 //  * Redistributions in binary form must reproduce the above copyright\r
12 //    notice, this list of conditions and the following disclaimer in the\r
13 //    documentation and/or other materials provided with the\r
14 //    distribution.\r
15 //  * All advertising materials mentioning features or use of this\r
16 //    software must display the following acknowledgement: This product\r
17 //    includes software developed by tm3d.de and its contributors.\r
18 //  * Neither the name of tm3d.de nor the names of its contributors may\r
19 //    be used to endorse or promote products derived from this software\r
20 //    without specific prior written permission.\r
21 //\r
22 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
23 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
24 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r
25 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\r
26 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r
27 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r
28 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
29 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
30 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
31 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\r
32 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
33 \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 \r
45 extern void OWINIT();\r
46 \r
47 uint8_t owid[8]={0x1D, 0xA2, 0xD9, 0x84, 0x00, 0x26, 0x02, 0x5C};/**/\r
48 uint8_t config_info[18]={0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};\r
49 \r
50         \r
51 \r
52 extern uint8_t mode;\r
53 extern uint8_t gcontrol;\r
54 extern uint8_t reset_indicator;\r
55 \r
56 \r
57 volatile uint8_t wdcounter;\r
58 \r
59 \r
60 \r
61 \r
62 typedef union {\r
63         volatile uint8_t bytes[45];\r
64         struct {\r
65                 uint16_t addr;\r
66                 uint8_t status;\r
67                 uint8_t scratch[32];//3\r
68                 uint32_t counter;  //35\r
69                 uint32_t zero;   //39\r
70                 uint16_t crc;  //43\r
71         };\r
72 } counterpack_t;\r
73 counterpack_t pack;\r
74 \r
75 typedef union {\r
76         uint32_t c32[4];\r
77         uint8_t c8[16];\r
78 } counters_t;\r
79 \r
80 volatile counters_t counters;\r
81 \r
82 volatile uint8_t istat;\r
83 \r
84 #define PCINT_VECTOR PCINT0_vect\r
85 #define PIN_REG PINA\r
86 #define PIN_DDR DDRA\r
87 #define PIN_CH0 (1<<PINA3)\r
88 #define PIN_CH1 (1<<PINA4)\r
89 #define PIN_CH2 (1<<PINA1)\r
90 #define PIN_CH3 (1<<PINA2)\r
91 #define LPIN_CH2 (1<<PINB0)\r
92 #define LDD_CH2 DDRB\r
93 #define LPORT_CH2 PORTB\r
94 #define LPIN_CH3 (1<<PINA5)\r
95 #define LDD_CH3 DDRA\r
96 #define LPORT_CH3 PORTA\r
97 #define LPIN_CH0 (1<<PINA7)\r
98 #define LDD_CH0 DDRA\r
99 #define LPORT_CH0 PORTA\r
100 #define LPIN_CH1 (1<<PINB1)\r
101 #define LDD_CH1 DDRB\r
102 #define LPORT_CH1 PORTB\r
103 #define PORT_EE PINA //WARNING have to be the same PORT like PINREG because of istat\r
104 #define PIN_EE (1<<PINA0)\r
105 #define TEST_TIMER  ((TIMSK0 & (1<<TOIE0))==0)\r
106 \r
107 \r
108 \r
109 ISR(PCINT0_vect) {\r
110         if (((PIN_REG&PIN_CH0)==0)&&((istat&PIN_CH0)==PIN_CH0)) {       counters.c32[0]++;      LPORT_CH2|=LPIN_CH2;}\r
111         if (((PIN_REG&PIN_CH1)==0)&&((istat&PIN_CH1)==PIN_CH1)) {       counters.c32[1]++;      LPORT_CH2|=LPIN_CH2;}\r
112         if (((PIN_REG&PIN_CH2)==0)&&((istat&PIN_CH2)==PIN_CH2)) {       counters.c32[2]++;      LPORT_CH2|=LPIN_CH2;}\r
113         if (((PIN_REG&PIN_CH3)==0)&&((istat&PIN_CH3)==PIN_CH3)) {       counters.c32[3]++;      LPORT_CH2|=LPIN_CH2;}\r
114 \r
115         if (((PORT_EE&PIN_EE)==0)&&((istat&PIN_EE)==PIN_EE))  {\r
116                 \r
117                 _delay_ms(50);\r
118         if (((PORT_EE&PIN_EE)==0))  {\r
119 \r
120                 \r
121 \r
122                 LPORT_CH1|=LPIN_CH1;\r
123                 EEARH=0;\r
124                 for(uint8_t i=0;i<16;i++) {\r
125                         uint8_t addr=i^0x0C;\r
126                         while(EECR & (1<<EEPE));\r
127                         EECR = (0<<EEPM1)|(0<<EEPM0);\r
128                         EEARL = i;\r
129                         EEDR = counters.c8[addr];\r
130                         EECR |= (1<<EEMPE);\r
131                         EECR |= (1<<EEPE);\r
132                 }\r
133                 _delay_ms(250);\r
134                 LPORT_CH1&=~LPIN_CH1;\r
135 \r
136         }\r
137         GIFR|=(1<<PCIF0);\r
138         }\r
139         if ((((PINA&(1<<PINA6)))==0)&&((istat&(1<<PINA6))==(1<<PINA6)))   {\r
140                 _delay_ms(100);\r
141                 if (((PINA&(1<<PINA6)))==0) {\r
142                         LPORT_CH3|=LPIN_CH3;\r
143                         _delay_ms(100);\r
144 \r
145                         counters.c32[0]=0;\r
146                         counters.c32[2]=0;\r
147                         counters.c32[1]=0;\r
148                         counters.c32[3]=0;\r
149                         LPORT_CH3&=~LPIN_CH3;\r
150                         }\r
151                 GIFR|=(1<<PCIF0);\r
152 \r
153         }\r
154         istat=PIN_REG;\r
155         \r
156 }\r
157 \r
158 \r
159 int main(void){\r
160     PRR|=(1<<PRUSI)|(1<<PRADC);  //Switch off usi and adc for save Power\r
161         OWINIT();\r
162         \r
163         pack.zero=0;\r
164         counters.c32[0]=0;\r
165         counters.c32[2]=0;\r
166         counters.c32[1]=0;\r
167         counters.c32[3]=0;\r
168         ACSR|=(1<<ACD);  //Disable Comparator\r
169         ADCSRB|=(1<<ACME); //Disable Analog multiplexer\r
170         MCUCR &=~(1<<PUD); //All Pins Pullup...\r
171 \r
172         PORTB|=0xFF-(1<<PINB2); //Make PullUp an all Pins but not OW_PIN\r
173         PORTA|=0xFF; \r
174         PORTA&=~((1<<PINA1)|(1<<PINA2)|(1<<PINA3)|(1<<PINA4));\r
175                                 \r
176         GIMSK|=(1<<PCIE0);\r
177         PCMSK0=(1<<PCINT1)|(1<<PCINT2)|(1<<PCINT3)|(1<<PCINT4);\r
178         //Spannungsdetektor\r
179         DDRA&=~(1<<PINA0);\r
180         PCMSK0|=(1<<PCINT0);\r
181         PORTA&=~(1<<PINA0);\r
182         //Taster\r
183         DDRA&=~(1<<PINA6);\r
184         PCMSK0|=(1<<PCINT6);\r
185         PORTA|=(1<<PINA6); //Pullup\r
186 \r
187 \r
188 \r
189         LDD_CH0|=LPIN_CH0;\r
190         LPORT_CH0&=~LPIN_CH0;\r
191         LDD_CH1|=LPIN_CH1;\r
192         LPORT_CH1&=~LPIN_CH1;\r
193         LDD_CH2|=LPIN_CH2;\r
194         LPORT_CH2&=~LPIN_CH2;\r
195         LDD_CH3|=LPIN_CH3;\r
196         LPORT_CH3&=~LPIN_CH3;\r
197 \r
198 \r
199 \r
200         LPORT_CH0|=LPIN_CH0;\r
201         _delay_ms(500);\r
202         LPORT_CH0&=~LPIN_CH0;\r
203         \r
204         istat=PINA;\r
205         EEARH=0;\r
206         uint8_t addr;\r
207         for(uint8_t i=0;i<16;i++) {\r
208                 addr=i^0x0C;\r
209                 while(EECR & (1<<EEPE));   \r
210                 EEARL=i;\r
211                 EECR |= (1<<EERE);\r
212                 counters.c8[addr]=EEDR;\r
213         }\r
214         for (uint8_t i=0;i<4;i++) {\r
215                 if (counters.c32[i]==0xFFFFFFFF) counters.c32[i]=0;\r
216                 //counters.c32[i]=0;\r
217         }\r
218 \r
219    \r
220         sei();\r
221     while(1)   {\r
222             if (LPORT_CH2&LPIN_CH2) {\r
223                         _delay_ms(50);\r
224                         LPORT_CH2&=~LPIN_CH2;\r
225                 }\r
226                 //Test if timer active and no sleep then Idle else Power Down\r
227                 if (TEST_TIMER&&(mode==0)) {\r
228                         MCUCR|=(1<<SE)|(1<<SM1); //Power Down, only low level on 1-Wire and pin change on PCINT wakes up\r
229                         MCUCR&=~(1<<ISC01);\r
230                 } else {\r
231                         MCUCR|=(1<<SE);\r
232                         MCUCR&=~(1<<SM1); \r
233                 }\r
234                 asm("SLEEP");\r
235    }\r
236 }