Statistiques
| Branche: | Révision:

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
}