heat control  r71
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
comm.c
Go to the documentation of this file.
1 /*
2  * comm.c
3  *
4  * Created on: Jan 2, 2014
5  * Author: woodz
6  */
7 #include "comm.h"
8 #include "timer.h"
9 #include <util/crc16.h>
10 
14 //UCHAR volatile g_comDataReady = FALSE;
22 UCHAR volatile g_seqReady = FALSE;
23 
27 void CommInit(void) {
28  //disable USI module to avoid overriding of the PCINT8 functionality
29  DisableUsi();
30  //PCINT8 is used to receive serial bits, the DI line of the USI module
31  //set PCINT8 the DI pin as input, the DO pin is not changed, since we just receive and on DO there is a button connected
32  DDRB &= ~(1<<PCINT8);
33  //enabling pullup on DO is omitted, since we do not transmit anything
34  //enable pin change interrupts for group PCINT11..8
35  GIMSK = (0<<INT1) | (0<<INT0) | (0<<PCIE1) | (1<<PCIE0);
36  GIFR = (0<<INT1) | (0<<INTF0) | (1<<PCIF);
37  //enable specific pin change PCINT8, disable all others
38  PCMSK0 = (0<<PCINT7) | (0<<PCINT6) | (0<<PCINT5) | (0<<PCINT4) | (0<<PCINT3) | (0<<PCINT2) | (0<<PCINT1) | (0<<PCINT0);
39  EnablePcint8();
40 }
41 
46 ISR(PCINT_vect) {
47  //start bit detection:
48  //DATABIT = 0 -> start bit has begun
49  //DATABIT = 1 -> start bit has finished
50  //start bit is over?
51  if(DATABIT == TRUE) {
52  DisablePcint8();
53  EnableUsi();
54  }
55 }
56 
60 void EnablePcint8(void) {
61  //clear PCINT interrupt flag to avoid likely queued requests to execute immediately
62  GIFR |= (1<<PCIF);
63  PCMSK1 = (0<<PCINT15) | (0<<PCINT14) | (0<<PCINT13) | (0<<PCINT12) | (0<<PCINT11) | (0<<PCINT10) | (0<<PCINT9) | (1<<PCINT8);
64 }
65 
69 void DisablePcint8(void) {
70  PCMSK1 = (0<<PCINT15) | (0<<PCINT14) | (0<<PCINT13) | (0<<PCINT12) | (0<<PCINT11) | (0<<PCINT10) | (0<<PCINT9) | (0<<PCINT8);
71 }
72 
76 void DisableUsi(void) {
77  USISR = (0<<USISIF) | (0<<USIOIF) | (0<<USIPF) | (0<<USICNT3) | (0<<USICNT2) | (0<<USICNT1) | (0<<USICNT0);
78  USICR = (0<<USISIE) | (0<<USIOIE) | (0<<USIWM1) | (0<<USIWM0) | (0<<USICS1) | (0<<USICS0) | (0<<USICLK) | (0<<USITC);
79 }
80 
84 void EnableUsi(void) {
85  //plant initial Timer0 seed (and compare match value)
86  TCN_T0 = 0;
87  OCR0A = T0_INC20 + (T0_INC20 / 2);
88  //plant USI counter seed
89  USISR &= (0xf0 + (USI_CNTRNG - NUM_DB));
90  USISR |= USI_CNTRNG - NUM_DB;
91 // USISR &= ~(USI_CNTRNG - NUM_DB);
92  //set three-wire-mode, clock source to timer0 compare match and enable USI counter overflow interrupt
93  USICR &= ~0x0A;
94  USICR |= (1<<USIOIE) | (1<<USIWM0) | (0<<USICS1) | (1<<USICS0) | (0<<USICLK);
95 }
96 
101 ISR(USI_OVF_vect) {
102  static UCHAR sCnt=0;
103  UCHAR curByte = 0;
104 
105  DisableUsi();
106  EnablePcint8();
107 
108  //do no sequencing as long as the previous seq has not been processed
109  if(g_seqReady) { return; }
110  curByte = ~FlipByte(USIBR);
111  if((curByte == SEQ_STA) && (sCnt == 0)) {
112  ++sCnt;
113  return;
114  }
115  //store received byte in sequence buffer
116  if(sCnt >= 1) {
117  g_seq[sCnt] = curByte;
118  if(++sCnt >= SEQ_BUF_SIZE) {
119  sCnt = 0;
120  if(curByte == SEQ_END) {
121  g_seqReady = TRUE;
122  }
123  }
124  }
125 }
126 
133 UCHAR GetSenderValues(UINT* innerTemp, UINT* outerTemp/*, UINT* supVolt*/) {
134  UCHAR ret = FALSE;
135 
136  if(g_seqReady && (CalcCrc() == 0)) {
137  *innerTemp = g_seq[TEMP_CH1_VAL_H_ID] << 8;
138  *innerTemp |= g_seq[TEMP_CH1_VAL_L_ID];
139  *outerTemp = g_seq[TEMP_CH2_VAL_H_ID] << 8;
140  *outerTemp |= g_seq[TEMP_CH2_VAL_L_ID];
141 // *supVolt = g_seq[SUP_VOLT_VAL_H_ID] << 8;
142 // *supVolt |= g_seq[SUP_VOLT_VAL_L_ID];
143 // if(PlausibilityCheck(*innerTemp, *outerTemp))
144  ret = TRUE;
145  }
146  else {
147  *innerTemp = INVALID_VAL_U16;
148  *outerTemp = INVALID_VAL_U16;
149 // *supVolt = INVALID_VAL_U16;
150  ret = FALSE;
151  }
152  g_seqReady = FALSE;
153  return ret;
154 }
155 
162 UCHAR PlausibilityCheck(UINT innerTemp, UINT outerTemp) {
163  static UINT oldInnerTemp = INVALID_VAL_U16;
164  static UINT oldOuterTemp = INVALID_VAL_U16;
165  UCHAR ret=FALSE;
166  UINT dIn = innerTemp - oldInnerTemp, dOut = outerTemp - oldOuterTemp;
167 
168  if(innerTemp != INVALID_VAL_U16 && outerTemp != INVALID_VAL_U16) {
169  if(innerTemp <= MAX_ABS_INNER_TEMP && innerTemp >= MIN_ABS_INNER_TEMP
170  && outerTemp <= MAX_ABS_OUTER_TEMP && outerTemp >= MIN_ABS_OUTER_TEMP
171  && (dIn <= MAX_DEL_INNER_TEMP || (INVALID_VAL_U16 - dIn) <= MAX_DEL_INNER_TEMP)
172  && (dOut <= MAX_DEL_OUTER_TEMP || (INVALID_VAL_U16 - dOut) <= MAX_DEL_OUTER_TEMP))
173  ret=TRUE;
174  }
175  oldInnerTemp = innerTemp;
176  oldOuterTemp = outerTemp;
177  return ret;
178 }
179 
180 UCHAR CalcCrc(void) {
181  UCHAR crc = 0;
182 
183  crc = _crc_ibutton_update(crc, g_seq[TEMP_CH1_VAL_H_ID]);
184  crc = _crc_ibutton_update(crc, g_seq[TEMP_CH1_VAL_L_ID]);
185  crc = _crc_ibutton_update(crc, g_seq[TEMP_CH2_VAL_H_ID]);
186  crc = _crc_ibutton_update(crc, g_seq[TEMP_CH2_VAL_L_ID]);
187  crc = _crc_ibutton_update(crc, g_seq[SUP_VOLT_VAL_H_ID]);
188  crc = _crc_ibutton_update(crc, g_seq[SUP_VOLT_VAL_L_ID]);
189  crc = _crc_ibutton_update(crc, g_seq[CRC_OVER_ALL]);
190  return crc;
191 }
192 
194 //UCHAR StartBitElapsed(UCHAR started) {
195 // static UCHAR nextCnt = 0xFF;
196 //
197 // if(started) {
198 // if(TCN_T0 > MAX_STB_CNT)
199 // nextCnt = TCN_T0 - (MAX_STB_CNT + 1);
200 // else
201 // nextCnt = TCN_T0 + OAHBT;
202 // }
203 // else if(TCN_T0 == nextCnt)
204 // return TRUE;
205 // return FALSE;
206 //}
207 
208 
209 
210 
211 
212 
213 
214 
215 
216 
217 
218 
219 
220 
221 
222 
223 
224 
225 
226 
227 
228 
229 
230 
UCHAR volatile g_seqReady
Definition: comm.c:22
ISR(PCINT_vect)
pin change (PCINT8) interrupt service
Definition: comm.c:46
#define TEMP_CH1_VAL_H_ID
Definition: comm.h:40
#define NUM_DB
Definition: comm.h:20
#define TEMP_CH2_VAL_H_ID
Definition: comm.h:48
#define CRC_OVER_ALL
Definition: comm.h:64
#define MAX_DEL_OUTER_TEMP
Definition: comm.h:90
#define TCN_T0
Definition: types.h:46
#define DATABIT
Definition: comm.h:16
void EnablePcint8(void)
enable pin change interrupt PCINT8
Definition: comm.c:60
#define T0_INC20
Definition: timer.h:16
#define MIN_ABS_INNER_TEMP
Definition: comm.h:74
#define SUP_VOLT_VAL_H_ID
Definition: comm.h:56
#define FALSE
Definition: types.h:93
#define SEQ_STA
Definition: comm.h:32
#define SEQ_END
Definition: comm.h:36
UCHAR CalcCrc(void)
Definition: comm.c:180
#define SEQ_BUF_SIZE
Definition: comm.h:28
#define MAX_DEL_INNER_TEMP
Definition: comm.h:86
#define UCHAR
Definition: types.h:73
#define SUP_VOLT_VAL_L_ID
Definition: comm.h:60
#define USI_CNTRNG
Definition: comm.h:24
void DisableUsi(void)
disable USI module, there's no specific flag to do so -> disabling what can be done ...
Definition: comm.c:76
void EnableUsi(void)
enable USI module for proper comm
Definition: comm.c:84
#define TRUE
Definition: types.h:97
#define INVALID_VAL_U16
Definition: types.h:105
UCHAR GetSenderValues(UINT *innerTemp, UINT *outerTemp)
establish decimal temperature values form raw stream in sequence
Definition: comm.c:133
UCHAR PlausibilityCheck(UINT innerTemp, UINT outerTemp)
check plausibility of recently received temperatures against specific limits
Definition: comm.c:162
#define TEMP_CH2_VAL_L_ID
Definition: comm.h:52
#define TEMP_CH1_VAL_L_ID
Definition: comm.h:44
UCHAR FlipByte(UCHAR x)
reverse bits in a byte (make it RS232 conform for transmission)
Definition: types.c:53
#define UINT
Definition: types.h:81
void DisablePcint8(void)
disable pin change interrupt PCINT8
Definition: comm.c:69
void CommInit(void)
init as defined in "doc4300.pdf": figure 12. Initialization of the Receive Driver ...
Definition: comm.c:27
#define MIN_ABS_OUTER_TEMP
Definition: comm.h:82
UCHAR g_seq[SEQ_BUF_SIZE]
Definition: comm.c:18