-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathao_Control_K.cpp
More file actions
212 lines (190 loc) · 5.41 KB
/
ao_Control_K.cpp
File metadata and controls
212 lines (190 loc) · 5.41 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
#include "ao_Control_K.h"
// CLI max time = 180us!!!
#define AO_USRAT_CONTROL
#ifdef AO_USRAT_CONTROL
#define UBRRn UBRR0
#define UCSRnA UCSR0A
#define UCSRnB UCSR0B
#define UCSRnC UCSR0C
#define UDRn UDR0
#define RXENn RXEN0
#define RXCIEn RXCIE0
#define RXCn RXC0
#define UPEn UPE0
#define U2Xn U2X0
#define USARTn_RX_vect USART0_RX_vect
#else
#define UBRRn UBRR1
#define UCSRnA UCSR1A
#define UCSRnB UCSR1B
#define UCSRnC UCSR1C
#define UDRn UDR1
#define RXENn RXEN1
#define RXCIEn RXCIE1
#define RXCn RXC1
#define UPEn UPE1
#define U2Xn U2X1
#define USARTn_RX_vect USART1_RX_vect
#endif
Control_K::Control_K() {
_ThisControl_K = this;
}
void Control_K::start() {
resetPacket();
rx_irq =false;
UBRRn =16; //115200Baud
UCSRnA =(1<<U2Xn);
UCSRnC =SERIAL_DEF; // Data format
UCSRnB =(1<<RXENn)|(1<<RXCIEn); // RX on
}
// defined(USARTn_RX_vect)
ISR(USARTn_RX_vect) {
_ThisControl_K->rx_udr_rxc();
}
// write recived data into Buffer and do RX protocol
void Control_K::rx_udr_rxc(void){
while (UCSRnA&(1<<RXCn)){
uint8_t i =(rx_buffer_head +1) % RX_BUF_SIZE_RX1;
if ((UCSRnA&(1<<UPEn))==0) { // Parity okay?
if (i != rx_buffer_tail) {
rx_buffer[rx_buffer_head] = UDRn;
rx_buffer_head = i;
} else {
break; // SW Buffer full
}
} else {
unsigned char c = UDRn; // waste broken data
}
}
if (rx_irq==false) { // don't reenter statemachine
rx_irq=true;
sei();
stateMachine();
cli();
rx_irq=false;
}
}
void Control_K::stateMachine(void){
while (rx_buffer_head != rx_buffer_tail) {
unsigned char c;
c = rx_buffer[rx_buffer_tail];
rx_buffer_tail = (rx_buffer_tail + 1) % RX_BUF_SIZE_RX1;
if (b_state == WAIT_DATA) {
b_kBusBuffer[b_nBytes++] = c;
if (b_nBytes == b_nPacketLen) {
if (b_kBusBuffer[3]=='L') { // LIve data
decodeLiveData();
} else if (b_kBusBuffer[3]=='I') { // Info data
decodeInfoData();
}
b_state = WAIT_HDR_0;
}
} else if (b_state == WAIT_HDR_0) {
if (c == 0x4b) { // K
b_state = WAIT_HDR_1;
b_kBusBuffer[0] = c;
}
} else if (b_state == WAIT_HDR_1) {
if (c == 0x4f) { // O
b_state = WAIT_HDR_2;
b_kBusBuffer[1] = c;
}
} else if (b_state == WAIT_HDR_2) {
if (c == 0x44) { // D
b_state = WAIT_HDR_3;
b_kBusBuffer[2] = c;
}
} else if (b_state == WAIT_HDR_3) {
if (c == 0x4c || c == 0x49) { // L or I
b_state = WAIT_DATA;
b_kBusBuffer[3] = c;
b_nBytes=4;
b_nPacketLen =(c == 'L' ? SENSOR_LIVEDATA : SENSOR_INFODATA);
}
} else {
b_state = WAIT_HDR_0; // --> Error
}
}
}
void Control_K::decodeLiveData(){
if (receiveCRCCheck(b_nPacketLen-7)){
memcpy(m_LiveData,&b_kBusBuffer[4],SENSOR_LIVEDATA-8); // without header and crc
m_LiveDataNew = true;
m_LiveDataTime=millis();
}
}
void Control_K::decodeInfoData(){
if (receiveCRCCheck(b_nPacketLen-6)){
memcpy(m_InfoData,&b_kBusBuffer[4],SENSOR_INFODATA-8); // without header and crc
m_InfoDataNew = true;
m_InfoDataTime=millis();
}
}
bool Control_K::receiveCRCCheck(uint8_t length){ //-6 für Info -7 für Live (4 CRC)
reset();
for (uint8_t i=0; i<=length;i++)
update(b_kBusBuffer[i]);
uint32_t crcBus= ((uint32_t)(b_kBusBuffer[b_nPacketLen-1])<<24)|((uint32_t)(b_kBusBuffer[b_nPacketLen-2])<<16)
|((uint32_t)(b_kBusBuffer[b_nPacketLen-3])<<8)|((uint32_t)(b_kBusBuffer[b_nPacketLen-4]));
return crcBus==finalize();
}
bool Control_K::hasNewLiveData(void) {
uint8_t cSREG= SREG;
cli();
bool b = m_LiveDataNew;
m_LiveDataNew = false;
SREG = cSREG; // restore SREG value (I-bit)
return b;
}
bool Control_K::hasNewInfoData(void) {
uint8_t cSREG= SREG;
cli();
bool b = m_InfoDataNew;
m_InfoDataNew = false;
SREG = cSREG; // restore SREG value (I-bit)
return b;
}
// get live data
uint32_t Control_K::getLiveValue32(uint8_t pos){
uint8_t cSREG= SREG;
cli();
uint32_t value=((uint32_t)(m_LiveData[pos+3])<<24)|((uint32_t)(m_LiveData[pos+2])<<16)|((uint32_t)(m_LiveData[pos+1])<<8)|((uint32_t)(m_LiveData[pos]));
SREG = cSREG; // restore SREG value (I-bit)
return value;
}
uint16_t Control_K::getLiveValue16(uint8_t pos){
uint8_t cSREG= SREG;
cli();
uint16_t value=((uint16_t)(m_LiveData[pos+1])<<8)|((uint32_t)(m_LiveData[pos]));
SREG = cSREG; // restore SREG value (I-bit)
return value;
}
uint8_t Control_K::getLiveValue8(uint8_t pos){
uint8_t cSREG= SREG;
cli();
uint8_t value=m_LiveData[pos];
SREG = cSREG; // restore SREG value (I-bit)
return value;
}
// get info data
uint32_t Control_K::getInfoValue32(uint8_t pos){
uint8_t cSREG= SREG;
cli();
uint32_t value=((uint32_t)(m_InfoData[pos+3])<<24)|((uint32_t)(m_InfoData[pos+2])<<16)|((uint32_t)(m_InfoData[pos+1])<<8)|((uint32_t)(m_InfoData[pos]));
SREG = cSREG; // restore SREG value (I-bit)
return value;
}
uint16_t Control_K::getInfoValue16(uint8_t pos){
uint8_t cSREG= SREG;
cli();
uint16_t value=((uint16_t)(m_InfoData[pos+1])<<8)|((uint32_t)(m_InfoData[pos]));
SREG = cSREG; // restore SREG value (I-bit)
return value;
}
uint8_t Control_K::getInfoValue8(uint8_t pos){
uint8_t cSREG= SREG;
cli();
uint8_t value=m_InfoData[pos];
SREG = cSREG; // restore SREG value (I-bit)
return value;
}