root / Version 2.3 / Panel_reader_controller.X / main.c @ fa27b68e
Historique | Voir | Annoter | Télécharger (27,321 ko)
1 | 26acdf16 | Enzo Niro | /*
|
---|---|---|---|
2 | * File: main.c
|
||
3 | * Author: Enzo Niro
|
||
4 | * Revision history : 2.0
|
||
5 | *
|
||
6 | * Created on August 28, 2024, 2:39 PM
|
||
7 | */
|
||
8 | |||
9 | |||
10 | #define F_CPU 10000000UL |
||
11 | |||
12 | #include <xc.h> |
||
13 | #include <stdio.h> |
||
14 | #include <string.h> |
||
15 | #include <stdint.h> |
||
16 | #include <stdbool.h> |
||
17 | #include <util/delay.h> |
||
18 | #include <avr/interrupt.h> |
||
19 | #include <avr/eeprom.h> |
||
20 | |||
21 | #include "factory.h" |
||
22 | #include "defValues.h" |
||
23 | #include "configuration.h" |
||
24 | #include "pins.h" |
||
25 | #include "moduleCmds.h" |
||
26 | |||
27 | |||
28 | |||
29 | /*
|
||
30 | TODO list :
|
||
31 | * ADC for battery
|
||
32 | * Test setBluetoothConfiguration()
|
||
33 |
|
||
34 | */
|
||
35 | |||
36 | |||
37 | |||
38 | |||
39 | ////////////////////////////////////////////
|
||
40 | //Prototypes & Macros
|
||
41 | |||
42 | //USART functions
|
||
43 | void writeCommand(const uint8_t *buf, uint8_t n); //Write a buffer on usart 1 port |
||
44 | void readBuffer(uint8_t *cfg, uint8_t n);
|
||
45 | void usart0_write_byte(uint8_t b); //send a single byte to usart 0 port |
||
46 | void usart1_write_byte(uint8_t b); //send a single byte to usart 1 port |
||
47 | uint8_t usart0_read_byte(void); //read a single byte from usart 0 port |
||
48 | uint8_t usart1_read_byte(void); //read a single byte from usart 1 port |
||
49 | uint8_t usart0_available(void); //check number of bytes available into usart 0 buffer |
||
50 | uint8_t usart1_available(void); //check number of bytes available into usart 1 buffer |
||
51 | void serialDebug(const char *str, uint8_t n); |
||
52 | |||
53 | //Analog functions
|
||
54 | void dimmerSetup(void); //start dimmer |
||
55 | void adcInit(void); //Init ADC cfg |
||
56 | |||
57 | //Control functions
|
||
58 | uint8_t numberOfParity(uint8_t *p, uint8_t n); //Return the sum of bytes' parity
|
||
59 | uint8_t numberOfBit(uint8_t *p, uint8_t n); //Return the total bit at 1 of buffer
|
||
60 | void getEEPROMCfg(uint8_t *cfg); //Get EEPROM buffer into RAM |
||
61 | uint8_t controlCfg(uint8_t *cfg); //Control RAM buffer
|
||
62 | void getBluetoothConfiguration(uint8_t *cfg);
|
||
63 | void setBluetoothConfiguration(uint8_t *cfg);
|
||
64 | void restoreFactoryConfiguration(uint8_t *cfg);
|
||
65 | uint8_t controlRN4678(void);
|
||
66 | |||
67 | //MCU Commands functions
|
||
68 | uint8_t gotMCUCommand(uint8_t *buf, uint8_t *frame, uint8_t n); //Method to analyse command
|
||
69 | |||
70 | //Macros
|
||
71 | |||
72 | #define ADC_START_CONV ADC0.COMMAND |= 0x01 //Start conversion |
||
73 | #define ADC_READ ADC0.SAMPLE //Get sample value |
||
74 | #define BLUETOOTH_CONNECTED ((PORTA.IN & STAT2_PIN) >> 4) //Get Bluetooth connected status |
||
75 | |||
76 | #define SET_DATA_LED PORTB.OUT |= STATUS_DATA_PIN
|
||
77 | #define CLR_DATA_LED PORTB.OUT &= ~STATUS_DATA_PIN
|
||
78 | #define SET_CONNECTED_LED PORTB.OUT |= STATUS_CONNECTED_PIN
|
||
79 | #define CLR_CONNECTED_LED PORTB.OUT &= ~STATUS_CONNECTED_PIN
|
||
80 | #define SET_POWER_LED TCA0.SINGLE.CMP1 = 255 //Pin depend on timer |
||
81 | #define CLR_POWER_LED TCA0.SINGLE.CMP1 = 0 |
||
82 | |||
83 | ////////////////////////////////////////////
|
||
84 | |||
85 | |||
86 | |||
87 | /////////////////////////////////////////////////
|
||
88 | //Serial port backend
|
||
89 | enum baudsIndex
|
||
90 | { |
||
91 | B2400 = 0,
|
||
92 | B4800, |
||
93 | B9600, |
||
94 | B14400, |
||
95 | B19200, |
||
96 | B28800, |
||
97 | B38400, |
||
98 | B57600, |
||
99 | B115200, |
||
100 | }; |
||
101 | |||
102 | |||
103 | enum ATtinyMemAddr
|
||
104 | { |
||
105 | AUTH_ADDR = 0x0,
|
||
106 | BLM_ADDR = 0x3,
|
||
107 | DEVN_ADDR = 0x6,
|
||
108 | PINC_ADDR = 0x18,
|
||
109 | BAUD_ADDR = 0x1E,
|
||
110 | COUNT_ADDR = 0x50, //For error memory count |
||
111 | }; |
||
112 | |||
113 | |||
114 | //Equivalents baudrate at 10MHz of oscillation
|
||
115 | uint16_t _10MHz_Baud_CFG[] = { 16666, 8333, 4166, 2777, 2083, 1389, 1042, 694, 347 }; |
||
116 | |||
117 | |||
118 | uint8_t USART0_Buffer[256], USART0_counter = 0; |
||
119 | uint8_t USART1_Buffer[256], USART1_counter = 0; |
||
120 | |||
121 | |||
122 | /////////////////////////////////////////////////////////////////////////
|
||
123 | //Special MCU Commands
|
||
124 | |||
125 | uint8_t debugSerialBuffer[MAX_WINDOW_BUFFER]; //set window analyse buffer
|
||
126 | uint8_t debugSerialCounter = 0;
|
||
127 | uint8_t debugStatus_cmd[] = { 0x2, 'A', '$', '$', 'G', 'E', 'T', 'M', 'E', 'M', 'S', 'T', 'S', 0x3, }; |
||
128 | |||
129 | |||
130 | |||
131 | int main(void) { |
||
132 | |||
133 | |||
134 | uint8_t ATtiny826_buffer[TOP_CFG_ADDR]; //saved cfg
|
||
135 | bool serialOk = false; //To find the right baud value |
||
136 | uint8_t baudSelector = 0;
|
||
137 | |||
138 | //Memory corrupt variables
|
||
139 | uint8_t ATtiny_mem_err = 0x00;
|
||
140 | uint8_t RN4678_mem_err = 0x00;
|
||
141 | //Memory corrput counter (for debug, if this is not corrupted...)
|
||
142 | uint8_t ATtiny_mem_cnt = 0;
|
||
143 | uint8_t RN4678_mem_cnt = 0;
|
||
144 | uint8_t EMRG_mem_cnt = 0;
|
||
145 | |||
146 | uint8_t paramBuffer[64];
|
||
147 | uint8_t paramBuffer_cnt = 0;
|
||
148 | |||
149 | |||
150 | _PROTECTED_WRITE(CLKCTRL.MCLKCTRLB, ENABLE_BIT); //Enable clock prescaler (and divide by 2)
|
||
151 | |||
152 | |||
153 | |||
154 | |||
155 | |||
156 | |||
157 | ////////////////////////////////////////////////
|
||
158 | //Basic pins setup
|
||
159 | PORTA.OUT = 0x00;
|
||
160 | PORTA.DIR = BOOT_BL_PIN; //set boot pin as output
|
||
161 | PORTB.OUT = 0x00;
|
||
162 | PORTB.DIR = STATUS_POWER_PIN | STATUS_DATA_PIN | STATUS_CONNECTED_PIN; //set all status pins as output
|
||
163 | ////////////////////////////////////////////////
|
||
164 | |||
165 | /////////////////////////
|
||
166 | //Start PWM
|
||
167 | dimmerSetup(); |
||
168 | |||
169 | SET_DATA_LED; //display boot status
|
||
170 | /////////////////////////
|
||
171 | //Boot Bluetooth module
|
||
172 | _delay_ms(50);
|
||
173 | PORTA.OUT |= BOOT_BL_PIN; |
||
174 | _delay_ms(50);
|
||
175 | PORTA.OUT &= ~(BOOT_BL_PIN); |
||
176 | _delay_ms(50);
|
||
177 | PORTA.OUT |= BOOT_BL_PIN; |
||
178 | |||
179 | _delay_ms(500);
|
||
180 | CLR_DATA_LED; |
||
181 | ////////////////////////////////////////////////
|
||
182 | //USART Setup
|
||
183 | #ifdef USE_TWO_SERIAL_PORTS
|
||
184 | cli(); |
||
185 | PORTA.DIR |= TX2_PIN; //Only this pin is output, others are input
|
||
186 | PORTB.DIR |= TX1_PIN; //Add TX1 pin as output on PORTB
|
||
187 | |||
188 | USART0.CTRLA = USART_RXCIE_bm; // Enable RXCIE -> Receive complete interrupt flag
|
||
189 | USART0.CTRLB = USART_RXEN_bm | USART_TXEN_bm; //TX and RX enable
|
||
190 | USART0.CTRLC = USART_CHSIZE_8BIT_gc | USART_CMODE_ASYNCHRONOUS_gc | USART_PMODE_DISABLED_gc | USART_SBMODE_2BIT_gc; // 8 bits + 2 stop bit + No parity (Normal mode)
|
||
191 | USART0.BAUD = _10MHz_Baud_CFG[0]; //set baudrate |
||
192 | |||
193 | USART1.CTRLA = USART_RXCIE_bm; // Enable RXCIE -> Receive complete interrupt flag
|
||
194 | USART1.CTRLB = USART_RXEN_bm | USART_TXEN_bm; //TX and RX enable
|
||
195 | USART1.CTRLC = USART_CHSIZE_8BIT_gc | USART_CMODE_ASYNCHRONOUS_gc | USART_PMODE_DISABLED_gc; // 8 bits + 2 stop bit + No parity (Normal mode)
|
||
196 | USART1.BAUD = _10MHz_Baud_CFG[0]; //set baudrate |
||
197 | sei(); |
||
198 | #endif
|
||
199 | ////////////////////////////////////////////////
|
||
200 | |||
201 | |||
202 | ////////////////////////////////////////////////
|
||
203 | //Start ADC
|
||
204 | //adcInit();
|
||
205 | |||
206 | |||
207 | |||
208 | |||
209 | |||
210 | |||
211 | |||
212 | ///////////////////////////////////////////////////////////////
|
||
213 | //Find serial port baud speed
|
||
214 | |||
215 | |||
216 | |||
217 | while(!serialOk)
|
||
218 | { |
||
219 | uint8_t window_analysis[3]; //create window here (to analyse "CMD" command) |
||
220 | writeCommand(ENTER_SETUP, 4); //sizeof(ENTER_SETUP) |
||
221 | _delay_ms(100); //wait a bit |
||
222 | while(usart0_available() > 0) |
||
223 | { |
||
224 | paramBuffer[paramBuffer_cnt] = usart0_read_byte(); |
||
225 | paramBuffer_cnt++; |
||
226 | } |
||
227 | |||
228 | |||
229 | while(paramBuffer_cnt > 0) //Try to reach desired buffer and flush "noise" buffer |
||
230 | { |
||
231 | //Read 3 first bytes...
|
||
232 | for(int i = 0; i < 3; i++) |
||
233 | { |
||
234 | window_analysis[i] = paramBuffer[i]; |
||
235 | } |
||
236 | //Sweep buffer
|
||
237 | for(int i = 0; i < paramBuffer_cnt-1; i++) |
||
238 | { |
||
239 | paramBuffer[i] = paramBuffer[i+1];
|
||
240 | } |
||
241 | //Check buffer
|
||
242 | if(window_analysis[0] == 'C' && window_analysis[1] == 'M' && window_analysis[2] == 'D') //we've got data -> Leave ! |
||
243 | { |
||
244 | serialOk = true;
|
||
245 | } |
||
246 | paramBuffer_cnt--; |
||
247 | } |
||
248 | |||
249 | |||
250 | if(!serialOk) //if buffer messed up (no "CMD" string found...) |
||
251 | { |
||
252 | //Go on next baud
|
||
253 | USART0.BAUD = _10MHz_Baud_CFG[baudSelector]; //set baudrate
|
||
254 | baudSelector++; |
||
255 | _delay_ms(10);
|
||
256 | //If we've got the last param
|
||
257 | if(baudSelector >= MAX_BAUD_VALUES)
|
||
258 | serialOk = true; //force |
||
259 | } |
||
260 | } |
||
261 | |||
262 | serialDebug("Start\n", 6); |
||
263 | |||
264 | //_delay_ms(50);
|
||
265 | |||
266 | while(usart0_available() > 0) //flush buffer |
||
267 | { |
||
268 | usart0_read_byte(); |
||
269 | } |
||
270 | |||
271 | _delay_ms(1000); //wait a bit |
||
272 | USART1.BAUD = USART0.BAUD; //copy baud to another...
|
||
273 | |||
274 | |||
275 | //serialDebug("Dimst\n", 6);
|
||
276 | ///////////////////////////////////////////////////////////////
|
||
277 | //Memory boot management
|
||
278 | getEEPROMCfg(ATtiny826_buffer); //read EEPROM saved cfg (At first...)
|
||
279 | ATtiny_mem_err = controlCfg(ATtiny826_buffer); //control ATtiny826 Memory
|
||
280 | RN4678_mem_err = controlRN4678(); //control RN4678 Memory Status
|
||
281 | //serialDebug("Cfggt\n", 6);
|
||
282 | ATtiny_mem_cnt = eeprom_read_byte(COUNT_ADDR); |
||
283 | _delay_ms(100);
|
||
284 | RN4678_mem_cnt = eeprom_read_byte(COUNT_ADDR+1);
|
||
285 | _delay_ms(100);
|
||
286 | EMRG_mem_cnt = eeprom_read_byte(COUNT_ADDR+2);
|
||
287 | _delay_ms(100);
|
||
288 | |||
289 | if(ATtiny_mem_err != 0x00 && RN4678_mem_err == 0x00) //MCU memory error ! |
||
290 | { |
||
291 | ATtiny_mem_cnt++; |
||
292 | SET_DATA_LED; |
||
293 | _delay_ms(250);
|
||
294 | CLR_DATA_LED; |
||
295 | _delay_ms(250);
|
||
296 | SET_DATA_LED; |
||
297 | _delay_ms(250);
|
||
298 | CLR_DATA_LED; |
||
299 | _delay_ms(250);
|
||
300 | SET_DATA_LED; |
||
301 | _delay_ms(250);
|
||
302 | CLR_DATA_LED; |
||
303 | _delay_ms(250);
|
||
304 | getBluetoothConfiguration(ATtiny826_buffer); |
||
305 | } |
||
306 | else if(ATtiny_mem_err == 0x00 && RN4678_mem_err != 0x00) // RN4678 memory error ! |
||
307 | { |
||
308 | RN4678_mem_cnt++; |
||
309 | SET_CONNECTED_LED; |
||
310 | _delay_ms(250);
|
||
311 | CLR_CONNECTED_LED; |
||
312 | _delay_ms(250);
|
||
313 | SET_CONNECTED_LED; |
||
314 | _delay_ms(250);
|
||
315 | CLR_CONNECTED_LED; |
||
316 | _delay_ms(250);
|
||
317 | SET_CONNECTED_LED; |
||
318 | _delay_ms(250);
|
||
319 | CLR_CONNECTED_LED; |
||
320 | _delay_ms(250);
|
||
321 | setBluetoothConfiguration(ATtiny826_buffer); |
||
322 | } |
||
323 | else if(ATtiny_mem_err != 0x00 && RN4678_mem_err != 0x00)//Emergency case !!! (Twice memory are corrupted...) |
||
324 | { |
||
325 | EMRG_mem_cnt++; |
||
326 | SET_POWER_LED; |
||
327 | _delay_ms(250);
|
||
328 | CLR_POWER_LED; |
||
329 | _delay_ms(250);
|
||
330 | SET_POWER_LED; |
||
331 | _delay_ms(250);
|
||
332 | CLR_POWER_LED; |
||
333 | _delay_ms(250);
|
||
334 | SET_POWER_LED; |
||
335 | _delay_ms(250);
|
||
336 | CLR_POWER_LED; |
||
337 | _delay_ms(250);
|
||
338 | restoreFactoryConfiguration(ATtiny826_buffer); |
||
339 | } |
||
340 | else
|
||
341 | { |
||
342 | SET_DATA_LED; |
||
343 | _delay_ms(250);
|
||
344 | CLR_DATA_LED; |
||
345 | SET_CONNECTED_LED; |
||
346 | _delay_ms(250);
|
||
347 | CLR_CONNECTED_LED; |
||
348 | SET_POWER_LED; //STATUS_POWER_PIN
|
||
349 | _delay_ms(250);
|
||
350 | CLR_POWER_LED; //STATUS_POWER_PIN
|
||
351 | SET_DATA_LED; |
||
352 | _delay_ms(250);
|
||
353 | CLR_DATA_LED; |
||
354 | SET_CONNECTED_LED; |
||
355 | _delay_ms(250);
|
||
356 | CLR_CONNECTED_LED; |
||
357 | SET_POWER_LED; //STATUS_POWER_PIN
|
||
358 | _delay_ms(250);
|
||
359 | CLR_POWER_LED; //STATUS_POWER_PIN
|
||
360 | } |
||
361 | |||
362 | |||
363 | if(EMRG_mem_cnt == 0xFF) //if default EEPROM mem. |
||
364 | { |
||
365 | EMRG_mem_cnt = 0; //clear... |
||
366 | //And write to EEPROM...
|
||
367 | eeprom_write_byte(COUNT_ADDR+2, EMRG_mem_cnt);
|
||
368 | _delay_ms(100);
|
||
369 | } |
||
370 | if(RN4678_mem_cnt == 0xFF) //if default EEPROM mem. |
||
371 | { |
||
372 | RN4678_mem_cnt = 0; //clear... |
||
373 | //And write to EEPROM...
|
||
374 | eeprom_write_byte(COUNT_ADDR+1, RN4678_mem_cnt);
|
||
375 | _delay_ms(100);
|
||
376 | } |
||
377 | if(ATtiny_mem_cnt == 0xFF) //if default EEPROM mem. |
||
378 | { |
||
379 | ATtiny_mem_cnt = 0; //clear... |
||
380 | //And write to EEPROM...
|
||
381 | eeprom_write_byte(COUNT_ADDR, ATtiny_mem_cnt); |
||
382 | _delay_ms(100);
|
||
383 | } |
||
384 | |||
385 | |||
386 | writeCommand(QUIT_SETUP, sizeof(QUIT_SETUP));
|
||
387 | _delay_ms(1000); //wait a bit |
||
388 | while(usart0_available() > 0) //flush buffer |
||
389 | { |
||
390 | usart0_read_byte(); |
||
391 | } |
||
392 | |||
393 | |||
394 | |||
395 | |||
396 | while(1) |
||
397 | { |
||
398 | |||
399 | //Mux USART Management (Put status and switch together)
|
||
400 | BLUETOOTH_CONNECTED ? (SET_CONNECTED_LED) : (CLR_CONNECTED_LED); |
||
401 | //Set USART data flow status
|
||
402 | |||
403 | if((PORTA.IN & (STAT1_PIN | STAT_RX_PIN)) != (STAT1_PIN | STAT_RX_PIN))
|
||
404 | { |
||
405 | SET_DATA_LED; |
||
406 | } |
||
407 | else
|
||
408 | { |
||
409 | CLR_DATA_LED; |
||
410 | } |
||
411 | |||
412 | |||
413 | |||
414 | |||
415 | //Set Power status (Depending on ADC_BAT and SECTOR_STAT)
|
||
416 | if((PORTC.IN & SECTOR_PIN) == SECTOR_PIN)
|
||
417 | { |
||
418 | SET_POWER_LED; |
||
419 | } |
||
420 | else //Battery Only |
||
421 | { |
||
422 | CLR_POWER_LED; |
||
423 | } |
||
424 | |||
425 | |||
426 | |||
427 | |||
428 | ///////////////////////////////////////////////////
|
||
429 | //Man-in-the-middle script
|
||
430 | |||
431 | |||
432 | if(usart1_available() > 0) |
||
433 | { |
||
434 | //usart0_write_byte(usart1_read_byte());
|
||
435 | /*paramBuffer[paramBuffer_cnt] = usart1_read_byte();
|
||
436 | usart0_write_byte(paramBuffer[paramBuffer_cnt]);
|
||
437 | paramBuffer_cnt++;*/
|
||
438 | //_delay_ms(1);
|
||
439 | if(BLUETOOTH_CONNECTED)
|
||
440 | usart0_write_byte(usart1_read_byte()); |
||
441 | else
|
||
442 | { |
||
443 | ///////////////////////////////////////////////////
|
||
444 | //Debug Hardware When BL. module disconnected
|
||
445 | debugSerialBuffer[MAX_WINDOW_BUFFER-1] = usart1_read_byte(); //get byte into window buffer |
||
446 | //usart1_write_byte(debugSerialBuffer[MAX_WINDOW_BUFFER-1]);
|
||
447 | usart0_write_byte(debugSerialBuffer[MAX_WINDOW_BUFFER-1]); //send it to another serial port (just in case) |
||
448 | for(int i = 0; i < MAX_WINDOW_BUFFER-1; i++) |
||
449 | { |
||
450 | debugSerialBuffer[i] = debugSerialBuffer[i+1]; //shift bytes from right to left |
||
451 | } |
||
452 | |||
453 | if(gotMCUCommand(debugSerialBuffer, debugStatus_cmd, sizeof(debugStatus_cmd))) |
||
454 | { |
||
455 | //Bad coding...
|
||
456 | serialDebug("COUNT: ", 7); |
||
457 | usart1_write_byte(ATtiny_mem_cnt); |
||
458 | _delay_ms(1);
|
||
459 | usart1_write_byte(' ');
|
||
460 | _delay_ms(1);
|
||
461 | usart1_write_byte(RN4678_mem_cnt); |
||
462 | _delay_ms(1);
|
||
463 | usart1_write_byte(' ');
|
||
464 | _delay_ms(1);
|
||
465 | usart1_write_byte(EMRG_mem_cnt); |
||
466 | _delay_ms(1);
|
||
467 | //clearDebugBuffer(debugSerialBuffer, MAX_WINDOW_BUFFER); //if needed, implement it !
|
||
468 | } |
||
469 | } |
||
470 | |||
471 | |||
472 | } |
||
473 | //When buffer is filled, load it to serial port
|
||
474 | /*for(int i = 0; i < paramBuffer_cnt; i++)
|
||
475 | {
|
||
476 | usart0_write_byte(paramBuffer[i]);
|
||
477 | }
|
||
478 | paramBuffer_cnt = 0;*/
|
||
479 | |||
480 | if(usart0_available() > 0) |
||
481 | { |
||
482 | usart1_write_byte(usart0_read_byte()); |
||
483 | } |
||
484 | |||
485 | |||
486 | |||
487 | |||
488 | |||
489 | |||
490 | /*
|
||
491 | if(!BLUETOOTH_CONNECTED) //Check STAT2 pin if not connected
|
||
492 | {
|
||
493 | //Now we accept setup mode
|
||
494 | }
|
||
495 | */
|
||
496 | |||
497 | /*if((PORTA.IN & 0x10) == 0x00) //button pushed
|
||
498 | {
|
||
499 | //wait a bit
|
||
500 | _delay_ms(500);
|
||
501 | _delay_ms(500);
|
||
502 | SLPCTRL.CTRLA = (0x01 << 1); //standby sleep mode
|
||
503 | SLPCTRL.CTRLA |= ENABLE_BIT;
|
||
504 | }
|
||
505 |
|
||
506 | PORTA.OUT ^= 0x20;
|
||
507 | counter++;
|
||
508 | _delay_ms(500);*/
|
||
509 | |||
510 | } |
||
511 | |||
512 | return 0; |
||
513 | } |
||
514 | |||
515 | |||
516 | |||
517 | |||
518 | |||
519 | |||
520 | |||
521 | |||
522 | |||
523 | |||
524 | |||
525 | |||
526 | ////////////////////////////////////////////////////////////////////////////
|
||
527 | //Functions
|
||
528 | |||
529 | //Memory configuration functions
|
||
530 | |||
531 | //Control RN4678 memory status
|
||
532 | uint8_t controlRN4678(void)
|
||
533 | { |
||
534 | uint8_t result = 0x02;
|
||
535 | uint8_t _name[16];
|
||
536 | //uint8_t cmd[3];
|
||
537 | uint8_t devNameTrig[] = {'R','N','4','6','7','8'}; |
||
538 | |||
539 | |||
540 | //TODO : Add more reading through Bluetooth module
|
||
541 | //sprintf(cmd, "%s\r", GET_BLM); //prepare get Bluetooth mode cmd
|
||
542 | |||
543 | do
|
||
544 | { |
||
545 | writeCommand(GET_DEVN, 3); //send command |
||
546 | _delay_ms(500); //wait a bit |
||
547 | } |
||
548 | while(usart0_available <= 0); //wait until we've got data |
||
549 | |||
550 | readBuffer(_name, 16); //get request for 16 bytes |
||
551 | |||
552 | while(usart0_available() > 0) //flush dust bytes... |
||
553 | { |
||
554 | usart0_read_byte(); |
||
555 | } |
||
556 | |||
557 | for(uint8_t i = 0; i < 6; i++) |
||
558 | { |
||
559 | result = (_name[i] != devNameTrig[i]) ? 0x00 : result;
|
||
560 | } |
||
561 | if(result == 0x02) //fault detected -> Dev. name = "RN4678-XXXXX" ! |
||
562 | result = 0x01;
|
||
563 | |||
564 | return result;
|
||
565 | } |
||
566 | |||
567 | |||
568 | //Control ATtiny memory CFG
|
||
569 | uint8_t controlCfg(uint8_t *cfg) |
||
570 | { |
||
571 | uint8_t err_code = 0;
|
||
572 | uint16_t local_crc; |
||
573 | |||
574 | |||
575 | //Check Authentification mode
|
||
576 | local_crc = numberOfBit(&cfg[AUTH_ADDR], 1) << 8 | numberOfParity(&cfg[AUTH_ADDR], 1); |
||
577 | if(local_crc != ((cfg[AUTH_ADDR + 1] << 8) | cfg[AUTH_ADDR + 2])) |
||
578 | { |
||
579 | err_code |= 0x01;
|
||
580 | } |
||
581 | |||
582 | //Check Bluetooth mode
|
||
583 | local_crc = numberOfBit(&cfg[BLM_ADDR], 1) << 8 | numberOfParity(&cfg[BLM_ADDR], 1); |
||
584 | if(local_crc != ((cfg[BLM_ADDR + 1] << 8) | cfg[BLM_ADDR + 2])) |
||
585 | { |
||
586 | err_code |= 0x02;
|
||
587 | } |
||
588 | |||
589 | //Check Device name (ISSUE HERE)
|
||
590 | local_crc = numberOfBit(&cfg[DEVN_ADDR], 16) << 8 | numberOfParity(&cfg[DEVN_ADDR], 16); |
||
591 | if(local_crc != ((cfg[DEVN_ADDR + 16] << 8) | cfg[DEVN_ADDR + 17])) //read CRC at DEVN_ADDR + STR_LENGTH (16 alphanumeric char) |
||
592 | { |
||
593 | err_code |= 0x04;
|
||
594 | } |
||
595 | |||
596 | //Check Pincode
|
||
597 | local_crc = numberOfBit(&cfg[PINC_ADDR], 4) << 8 | numberOfParity(&cfg[PINC_ADDR], 4); |
||
598 | if(local_crc != ((cfg[PINC_ADDR + 4] << 8) | cfg[PINC_ADDR + 5])) //read CRC at PINC_ADDR + STR_LENGTH (4 char number) |
||
599 | { |
||
600 | err_code |= 0x08;
|
||
601 | } |
||
602 | |||
603 | //Check Baud (ISSUE HERE)
|
||
604 | local_crc = numberOfBit(&cfg[BAUD_ADDR], 1) << 8 | numberOfParity(&cfg[BAUD_ADDR], 1); |
||
605 | if(local_crc != ((cfg[BAUD_ADDR + 1] << 8) | cfg[BAUD_ADDR + 2])) |
||
606 | { |
||
607 | err_code |= 0x10;
|
||
608 | } |
||
609 | |||
610 | |||
611 | return err_code;
|
||
612 | } |
||
613 | |||
614 | |||
615 | |||
616 | //Read RN4678 in case of ATtiny826 memory corrupt
|
||
617 | void getBluetoothConfiguration(uint8_t *cfg)
|
||
618 | { |
||
619 | |||
620 | char cmd[25]; |
||
621 | int i;
|
||
622 | |||
623 | uint8_t buffer[25];
|
||
624 | |||
625 | |||
626 | //Implement get bluetooth value with index here
|
||
627 | //Authentification Mode
|
||
628 | sprintf(cmd, "%s", GET_AUTH); //prepare get authentification cmd |
||
629 | writeCommand(cmd, 25); //send command |
||
630 | _delay_ms(1000);
|
||
631 | //serialDebug("\r\ncmd : ", 8);
|
||
632 | //serialDebug(cmd, 25);
|
||
633 | |||
634 | readBuffer(buffer, 25); //get request (for 1 byte here) |
||
635 | |||
636 | //serialDebug("\r\nbuf : ", 8);
|
||
637 | //serialDebug(buffer, 25);
|
||
638 | |||
639 | cfg[AUTH_ADDR] = buffer[0]-ASCII_NUMBER_CONVERSION; //store result |
||
640 | //crc calcultate
|
||
641 | cfg[AUTH_ADDR + 1] = numberOfBit(&cfg[AUTH_ADDR], 1); |
||
642 | cfg[AUTH_ADDR + 2] = numberOfParity(&cfg[AUTH_ADDR], 1); |
||
643 | |||
644 | //Bluetooth Mode
|
||
645 | sprintf(cmd, "%s", GET_BLM); //prepare get Bluetooth mode cmd |
||
646 | writeCommand(cmd, 25); //send command |
||
647 | _delay_ms(1000);
|
||
648 | readBuffer(buffer, 25); //get request for 1 byte again |
||
649 | cfg[BLM_ADDR] = buffer[0]-ASCII_NUMBER_CONVERSION; //store result |
||
650 | //serialDebug("\r\nbuffer[0] : ", 14);
|
||
651 | //serialDebug(buffer[0], 1);
|
||
652 | //serialDebug("\r\nbascii[0] : ", 14);
|
||
653 | //serialDebug(buffer[0]-ASCII_NUMBER_CONVERSION, 1);
|
||
654 | //crc calcultate
|
||
655 | cfg[BLM_ADDR + 1] = numberOfBit(&cfg[BLM_ADDR], 1); |
||
656 | cfg[BLM_ADDR + 2] = numberOfParity(&cfg[BLM_ADDR], 1); |
||
657 | |||
658 | |||
659 | //Device Name
|
||
660 | sprintf(cmd, "%s", GET_DEVN); //prepare get Bluetooth dev. name |
||
661 | |||
662 | //serialDebug("\r\ncmd : ", 8);
|
||
663 | //serialDebug(cmd, 25);
|
||
664 | |||
665 | writeCommand(cmd, 25); //send command |
||
666 | _delay_ms(1000);
|
||
667 | readBuffer(buffer, 25); //get request for 16 bytes |
||
668 | //serialDebug("\r\nbuf : ", 8);
|
||
669 | //serialDebug(buffer, 25);
|
||
670 | i = 15; //max buffer for device name |
||
671 | while(buffer[i] != '\r') //clear buffer exclusivity (for name structure) |
||
672 | { |
||
673 | buffer[i] = 0xFF;
|
||
674 | i--; |
||
675 | } |
||
676 | for(i = 0; i < 16; i++) |
||
677 | { |
||
678 | cfg[DEVN_ADDR + i] = buffer[i]; //store name
|
||
679 | } |
||
680 | cfg[DEVN_ADDR + 16] = numberOfBit(&cfg[DEVN_ADDR], 16); |
||
681 | cfg[DEVN_ADDR + 17] = numberOfParity(&cfg[DEVN_ADDR], 16); |
||
682 | |||
683 | |||
684 | //Pincode
|
||
685 | sprintf(cmd, "%s", GET_PINC); //prepare get Bluetooth pin code |
||
686 | writeCommand(cmd, 25); //send command |
||
687 | _delay_ms(1000);
|
||
688 | readBuffer(buffer, 25); //get request for 4 bytes |
||
689 | for(i = 0; i < 4; i++) |
||
690 | { |
||
691 | cfg[PINC_ADDR + i] = buffer[i]; //store name
|
||
692 | } |
||
693 | cfg[PINC_ADDR + 4] = numberOfBit(&cfg[PINC_ADDR], 4); |
||
694 | cfg[PINC_ADDR + 5] = numberOfParity(&cfg[PINC_ADDR], 4); |
||
695 | |||
696 | //Baudrate
|
||
697 | sprintf(cmd, "%s", GET_BAUD); //prepare get Bluetooth mode cmd |
||
698 | writeCommand(cmd, 25); //send command |
||
699 | _delay_ms(1000);
|
||
700 | readBuffer(buffer, 25); //get request for 4 bytes |
||
701 | //Buffer will get "0x" -> buffer[0] = '0' and buffer[1] = 'x'
|
||
702 | cfg[BAUD_ADDR] = (buffer[1] == 'A') ? 0x0A : (buffer[1] == 'B') ? 0x0B : buffer[1] - '0'; //Method "0A", "0B" and "03" to "09" |
||
703 | cfg[BAUD_ADDR + 1] = numberOfBit(&cfg[BAUD_ADDR], 1); |
||
704 | cfg[BAUD_ADDR + 2] = numberOfParity(&cfg[BAUD_ADDR], 1); |
||
705 | |||
706 | //Write into eeprom
|
||
707 | for(i = 0; i < TOP_CFG_ADDR; i++) |
||
708 | { |
||
709 | eeprom_write_byte(i, cfg[i]); |
||
710 | } |
||
711 | } |
||
712 | |||
713 | |||
714 | |||
715 | //Read ATtiny826 in case of RN4678 memory corrupt
|
||
716 | void setBluetoothConfiguration(uint8_t *cfg)
|
||
717 | { |
||
718 | //Implement set bluetooth value with index here
|
||
719 | char cmd[25]; |
||
720 | char _name[16]; |
||
721 | char _pin[4]; |
||
722 | char _authValues[] = { '1', '2', '3', '4', }; |
||
723 | char _blmValues[] = { '0', '1', '2', }; |
||
724 | char *_baudsValues[] = { BAUD_VAL_115200, BAUD_VAL_57600, BAUD_VAL_38400, BAUD_VAL_28800, BAUD_VAL_19200, BAUD_VAL_14400, BAUD_VAL_9600, BAUD_VAL_4800, BAUD_VAL_2400, };
|
||
725 | |||
726 | //Write authentification mode
|
||
727 | sprintf(cmd, "%s%c\r", SET_AUTH, _authValues[cfg[AUTH_ADDR]]);
|
||
728 | writeCommand(cmd, 25); //always put max buffer value, it stop with chara \r ! |
||
729 | //serialDebug(cmd, 25);
|
||
730 | //Write bluetooth mode
|
||
731 | sprintf(cmd, "%s%c\r", SET_BLM, _blmValues[cfg[BLM_ADDR]]);
|
||
732 | writeCommand(cmd, 25); //always put max buffer value, it stop with chara \r ! |
||
733 | //serialDebug(cmd, 25);
|
||
734 | //Write device name
|
||
735 | /*serialDebug("Copy : ", 7);
|
||
736 | serialDebug(&cfg[DEVN_ADDR], 16);
|
||
737 | serialDebug("\r\n", 2);
|
||
738 | serialDebug("Name : ", 7);*/
|
||
739 | strncpy(_name, &cfg[DEVN_ADDR], 16);
|
||
740 | /*serialDebug(_name, 16);
|
||
741 | serialDebug("\r\n", 2);
|
||
742 | serialDebug("DEVN : ", 7);
|
||
743 | serialDebug(SET_DEVN, 3);
|
||
744 | serialDebug("\r\n", 2);*/
|
||
745 | sprintf(cmd, "%s%s\r", SET_DEVN, _name);
|
||
746 | writeCommand(cmd, 25); //always put max buffer value, it stop with chara \r ! |
||
747 | /*serialDebug("cmd : ", 6);
|
||
748 | serialDebug(cmd, 25);
|
||
749 | serialDebug("\r\n", 2);*/
|
||
750 | //Write pin code
|
||
751 | strncpy(_pin, &cfg[PINC_ADDR], 4);
|
||
752 | sprintf(cmd, "%s%s\r", SET_PINC, _pin);
|
||
753 | writeCommand(cmd, 25); //always put max buffer value, it stop with chara \r ! |
||
754 | //serialDebug(cmd, 25);
|
||
755 | //Write baudrate
|
||
756 | sprintf(cmd, "%s%s\r", SET_BAUD, _baudsValues[cfg[BAUD_ADDR]]);
|
||
757 | writeCommand(cmd, 25); //always put max buffer value, it stop with chara \r ! |
||
758 | //serialDebug(cmd, 25);
|
||
759 | } |
||
760 | |||
761 | |||
762 | |||
763 | //Restore Factory setting in ATtiny826 EEPROM and RN4678 EEPROM
|
||
764 | void restoreFactoryConfiguration(uint8_t *cfg)
|
||
765 | { |
||
766 | //Write factory settings inside ATtiny826 EEPROM
|
||
767 | for(int i = 0; i < sizeof(ATtiny826_factory_buffer); i++) |
||
768 | { |
||
769 | cfg[i] = ATtiny826_factory_buffer[i]; |
||
770 | eeprom_write_byte(i, cfg[i]); |
||
771 | } |
||
772 | setBluetoothConfiguration(cfg); //Once we wrote configuration inside ATtiny EEPROM -> Write it on RN4678 EEPROM
|
||
773 | serialDebug("FactoryDone\r\n", 13); |
||
774 | } |
||
775 | |||
776 | |||
777 | |||
778 | |||
779 | void getEEPROMCfg(uint8_t *cfg)
|
||
780 | { |
||
781 | for(uint8_t i = 0; i < TOP_CFG_ADDR; i++) |
||
782 | { |
||
783 | cfg[i] = eeprom_read_byte(i); |
||
784 | _delay_ms(100); //wait a bit when reading eeprom... (so slow :'| ) |
||
785 | } |
||
786 | } |
||
787 | |||
788 | |||
789 | |||
790 | |||
791 | |||
792 | |||
793 | |||
794 | |||
795 | /////////////////////////////////////////////
|
||
796 | //CRC functions
|
||
797 | uint8_t numberOfParity(uint8_t *p, uint8_t n) |
||
798 | { |
||
799 | uint8_t r = 0;
|
||
800 | for(int i = 0; i < n; i++) |
||
801 | { |
||
802 | if(p[i] % 2 == 0) |
||
803 | r+=2;
|
||
804 | else // == 1 |
||
805 | r++; |
||
806 | } |
||
807 | return r;
|
||
808 | } |
||
809 | |||
810 | uint8_t numberOfBit(uint8_t *p, uint8_t n) |
||
811 | { |
||
812 | uint8_t r = 0;
|
||
813 | for(int i = 0; i < n; i++) |
||
814 | { |
||
815 | for(uint8_t j = 1; j != 0; j <<= 1) |
||
816 | { |
||
817 | if((j & p[i]) != 0) |
||
818 | r++; |
||
819 | } |
||
820 | } |
||
821 | return r;
|
||
822 | } |
||
823 | /////////////////////////////////////////////
|
||
824 | //MCU commands function
|
||
825 | |||
826 | //Method to analyse command
|
||
827 | uint8_t gotMCUCommand(uint8_t *buf, uint8_t *frame, uint8_t n) |
||
828 | { |
||
829 | bool result = true; |
||
830 | |||
831 | for(int i = 0; i < n; i++) |
||
832 | { |
||
833 | if((buf[i] != frame[i]))
|
||
834 | { |
||
835 | result = false;
|
||
836 | } |
||
837 | } |
||
838 | return result;
|
||
839 | } |
||
840 | |||
841 | |||
842 | |||
843 | |||
844 | |||
845 | |||
846 | //////////////////////////
|
||
847 | //Analog functions
|
||
848 | |||
849 | void adcInit(void) |
||
850 | { |
||
851 | ADC0.CTRLA = ENABLE_BIT; //Enable register
|
||
852 | ADC0.COMMAND = (ADC_SINGLE_12BIT << 4); //Just use 12 bit resolution (no differential mode) |
||
853 | ADC0.CTRLB = ADC_PRESCALER; //divide clock for conversion
|
||
854 | ADC0.CTRLC = (ADC_TIMEBASE << 3) | ADC_REF; //Set analog reference |
||
855 | ADC0.PGACTRL = (ADC_PGA_GAIN << 5) | (ADC_PGA_BIAS << 3) | (ADC_PGA_SMD << 1) | ENABLE_BIT; //set PGA cfg |
||
856 | ADC0.CTRLE = 0x80; //Set sample duration (SAMPDUR -> p.407) |
||
857 | ADC0.MUXPOS = (ADC_VIA_PGA << 6) | (ADC_MUX_AIN12); //PC0 connected to AIN12 |
||
858 | ADC0.MUXNEG = (ADC_VIA_DIRECT << 6) | (ADC_MUXN_GND); //Set reference in common mode |
||
859 | } |
||
860 | |||
861 | uint16_t adcGetSample(void)
|
||
862 | { |
||
863 | ADC_START_CONV; //as for a conversion
|
||
864 | _delay_ms(1); //wait a bit |
||
865 | while(!ADC0.STATUS); //Wait when conversion is now complete |
||
866 | return ADC_READ; //get stored value |
||
867 | } |
||
868 | |||
869 | |||
870 | void dimmerSetup(void) |
||
871 | { |
||
872 | TCA0.SINGLE.CTRLA = (PWM_DIV << 1) | ENABLE_BIT; //enable register set PWM frequency (datasheet p.209) |
||
873 | TCA0.SINGLE.CTRLB = 0x13; //set output frequency in Single-slope PWM |
||
874 | TCA0.SINGLE.CTRLD = ENABLE_BIT; //enable split mode
|
||
875 | TCA0.SINGLE.CMP0 = PWM_RATE; //set duty cycle
|
||
876 | PORTB.DIR |= PWM_DIMMER_PIN; |
||
877 | } |
||
878 | |||
879 | |||
880 | |||
881 | /////////////////
|
||
882 | //Usart functions
|
||
883 | |||
884 | void serialDebug(const char *str, uint8_t n) |
||
885 | { |
||
886 | for(int i = 0; i < n; i++) |
||
887 | { |
||
888 | usart1_write_byte(str[i]); |
||
889 | _delay_ms(1);
|
||
890 | } |
||
891 | } |
||
892 | |||
893 | void readBuffer(uint8_t *cfg, uint8_t n)
|
||
894 | { |
||
895 | uint8_t _counter = 0;
|
||
896 | _delay_ms(50); //force wait to let buffer filling inside interrutp |
||
897 | while(usart0_available() > 0 && _counter < n) //ensure not overflow buffer... |
||
898 | { |
||
899 | cfg[_counter] = usart0_read_byte(); //now read the stuff
|
||
900 | _counter++; |
||
901 | } |
||
902 | } |
||
903 | |||
904 | void writeCommand(const uint8_t *buf, uint8_t n) |
||
905 | { |
||
906 | int i = 0; |
||
907 | while(i < n)
|
||
908 | { |
||
909 | usart0_write_byte(buf[i]); |
||
910 | //serialDebug("\n\rb: ", 5);
|
||
911 | //usart1_write_byte(buf[i]);
|
||
912 | if(buf[i] == '\r') //read before and increment after |
||
913 | { |
||
914 | i = n; //stop right there
|
||
915 | } |
||
916 | i++; |
||
917 | _delay_ms(10); //wait a bit... |
||
918 | } |
||
919 | } |
||
920 | |||
921 | //Write on TX0 buffer
|
||
922 | void usart0_write_byte(uint8_t b)
|
||
923 | { |
||
924 | USART0.TXDATAL = b; |
||
925 | } |
||
926 | |||
927 | //Write on TX1 buffer
|
||
928 | void usart1_write_byte(uint8_t b)
|
||
929 | { |
||
930 | USART1.TXDATAL = b; |
||
931 | } |
||
932 | |||
933 | //Read on RX0 FIFO buffer
|
||
934 | uint8_t usart0_read_byte(void)
|
||
935 | { |
||
936 | uint8_t r = USART0_Buffer[0];
|
||
937 | for(int i = 0; i < USART0_counter-1; i++) |
||
938 | { |
||
939 | USART0_Buffer[i] = USART0_Buffer[i+1];
|
||
940 | } |
||
941 | USART0_counter--; |
||
942 | return r;
|
||
943 | } |
||
944 | |||
945 | //Read on RX1 FIFO buffer
|
||
946 | uint8_t usart1_read_byte(void)
|
||
947 | { |
||
948 | uint8_t r = USART1_Buffer[0];
|
||
949 | for(int i = 0; i < USART1_counter-1; i++) |
||
950 | { |
||
951 | USART1_Buffer[i] = USART1_Buffer[i+1];
|
||
952 | } |
||
953 | USART1_counter--; |
||
954 | return r;
|
||
955 | } |
||
956 | |||
957 | |||
958 | //Check RX0 FIFO buffer
|
||
959 | uint8_t usart0_available(void)
|
||
960 | { |
||
961 | return USART0_counter;
|
||
962 | } |
||
963 | |||
964 | //Check RX1 FIFO buffer
|
||
965 | uint8_t usart1_available(void)
|
||
966 | { |
||
967 | return USART1_counter;
|
||
968 | } |
||
969 | |||
970 | |||
971 | |||
972 | //////////
|
||
973 | //ISR part
|
||
974 | |||
975 | //When interrupt is occured (Receive complete flag), read RX buffer and store it into the equivalent software buffer
|
||
976 | |||
977 | ISR(USART0_RXC_vect) |
||
978 | { |
||
979 | USART0_Buffer[USART0_counter++] = USART0.RXDATAL; |
||
980 | } |
||
981 | |||
982 | |||
983 | ISR(USART1_RXC_vect) |
||
984 | { |
||
985 | USART1_Buffer[USART1_counter++] = USART1.RXDATAL; |
||
986 | } |