Statistiques
| Branche: | Révision:

root / Version 2.8 / Panel_reader_controller.X / main.c @ 367905ec

Historique | Voir | Annoter | Télécharger (31,372 ko)

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