Many changes from 2018
[owSlave2.git] / DS2450_DSM501A / DS2450_DSM501A.c
1 \r
2 // Copyright (c) 2017, 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 #define F_CPU 8000000UL\r
35 #include <avr/io.h>\r
36 #include <avr/interrupt.h>\r
37 #include <util/delay.h>\r
38 #include <avr/wdt.h>\r
39 #include <avr/sleep.h>\r
40 #include <avr/pgmspace.h>\r
41 \r
42 extern void OWINIT();\r
43 extern void EXTERN_SLEEP();\r
44 \r
45 uint8_t owid[8]={0x20, 0xA2, 0xD9, 0x84, 0x00, 0x16, 0x02, 0x5D};/**/\r
46 uint8_t config_info[26]={0x9,13,0x06,0x09,0x06,0x013,0x06,0x013,0x02,20,20,20,20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};\r
47 #if (owid>128) \r
48 #error "Variable not correct"\r
49 #endif\r
50 \r
51 extern uint8_t mode;\r
52 extern uint8_t gcontrol;\r
53 extern uint8_t reset_indicator;\r
54 extern uint8_t alarmflag;\r
55 \r
56 volatile uint16_t ltime_list[32];\r
57 volatile uint16_t pcount_list[32];\r
58 volatile uint8_t wsp=0;\r
59 volatile uint16_t max_count;\r
60 volatile uint16_t max_ptime=0;\r
61 volatile uint16_t min_ptime=0;\r
62 \r
63 uint16_t ds;\r
64 \r
65 \r
66 \r
67 typedef union {\r
68         volatile uint8_t bytes[0x20];\r
69         struct {\r
70                 //Page0\r
71                 uint16_t A;  //0\r
72                 uint16_t B;  //2\r
73                 uint16_t C;  //4\r
74                 uint16_t D;  //6\r
75                 //Page1\r
76                 uint8_t CSA1;\r
77                 uint8_t CSA2;\r
78                 uint8_t CSB1;\r
79                 uint8_t CSB2;\r
80                 uint8_t CSC1;\r
81                 uint8_t CSC2;\r
82                 uint8_t CSD1;\r
83                 uint8_t CSD2;\r
84                 //Page2\r
85                 uint8_t LA;\r
86                 uint8_t HA;\r
87                 uint8_t LB;\r
88                 uint8_t HB;\r
89                 uint8_t LC;\r
90                 uint8_t HC;\r
91                 uint8_t LD;\r
92                 uint8_t HD;\r
93                 //Page3\r
94                 uint8_t FC1;\r
95                 uint8_t FC2;\r
96                 uint8_t FC3;\r
97                 uint8_t FC4;\r
98                 uint8_t VCCP;\r
99                 uint8_t FC5;\r
100                 uint8_t FC6;\r
101                 uint8_t FC7;\r
102                 uint8_t convc1;\r
103                 uint8_t convc2;\r
104                 \r
105                 \r
106         };\r
107 } pack_t;\r
108 volatile pack_t pack;\r
109 \r
110 volatile uint16_t count;\r
111 volatile uint16_t ltime;\r
112 volatile uint16_t startt;\r
113 \r
114 #define SEC_TIME 31250+300\r
115 \r
116 ISR(TIM1_OVF_vect){\r
117         TCNT1=~(SEC_TIME);\r
118         ltime_list[wsp]=ltime;\r
119         pcount_list[wsp]=count;\r
120         wsp++;\r
121         if (wsp>=32) wsp=0;\r
122         //if (count>max) max=count;\r
123         //if (mess) \r
124         //count=(SEC_TIME)\r
125         startt=~(SEC_TIME);\r
126         count=0;\r
127         ltime=0;\r
128         \r
129 }\r
130 #define PIN_WIND (1<<PINA2)\r
131 #define PIN_REG PINA\r
132 volatile uint8_t istat;\r
133 volatile uint8_t mess=0;\r
134 \r
135 \r
136 ISR(PCINT0_vect) {\r
137         if (((PIN_REG&PIN_WIND)==0)&&((istat&PIN_WIND)==PIN_WIND)) {    \r
138          startt=TCNT1;\r
139          mess=1;\r
140         PORTB&=~(1<<PINB1);\r
141         }\r
142         if (((PIN_REG&PIN_WIND)==PIN_WIND)&&((istat&PIN_WIND)==0)) {\r
143                 uint16_t duration=(+TCNT1-startt);\r
144                 ltime+=duration;\r
145                 count++;\r
146                 if (min_ptime==0) min_ptime=duration;\r
147                 if (duration>max_ptime)max_ptime=duration;\r
148                 if (duration<min_ptime)min_ptime=duration;\r
149                 \r
150                 mess=0;\r
151         }\r
152 \r
153         istat=PIN_REG;\r
154         \r
155 }\r
156 \r
157 \r
158 int main(void){\r
159         for(uint8_t i=0;i<16;i++) {ltime_list[i]=0;pcount_list[i]=0;}\r
160         pack.A=0;\r
161         pack.B=0;\r
162         pack.C=0;\r
163         pack.D=0;\r
164         pack.CSA1=0x08;\r
165         pack.CSA2=0x8C;\r
166         pack.CSB1=0x08;\r
167         pack.CSB2=0x8C;\r
168         pack.CSC1=0x08;\r
169         pack.CSC2=0x8C;\r
170         pack.CSD1=0x08;\r
171         pack.CSD2=0x8C;\r
172         pack.HA=0xFF;\r
173         pack.LA=0x00;\r
174         pack.HB=0xFF;\r
175         pack.LB=0x00;\r
176         pack.HC=0xFF;\r
177         pack.LC=0x00;\r
178         pack.HD=0xFF;\r
179         pack.LD=0x00;\r
180         pack.VCCP=0;\r
181         OWINIT();\r
182 \r
183         MCUCR &=~(1<<PUD); //All Pins Pullup...\r
184         MCUCR |=(1<<BODS);\r
185         PORTA&=~((1<<PINA0)|(1<<PINA1)|(1<<PINA2)|(1<<PINA3));\r
186         ADCSRA=(1<<ADEN)|(1<ADPS0)|(1<<ADPS2);\r
187 \r
188         \r
189         \r
190         gcontrol=1;\r
191         ADCSRB|=(1<<ADLAR); \r
192         sei();\r
193         \r
194         DDRB|=(1<<PINB1);\r
195         TCCR1B|=(1<<CS12); //8000000/256 =31250\r
196         TIMSK1|=(1<<TOIE1); \r
197         istat=PIN_REG;\r
198         GIMSK|=(1<<PCIE0);\r
199         PCMSK0=(PIN_WIND);\r
200         MCUCR &=~(1<<PUD); //All Pins Pullup...\r
201         PORTA|=0xFF; \r
202     while(1)   {\r
203                 //PORTB&=~(1<<PINB1);\r
204 \r
205                 if (gcontrol) {\r
206                         //PORTB|=(1<<PINB1);\r
207                         uint8_t bb=1;\r
208                         uint8_t bb1=1;\r
209                         for(uint8_t i=0;i<4;i++){\r
210                                 if (pack.convc1&bb1) {\r
211                                         if (pack.convc2&(bb)) {pack.bytes[i*2]=0;pack.bytes[i*2+1]=0;}\r
212                                         bb=bb<<1;\r
213                                         if (pack.convc2&(bb)) {pack.bytes[i*2]=0xFF;pack.bytes[i*2+1]=0xFF;}\r
214                                         bb=bb<<1;\r
215                                 } else bb=bb<<2;\r
216                                 bb1=bb1<<1;                             \r
217                         }\r
218                         //CHanel A\r
219                         if (pack.convc1&1) {\r
220                                 //if (pack.CSA2&0x01)   ADMUX=0; else ADMUX=0x80;\r
221                                 //_delay_us(100);\r
222                                 //ADCSRA|=(1<<ADSC);\r
223                                 //while ((ADCSRA&(1<<ADSC)));\r
224                                 //cli();pack.A=ADC;sei();\r
225                                 ds=0;\r
226                                 for(uint8_t i=0;i<32;i++) {\r
227                                         ds+=pcount_list[i];\r
228                                         //if (wspeed[i]>ds) ds=wspeed[i];\r
229                                 }\r
230                                 cli();pack.A=ds;sei();\r
231                                 alarmflag=0;\r
232                                 if (pack.CSA2&0x08)  //AEH\r
233                                         if (pack.bytes[1]>pack.HA) {alarmflag=1;pack.CSA2|=0x20;}\r
234                                 if (pack.CSA2&0x04)  //AEL\r
235                                         if (pack.bytes[1]<pack.LA) {alarmflag=1;pack.CSA2|=0x10;}\r
236                         }\r
237 \r
238                         if (pack.convc1&2) {\r
239                                 double fds=0;\r
240                                 for(uint8_t i=0;i<32;i++) {\r
241                                         fds+=ltime_list[i];\r
242                                         //if (wspeed[i]>ds) ds=wspeed[i];\r
243                                 }\r
244                                 double lr=(fds/32.0)/(SEC_TIME)*65535/5.1;\r
245                                 cli();pack.B=lr;sei();\r
246                                 //max=0;\r
247                                 if (pack.CSB2&0x08)  //AEH\r
248                                         if (pack.bytes[1]>pack.HB) {alarmflag=1;pack.CSB2|=0x20;}\r
249                                 if (pack.CSB2&0x04)  //AEL\r
250                                         if (pack.bytes[1]<pack.LB) {alarmflag=1;pack.CSB2|=0x10;}\r
251                         }\r
252 \r
253                         if (pack.convc1&4) {\r
254                                 double mu_sek=(double)max_ptime/(SEC_TIME)*1e6;\r
255                                 max_ptime=0;\r
256                                 cli();pack.C=mu_sek;sei();\r
257                                 if (pack.CSC2&0x08)  //AEH\r
258                                         if (pack.bytes[1]>pack.HC) {alarmflag=1;pack.CSC2|=0x20;}\r
259                                 if (pack.CSC2&0x04)  //AEL\r
260                                         if (pack.bytes[1]<pack.LC) {alarmflag=1;pack.CSC2|=0x10;}\r
261                         } \r
262                         if (pack.convc1&8) {\r
263                                 double mu_sek=(double)min_ptime/(SEC_TIME)*1e6;\r
264                                 min_ptime=0;\r
265                                 cli();pack.D=mu_sek;sei();\r
266                                 if (pack.CSD2&0x08)  //AEH\r
267                                         if (pack.bytes[1]>pack.HD) {alarmflag=1;pack.CSD2|=0x20;}\r
268                                 if (pack.CSD2&0x04)  //AEL\r
269                                         if (pack.bytes[1]<pack.LD) {alarmflag=1;pack.CSD2|=0x10;}\r
270                         }\r
271                         \r
272                         EXTERN_SLEEP();\r
273                         //\r
274                 }\r
275 \r
276                 uint8_t bb=1;\r
277                 for(uint8_t i=0;i<4;i++) {\r
278                         if (pack.bytes[8+i*2]&0x80) {  //Chanel as output\r
279                                 if (pack.bytes[8+i*2]&0x40) {\r
280                                         DDRA|=bb;\r
281                                 } else {\r
282                                         DDRA&=~bb;\r
283                                 }\r
284                         } else {\r
285                                 DDRA&=~bb;\r
286                         }\r
287                         bb=bb*2;\r
288                 }\r
289                 if ((PORTB&(1<<PINB1))==0) {\r
290                         _delay_ms(100);\r
291                         PORTB|=(1<<PINB1);\r
292                  }\r
293                 \r
294 #if  defined(__AVR_ATtiny25__)||defined(__AVR_ATtiny45__)  || defined(__AVR_ATtiny85__)\r
295                         if (((TIMSK & (1<<TOIE0))==0)&& (mode==0))\r
296 #endif                  \r
297 #if  defined(__AVR_ATtiny24__)||defined(__AVR_ATtiny44__)  || defined(__AVR_ATtiny84__) ||defined(__AVR_ATtiny24A__)||defined(__AVR_ATtiny44A__)  || defined(__AVR_ATtiny84A__)\r
298                         if (((TIMSK0 & (1<<TOIE0))==0)&& (mode==0))\r
299 #endif\r
300                           {\r
301 \r
302                         MCUCR|=(1<<SE)|(1<<SM1);\r
303                         MCUCR&=~(1<<ISC01);\r
304                 } else {\r
305                         MCUCR|=(1<<SE);\r
306                         MCUCR&=~(1<<SM1);\r
307                 }\r
308         //      asm("SLEEP");\r
309    }\r
310 \r
311 \r
312 }