Commit 1e9aafb0e7b5b118bc042269f1b4e7d0b290229f
Committed by
GitHub
1 parent
ed9f0a60
.
Showing
5 changed files
with
310 additions
and
185 deletions
Examples/Commissioning/Commissioning.ino
| @@ -28,9 +28,9 @@ Changelog: | @@ -28,9 +28,9 @@ Changelog: | ||
| 28 | #define DALI_OUTPUT_PIN 3 | 28 | #define DALI_OUTPUT_PIN 3 |
| 29 | #define DALI_INPUT_PIN 4 | 29 | #define DALI_INPUT_PIN 4 |
| 30 | 30 | ||
| 31 | -#include "qqqDali.h" | 31 | +#include "qqqDali_ATMega328.h" |
| 32 | 32 | ||
| 33 | -Dali dali; | 33 | +Dali_ATMega328 dali; |
| 34 | 34 | ||
| 35 | void setup() { | 35 | void setup() { |
| 36 | Serial.begin(115200); | 36 | Serial.begin(115200); |
| @@ -50,42 +50,52 @@ void loop() { | @@ -50,42 +50,52 @@ void loop() { | ||
| 50 | while (Serial.available() > 0) { | 50 | while (Serial.available() > 0) { |
| 51 | int incomingByte = Serial.read(); | 51 | int incomingByte = Serial.read(); |
| 52 | switch(incomingByte) { | 52 | switch(incomingByte) { |
| 53 | - case '1': scan_short_addr(); menu(); break; | ||
| 54 | - case '2': delete_short_addr(); menu(); break; | ||
| 55 | - case '3': commission_wo_short(); menu(); break; | ||
| 56 | - case '4': commission_all(); menu(); break; | ||
| 57 | - case '5': flash(); menu(); break; } | 53 | + case '1': menu_flash(); menu(); break; |
| 54 | + case '2': menu_scan_short_addr(); menu(); break; | ||
| 55 | + case '3': menu_commission(); menu(); break; | ||
| 56 | + case '4': menu_delete_short_addr(); menu(); break; | ||
| 57 | + } | ||
| 58 | } | 58 | } |
| 59 | } | 59 | } |
| 60 | 60 | ||
| 61 | void menu() { | 61 | void menu() { |
| 62 | Serial.println("----------------------------"); | 62 | Serial.println("----------------------------"); |
| 63 | - Serial.println("1 Scan all short addresses"); | ||
| 64 | - Serial.println("2 Dele1te all short addresses"); | ||
| 65 | - Serial.println("3 Commission w/o short adr"); | ||
| 66 | - Serial.println("4 Commission all short addresses"); | ||
| 67 | - Serial.println("5 Flash all lights"); | 63 | + Serial.println("1 Flash all lights"); |
| 64 | + Serial.println("2 Scan short addresses"); | ||
| 65 | + Serial.println("3 Commission short addresses"); | ||
| 66 | + Serial.println("4 Delete short addresses"); | ||
| 68 | Serial.println("----------------------------"); | 67 | Serial.println("----------------------------"); |
| 69 | } | 68 | } |
| 70 | 69 | ||
| 71 | -void delete_short_addr() { | ||
| 72 | - Serial.println("Running: Delete all short addresses"); | ||
| 73 | - //remove all short addresses | ||
| 74 | - dali.cmd(DALI_DATA_TRANSFER_REGISTER0,0xFF); | ||
| 75 | - dali.cmd(DALI_SET_SHORT_ADDRESS, 0xFF); | 70 | + |
| 71 | +void menu_flash() { | ||
| 72 | + Serial.println("Running: Flash all"); | ||
| 73 | + for(uint8_t i=0;i<5;i++) { | ||
| 74 | + dali.set_level(254); | ||
| 75 | + Serial.print("."); | ||
| 76 | + delay(500); | ||
| 77 | + dali.set_level(0); | ||
| 78 | + Serial.print("."); | ||
| 79 | + delay(500); | ||
| 80 | + } | ||
| 81 | + Serial.println(); | ||
| 76 | } | 82 | } |
| 77 | 83 | ||
| 78 | -void scan_short_addr() { | 84 | +void menu_scan_short_addr() { |
| 79 | Serial.println("Running: Scan all short addresses"); | 85 | Serial.println("Running: Scan all short addresses"); |
| 80 | uint8_t sa; | 86 | uint8_t sa; |
| 87 | + uint8_t cnt = 0; | ||
| 81 | for(sa = 0; sa<64; sa++) { | 88 | for(sa = 0; sa<64; sa++) { |
| 82 | int16_t rv = dali.cmd(DALI_QUERY_STATUS,sa); | 89 | int16_t rv = dali.cmd(DALI_QUERY_STATUS,sa); |
| 83 | if(rv!=DALI_RESULT_NO_REPLY) { | 90 | if(rv!=DALI_RESULT_NO_REPLY) { |
| 91 | + cnt++; | ||
| 92 | + Serial.print("short address="); | ||
| 84 | Serial.print(sa); | 93 | Serial.print(sa); |
| 85 | Serial.print(" status=0x"); | 94 | Serial.print(" status=0x"); |
| 86 | Serial.print(rv,HEX); | 95 | Serial.print(rv,HEX); |
| 87 | Serial.print(" minLevel="); | 96 | Serial.print(" minLevel="); |
| 88 | Serial.print(dali.cmd(DALI_QUERY_MIN_LEVEL,sa)); | 97 | Serial.print(dali.cmd(DALI_QUERY_MIN_LEVEL,sa)); |
| 98 | + Serial.print(" flashing"); | ||
| 89 | for(uint8_t i=0;i<5;i++) { | 99 | for(uint8_t i=0;i<5;i++) { |
| 90 | dali.set_level(254,sa); | 100 | dali.set_level(254,sa); |
| 91 | Serial.print("."); | 101 | Serial.print("."); |
| @@ -102,28 +112,79 @@ void scan_short_addr() { | @@ -102,28 +112,79 @@ void scan_short_addr() { | ||
| 102 | // dali.cmd(DALI_SET_SHORT_ADDRESS, sa); | 112 | // dali.cmd(DALI_SET_SHORT_ADDRESS, sa); |
| 103 | // } | 113 | // } |
| 104 | } | 114 | } |
| 115 | + Serial.print("DONE, found ");Serial.print(cnt);Serial.println(" short addresses"); | ||
| 105 | } | 116 | } |
| 106 | 117 | ||
| 107 | //might need a couple of calls to find everything... | 118 | //might need a couple of calls to find everything... |
| 108 | -void commission_wo_short(){ | ||
| 109 | - Serial.println("Running: Commission w/o short adr"); | ||
| 110 | - dali.commission(0xff); //init_arg=0b11111111 : all without short address | 119 | +void menu_commission(){ |
| 120 | + Serial.println("Running: Commission - be patient, this takes a while ...."); | ||
| 121 | +// uint8_t cnt = dali.commission(0xff); //init_arg=0b11111111 : all without short address | ||
| 122 | + uint8_t cnt = debug_commission(0xff); //init_arg=0b11111111 : all without short address | ||
| 123 | + Serial.print("DONE, assigned ");Serial.print(cnt);Serial.println(" new short addresses"); | ||
| 111 | } | 124 | } |
| 112 | 125 | ||
| 113 | -void commission_all(){ | ||
| 114 | - Serial.println("Running: Commission all"); | ||
| 115 | - dali.commission(0x00); //init_arg=0b00000000 : all | 126 | +void menu_delete_short_addr() { |
| 127 | + Serial.println("Running: Delete all short addresses"); | ||
| 128 | + //remove all short addresses | ||
| 129 | + dali.cmd(DALI_DATA_TRANSFER_REGISTER0,0xFF); | ||
| 130 | + dali.cmd(DALI_SET_SHORT_ADDRESS, 0xFF); | ||
| 131 | + Serial.println("DONE delete"); | ||
| 116 | } | 132 | } |
| 117 | 133 | ||
| 118 | -void flash() { | ||
| 119 | - Serial.println("Running: Flash all"); | ||
| 120 | - for(uint8_t i=0;i<5;i++) { | ||
| 121 | - dali.set_level(254); | ||
| 122 | - Serial.print("."); | ||
| 123 | - delay(500); | ||
| 124 | - dali.set_level(0); | ||
| 125 | - Serial.print("."); | ||
| 126 | - delay(500); | 134 | +//init_arg=11111111 : all without short address |
| 135 | +//init_arg=00000000 : all | ||
| 136 | +//init_arg=0AAAAAA1 : only for this shortadr | ||
| 137 | +//returns number of new short addresses assigned | ||
| 138 | +uint8_t debug_commission(uint8_t init_arg) { | ||
| 139 | + uint8_t cnt = 0; | ||
| 140 | + uint8_t arr[64]; | ||
| 141 | + uint8_t sa; | ||
| 142 | + for(sa=0; sa<64; sa++) arr[sa]=0; | ||
| 143 | + | ||
| 144 | + //find existing short addresses when not assigning all | ||
| 145 | + if(init_arg!=0b00000000) { | ||
| 146 | + Serial.println("Find existing short adr"); | ||
| 147 | + for(sa = 0; sa<64; sa++) { | ||
| 148 | + int16_t rv = dali.cmd(DALI_QUERY_STATUS,sa); | ||
| 149 | + if(rv!=DALI_RESULT_NO_REPLY) { | ||
| 150 | + arr[sa]=1; | ||
| 151 | + Serial.print("sortadr="); | ||
| 152 | + Serial.print(sa); | ||
| 153 | + Serial.print(" status=0x"); | ||
| 154 | + Serial.print(rv,HEX); | ||
| 155 | + Serial.print(" minLevel="); | ||
| 156 | + Serial.println(dali.cmd(DALI_QUERY_MIN_LEVEL,sa)); | ||
| 157 | + } | ||
| 158 | + } | ||
| 127 | } | 159 | } |
| 128 | - Serial.println(); | 160 | + |
| 161 | + dali.cmd(DALI_INITIALISE,init_arg); | ||
| 162 | + dali.cmd(DALI_RANDOMISE,0x00); | ||
| 163 | + | ||
| 164 | + Serial.println("Find random adr"); | ||
| 165 | + while(1) { | ||
| 166 | + uint32_t adr = dali.find_addr(); | ||
| 167 | + if(adr>0xffffff) break; | ||
| 168 | + Serial.print("found="); | ||
| 169 | + Serial.println(adr,HEX); | ||
| 170 | + | ||
| 171 | + //find available address | ||
| 172 | + for(sa=0; sa<64; sa++) { | ||
| 173 | + if(arr[sa]==0) break; | ||
| 174 | + } | ||
| 175 | + if(sa>=64) break; | ||
| 176 | + arr[sa] = 1; | ||
| 177 | + cnt++; | ||
| 178 | + | ||
| 179 | + Serial.print("program short adr="); | ||
| 180 | + Serial.println(sa); | ||
| 181 | + dali.program_short_address(sa); | ||
| 182 | + Serial.print("read short adr="); | ||
| 183 | + Serial.println(dali.query_short_address()); | ||
| 184 | + | ||
| 185 | + dali.cmd(DALI_WITHDRAW,0x00); | ||
| 186 | + } | ||
| 187 | + | ||
| 188 | + dali.cmd(DALI_TERMINATE,0x00); | ||
| 189 | + return cnt; | ||
| 129 | } | 190 | } |
Examples/Dimmer/Dimmer.ino
| @@ -28,9 +28,9 @@ Changelog: | @@ -28,9 +28,9 @@ Changelog: | ||
| 28 | #define DALI_OUTPUT_PIN 3 | 28 | #define DALI_OUTPUT_PIN 3 |
| 29 | #define DALI_INPUT_PIN 4 | 29 | #define DALI_INPUT_PIN 4 |
| 30 | 30 | ||
| 31 | -#include "qqqDali.h" | 31 | +#include "qqqDali_ATMega328.h" |
| 32 | 32 | ||
| 33 | -Dali dali; | 33 | +Dali_ATMega328 dali; |
| 34 | 34 | ||
| 35 | void setup() { | 35 | void setup() { |
| 36 | Serial.begin(115200); | 36 | Serial.begin(115200); |
qqqDali.cpp
| @@ -16,39 +16,25 @@ | @@ -16,39 +16,25 @@ | ||
| 16 | 16 | ||
| 17 | ---------------------------------------------------------------------------- | 17 | ---------------------------------------------------------------------------- |
| 18 | Changelog: | 18 | Changelog: |
| 19 | +2020-11-10 Split off hardware specific code into separate class | ||
| 19 | 2020-11-08 Created & tested on ATMega328 @ 8Mhz | 20 | 2020-11-08 Created & tested on ATMega328 @ 8Mhz |
| 20 | ###########################################################################*/ | 21 | ###########################################################################*/ |
| 21 | #include "qqqDali.h" | 22 | #include "qqqDali.h" |
| 22 | -#include "arduino.h" | ||
| 23 | 23 | ||
| 24 | //########################################################################### | 24 | //########################################################################### |
| 25 | // Helpers | 25 | // Helpers |
| 26 | //########################################################################### | 26 | //########################################################################### |
| 27 | -#define DALI_BUS_LOW() digitalWrite(this->tx_pin,LOW); this->tx_bus_low=1 | ||
| 28 | -#define DALI_BUS_HIGH() digitalWrite(this->tx_pin,HIGH); this->tx_bus_low=0 | ||
| 29 | -#define DALI_IS_BUS_LOW() (digitalRead(this->rx_pin)==LOW) | ||
| 30 | -#define DALI_BAUD 1200 | 27 | +#define DALI_TOL 15 //allow for 15% tolerance on timing (DALI spec calls for 10%, add 5% for uc clock tolerance) |
| 31 | #define DALI_TE ((1000000+(DALI_BAUD))/(2*(DALI_BAUD))) //417us | 28 | #define DALI_TE ((1000000+(DALI_BAUD))/(2*(DALI_BAUD))) //417us |
| 32 | -#define DALI_TE_MIN (80*DALI_TE)/100 | ||
| 33 | -#define DALI_TE_MAX (120*DALI_TE)/100 | 29 | +#define DALI_TE_MIN ((100-DALI_TOL)*DALI_TE)/100 |
| 30 | +#define DALI_TE_MAX ((100+DALI_TOL)*DALI_TE)/100 | ||
| 34 | #define DALI_IS_TE(x) ((DALI_TE_MIN)<=(x) && (x)<=(DALI_TE_MAX)) | 31 | #define DALI_IS_TE(x) ((DALI_TE_MIN)<=(x) && (x)<=(DALI_TE_MAX)) |
| 35 | #define DALI_IS_2TE(x) ((2*(DALI_TE_MIN))<=(x) && (x)<=(2*(DALI_TE_MAX))) | 32 | #define DALI_IS_2TE(x) ((2*(DALI_TE_MIN))<=(x) && (x)<=(2*(DALI_TE_MAX))) |
| 36 | 33 | ||
| 37 | //########################################################################### | 34 | //########################################################################### |
| 38 | // Transmitter ISR | 35 | // Transmitter ISR |
| 39 | //########################################################################### | 36 | //########################################################################### |
| 40 | -static Dali *IsrTimerHooks[DALI_HOOK_COUNT+1]; | ||
| 41 | - | ||
| 42 | -// timer compare interrupt service routine | ||
| 43 | -ISR(TIMER1_COMPA_vect) { | ||
| 44 | - | ||
| 45 | - for(uint8_t i=0;i<DALI_HOOK_COUNT;i++) { | ||
| 46 | - if(IsrTimerHooks[i]==NULL) {return;} | ||
| 47 | - IsrTimerHooks[i]->ISR_timer(); | ||
| 48 | - } | ||
| 49 | -} | ||
| 50 | - | ||
| 51 | -//called every Te period (417us) | 37 | +//called by derived class every Te period (417us) |
| 52 | void Dali::ISR_timer() { | 38 | void Dali::ISR_timer() { |
| 53 | if(this->bus_idle_te_cnt<0xff) this->bus_idle_te_cnt++; | 39 | if(this->bus_idle_te_cnt<0xff) this->bus_idle_te_cnt++; |
| 54 | 40 | ||
| @@ -59,26 +45,29 @@ void Dali::ISR_timer() { | @@ -59,26 +45,29 @@ void Dali::ISR_timer() { | ||
| 59 | case TX_START: | 45 | case TX_START: |
| 60 | //wait for timeslot, then send start bit | 46 | //wait for timeslot, then send start bit |
| 61 | if(this->bus_idle_te_cnt >= 22) { | 47 | if(this->bus_idle_te_cnt >= 22) { |
| 62 | - DALI_BUS_LOW(); | 48 | + this->HAL_set_bus_low(); |
| 49 | + this->tx_bus_low=1; | ||
| 63 | this->tx_state = TX_START_X; | 50 | this->tx_state = TX_START_X; |
| 64 | } | 51 | } |
| 65 | break; | 52 | break; |
| 66 | case TX_START_X: | 53 | case TX_START_X: |
| 67 | - DALI_BUS_HIGH(); | 54 | + this->HAL_set_bus_high(); |
| 55 | + this->tx_bus_low=0; | ||
| 68 | this->tx_pos=0; | 56 | this->tx_pos=0; |
| 69 | this->tx_state = TX_BIT; | 57 | this->tx_state = TX_BIT; |
| 70 | break; | 58 | break; |
| 71 | case TX_BIT: | 59 | case TX_BIT: |
| 72 | - if(this->tx_msg[this->tx_pos>>3] & 1<<(7-(this->tx_pos&0x7))) {DALI_BUS_LOW();} else {DALI_BUS_HIGH();} | 60 | + if(this->tx_msg[this->tx_pos>>3] & 1<<(7-(this->tx_pos&0x7))) {this->HAL_set_bus_low();this->tx_bus_low=1;} else {this->HAL_set_bus_high();this->tx_bus_low=0;} |
| 73 | this->tx_state = TX_BIT_X; | 61 | this->tx_state = TX_BIT_X; |
| 74 | break; | 62 | break; |
| 75 | case TX_BIT_X: | 63 | case TX_BIT_X: |
| 76 | - if(this->tx_msg[this->tx_pos>>3] & 1<<(7-(this->tx_pos&0x7))) {DALI_BUS_HIGH();} else {DALI_BUS_LOW();} | 64 | + if(this->tx_msg[this->tx_pos>>3] & 1<<(7-(this->tx_pos&0x7))) {this->HAL_set_bus_high();this->tx_bus_low=0;} else {this->HAL_set_bus_low();this->tx_bus_low=1;} |
| 77 | this->tx_pos++; | 65 | this->tx_pos++; |
| 78 | if(this->tx_pos < this->tx_len) {this->tx_state = TX_BIT;} else {this->tx_state = TX_STOP1;} | 66 | if(this->tx_pos < this->tx_len) {this->tx_state = TX_BIT;} else {this->tx_state = TX_STOP1;} |
| 79 | break; | 67 | break; |
| 80 | case TX_STOP1: | 68 | case TX_STOP1: |
| 81 | - DALI_BUS_HIGH(); | 69 | + this->HAL_set_bus_high(); |
| 70 | + this->tx_bus_low=0; | ||
| 82 | this->tx_state = TX_STOP1_X; | 71 | this->tx_state = TX_STOP1_X; |
| 83 | break; | 72 | break; |
| 84 | case TX_STOP1_X: | 73 | case TX_STOP1_X: |
| @@ -105,7 +94,7 @@ void Dali::ISR_timer() { | @@ -105,7 +94,7 @@ void Dali::ISR_timer() { | ||
| 105 | uint8_t bitlen = (this->rx_halfbitlen+1)>>1; | 94 | uint8_t bitlen = (this->rx_halfbitlen+1)>>1; |
| 106 | if((bitlen & 0x7) == 0) { | 95 | if((bitlen & 0x7) == 0) { |
| 107 | this->rx_len = bitlen>>3; | 96 | this->rx_len = bitlen>>3; |
| 108 | - if(this->EventHandlerReceivedData!=NULL) this->EventHandlerReceivedData(this, (uint8_t*)this->rx_msg, this->rx_len); | 97 | + if(this->EventHandlerReceivedData) this->EventHandlerReceivedData(this, (uint8_t*)this->rx_msg, this->rx_len); |
| 109 | }else{ | 98 | }else{ |
| 110 | //invalid bitlen | 99 | //invalid bitlen |
| 111 | //TODO handle this | 100 | //TODO handle this |
| @@ -116,29 +105,11 @@ void Dali::ISR_timer() { | @@ -116,29 +105,11 @@ void Dali::ISR_timer() { | ||
| 116 | //########################################################################### | 105 | //########################################################################### |
| 117 | // Receiver ISR | 106 | // Receiver ISR |
| 118 | //########################################################################### | 107 | //########################################################################### |
| 119 | -//pin PCINT | ||
| 120 | -//0-7 PCINT2_vect PCINT16-23 | ||
| 121 | -//8-13 PCINT0_vect PCINT0-5 | ||
| 122 | -//14-19 PCINT1_vect PCINT8-13 | ||
| 123 | -static Dali *IsrPCINT0Hook; | ||
| 124 | -static Dali *IsrPCINT1Hook; | ||
| 125 | -static Dali *IsrPCINT2Hook; | ||
| 126 | - | ||
| 127 | -ISR(PCINT0_vect) { | ||
| 128 | - if(IsrPCINT0Hook!=NULL) IsrPCINT0Hook->ISR_pinchange(); | ||
| 129 | -} | ||
| 130 | -ISR(PCINT1_vect) { | ||
| 131 | - if(IsrPCINT1Hook!=NULL) IsrPCINT1Hook->ISR_pinchange(); | ||
| 132 | -} | ||
| 133 | -ISR(PCINT2_vect) { | ||
| 134 | - if(IsrPCINT2Hook!=NULL) IsrPCINT2Hook->ISR_pinchange(); | ||
| 135 | -} | ||
| 136 | - | ||
| 137 | - | 108 | +//called by derived class on bus state change |
| 138 | void Dali::ISR_pinchange() { | 109 | void Dali::ISR_pinchange() { |
| 139 | - uint32_t ts = micros(); //get timestamp of change | 110 | + uint32_t ts = this->HAL_micros(); //get timestamp of change |
| 140 | this->bus_idle_te_cnt=0; //reset idle counter | 111 | this->bus_idle_te_cnt=0; //reset idle counter |
| 141 | - uint8_t bus_low = DALI_IS_BUS_LOW(); | 112 | + uint8_t bus_low = this->HAL_is_bus_low(); |
| 142 | 113 | ||
| 143 | //exit if transmitting | 114 | //exit if transmitting |
| 144 | if(this->tx_state != TX_IDLE) { | 115 | if(this->tx_state != TX_IDLE) { |
| @@ -206,63 +177,6 @@ void Dali::push_halfbit(uint8_t bit) { | @@ -206,63 +177,6 @@ void Dali::push_halfbit(uint8_t bit) { | ||
| 206 | //########################################################################### | 177 | //########################################################################### |
| 207 | // Dali Class | 178 | // Dali Class |
| 208 | //########################################################################### | 179 | //########################################################################### |
| 209 | -void Dali::begin(int8_t tx_pin, int8_t rx_pin) { | ||
| 210 | - this->tx_pin = tx_pin; | ||
| 211 | - this->rx_pin = rx_pin; | ||
| 212 | - this->tx_state = TX_IDLE; | ||
| 213 | - this->rx_state = RX_IDLE; | ||
| 214 | - | ||
| 215 | - //setup tx | ||
| 216 | - if(this->tx_pin>=0) { | ||
| 217 | - //setup tx pin | ||
| 218 | - pinMode(this->tx_pin, OUTPUT); | ||
| 219 | - DALI_BUS_HIGH(); | ||
| 220 | - | ||
| 221 | - //setup tx timer interrupt | ||
| 222 | - TCCR1A = 0; | ||
| 223 | - TCCR1B = 0; | ||
| 224 | - TCNT1 = 0; | ||
| 225 | - | ||
| 226 | - OCR1A = (F_CPU+(DALI_BAUD))/(2*(DALI_BAUD)); // compare match register 16MHz/256/2Hz | ||
| 227 | - TCCR1B |= (1 << WGM12); // CTC mode | ||
| 228 | - TCCR1B |= (1 << CS10); // 1:1 prescaler | ||
| 229 | - TIMSK1 |= (1 << OCIE1A); // enable timer compare interrupt | ||
| 230 | - | ||
| 231 | - //setup timer interrupt hooks | ||
| 232 | - for(uint8_t i=0;i<DALI_HOOK_COUNT;i++) { | ||
| 233 | - if(IsrTimerHooks[i] == NULL) { | ||
| 234 | - IsrTimerHooks[i] = this; | ||
| 235 | - break; | ||
| 236 | - } | ||
| 237 | - } | ||
| 238 | - } | ||
| 239 | - | ||
| 240 | - //setup rx | ||
| 241 | - if(this->rx_pin>=0) { | ||
| 242 | - //setup rx pin | ||
| 243 | - pinMode(this->rx_pin, INPUT); | ||
| 244 | - | ||
| 245 | - //setup rx pinchange interrupt | ||
| 246 | - // 0- 7 PCINT2_vect PCINT16-23 | ||
| 247 | - // 8-13 PCINT0_vect PCINT0-5 | ||
| 248 | - //14-19 PCINT1_vect PCINT8-13 | ||
| 249 | - if(this->rx_pin<=7){ | ||
| 250 | - PCICR |= (1<<PCIE2); | ||
| 251 | - PCMSK2 |= (1<< (this->rx_pin)); | ||
| 252 | - IsrPCINT2Hook = this; //setup pinchange interrupt hook | ||
| 253 | - }else if(this->rx_pin<=13) { | ||
| 254 | - PCICR |= (1<<PCIE0); | ||
| 255 | - PCMSK0 |= (1<< (this->rx_pin-8)); | ||
| 256 | - IsrPCINT0Hook = this; //setup pinchange interrupt hook | ||
| 257 | - }else if(this->rx_pin<=19) { | ||
| 258 | - PCICR |= (1<<PCIE1); | ||
| 259 | - PCMSK1 |= (1<< (this->rx_pin-14)); | ||
| 260 | - IsrPCINT1Hook = this; //setup pinchange interrupt hook | ||
| 261 | - } | ||
| 262 | - } | ||
| 263 | -} | ||
| 264 | - | ||
| 265 | - | ||
| 266 | uint8_t Dali::send(uint8_t* tx_msg, uint8_t tx_len_bytes) { | 180 | uint8_t Dali::send(uint8_t* tx_msg, uint8_t tx_len_bytes) { |
| 267 | if(tx_len_bytes>3) return -(DALI_RESULT_INVALID_TOO_LONG); | 181 | if(tx_len_bytes>3) return -(DALI_RESULT_INVALID_TOO_LONG); |
| 268 | if(this->tx_state != TX_IDLE) return -(DALI_RESULT_TIMEOUT); | 182 | if(this->tx_state != TX_IDLE) return -(DALI_RESULT_TIMEOUT); |
| @@ -273,41 +187,41 @@ uint8_t Dali::send(uint8_t* tx_msg, uint8_t tx_len_bytes) { | @@ -273,41 +187,41 @@ uint8_t Dali::send(uint8_t* tx_msg, uint8_t tx_len_bytes) { | ||
| 273 | return 0; | 187 | return 0; |
| 274 | } | 188 | } |
| 275 | 189 | ||
| 276 | -uint8_t Dali::sendwait(uint8_t* tx_msg, uint8_t tx_len_bytes, uint32_t timeout_ms) { | 190 | +uint8_t Dali::sendwait(uint8_t* tx_msg, uint8_t tx_len_bytes, uint32_t timeout_us) { |
| 277 | if(tx_len_bytes>3) return -(DALI_RESULT_INVALID_TOO_LONG); | 191 | if(tx_len_bytes>3) return -(DALI_RESULT_INVALID_TOO_LONG); |
| 278 | - uint32_t ts = millis(); | 192 | + uint32_t ts = HAL_micros(); |
| 279 | //wait for idle | 193 | //wait for idle |
| 280 | while(this->tx_state != TX_IDLE) { | 194 | while(this->tx_state != TX_IDLE) { |
| 281 | - if(millis() - ts > timeout_ms) return -(DALI_RESULT_TIMEOUT); | 195 | + if(HAL_micros() - ts > timeout_us) return -(DALI_RESULT_TIMEOUT); |
| 282 | } | 196 | } |
| 283 | //start transmit | 197 | //start transmit |
| 284 | uint8_t rv = this->send(tx_msg,tx_len_bytes); | 198 | uint8_t rv = this->send(tx_msg,tx_len_bytes); |
| 285 | if(rv) return rv; | 199 | if(rv) return rv; |
| 286 | //wait for completion | 200 | //wait for completion |
| 287 | while(this->tx_state != TX_IDLE) { | 201 | while(this->tx_state != TX_IDLE) { |
| 288 | - if(millis() - ts > timeout_ms) return -(DALI_RESULT_TX_TIMEOUT); | 202 | + if(HAL_micros() - ts > timeout_us) return -(DALI_RESULT_TX_TIMEOUT); |
| 289 | } | 203 | } |
| 290 | return 0; | 204 | return 0; |
| 291 | } | 205 | } |
| 292 | 206 | ||
| 293 | //transmit 2 byte command, receive 1 byte reply | 207 | //transmit 2 byte command, receive 1 byte reply |
| 294 | -int16_t Dali::tx(uint8_t cmd0, uint8_t cmd1, uint32_t timeout_ms) { | 208 | +int16_t Dali::tx(uint8_t cmd0, uint8_t cmd1, uint32_t timeout_us) { |
| 295 | uint8_t tx[2]; | 209 | uint8_t tx[2]; |
| 296 | tx[0] = cmd0; | 210 | tx[0] = cmd0; |
| 297 | tx[1] = cmd1; | 211 | tx[1] = cmd1; |
| 298 | - int16_t rv = this->sendwait(tx,2); | 212 | + int16_t rv = this->sendwait(tx, 2, timeout_us); |
| 299 | this->rx_halfbitlen = 0; | 213 | this->rx_halfbitlen = 0; |
| 300 | if(rv) return -rv;; | 214 | if(rv) return -rv;; |
| 301 | 215 | ||
| 302 | //wait up to 10 ms for start of reply | 216 | //wait up to 10 ms for start of reply |
| 303 | - uint32_t ts = millis(); | 217 | + uint32_t ts = HAL_micros(); |
| 304 | while(this->rx_state == RX_IDLE) { | 218 | while(this->rx_state == RX_IDLE) { |
| 305 | - if(millis() - ts > 10) return DALI_RESULT_NO_REPLY; | 219 | + if(HAL_micros() - ts > 10000) return DALI_RESULT_NO_REPLY; |
| 306 | } | 220 | } |
| 307 | //wait up to 15 ms for completion of reply | 221 | //wait up to 15 ms for completion of reply |
| 308 | - ts = millis(); | 222 | + ts = HAL_micros(); |
| 309 | while(this->rx_len == 0) { | 223 | while(this->rx_len == 0) { |
| 310 | - if(millis() - ts > 15) return DALI_RESULT_NO_REPLY; | 224 | + if(HAL_micros() - ts > 15000) return DALI_RESULT_NO_REPLY; |
| 311 | } | 225 | } |
| 312 | if(this->rx_len > 1) return DALI_RESULT_INVALID_REPLY; | 226 | if(this->rx_len > 1) return DALI_RESULT_INVALID_REPLY; |
| 313 | return this->rx_msg[0]; | 227 | return this->rx_msg[0]; |
| @@ -464,41 +378,40 @@ uint32_t Dali::find_addr() { | @@ -464,41 +378,40 @@ uint32_t Dali::find_addr() { | ||
| 464 | //init_arg=11111111 : all without short address | 378 | //init_arg=11111111 : all without short address |
| 465 | //init_arg=00000000 : all | 379 | //init_arg=00000000 : all |
| 466 | //init_arg=0AAAAAA1 : only for this shortadr | 380 | //init_arg=0AAAAAA1 : only for this shortadr |
| 381 | +//returns number of new short addresses assigned | ||
| 467 | uint8_t Dali::commission(uint8_t init_arg) { | 382 | uint8_t Dali::commission(uint8_t init_arg) { |
| 468 | uint8_t cnt = 0; | 383 | uint8_t cnt = 0; |
| 469 | uint8_t arr[64]; | 384 | uint8_t arr[64]; |
| 470 | uint8_t sa; | 385 | uint8_t sa; |
| 471 | for(sa=0; sa<64; sa++) arr[sa]=0; | 386 | for(sa=0; sa<64; sa++) arr[sa]=0; |
| 472 | 387 | ||
| 473 | - //find existing short addresses | ||
| 474 | -// if(init_arg==0xff) { | ||
| 475 | - Serial.println("Short adr"); | 388 | + //find existing short addresses when not assigning all |
| 389 | + if(init_arg!=0b00000000) { | ||
| 390 | + //Serial.println("Short adr"); | ||
| 476 | for(sa = 0; sa<64; sa++) { | 391 | for(sa = 0; sa<64; sa++) { |
| 477 | int16_t rv = this->cmd(DALI_QUERY_STATUS,sa); | 392 | int16_t rv = this->cmd(DALI_QUERY_STATUS,sa); |
| 478 | if(rv!=DALI_RESULT_NO_REPLY) { | 393 | if(rv!=DALI_RESULT_NO_REPLY) { |
| 479 | arr[sa]=1; | 394 | arr[sa]=1; |
| 480 | - cnt++; | ||
| 481 | - Serial.print(sa); | ||
| 482 | - Serial.print(" status=0x"); | ||
| 483 | - Serial.print(rv,HEX); | ||
| 484 | - Serial.print(" minLevel="); | ||
| 485 | - Serial.println(this->cmd(DALI_QUERY_MIN_LEVEL,sa)); | 395 | + //Serial.print(sa); |
| 396 | + //Serial.print(" status=0x"); | ||
| 397 | + //Serial.print(rv,HEX); | ||
| 398 | + //Serial.print(" minLevel="); | ||
| 399 | + //Serial.println(this->cmd(DALI_QUERY_MIN_LEVEL,sa)); | ||
| 486 | } | 400 | } |
| 487 | } | 401 | } |
| 488 | -// } | 402 | + } |
| 489 | 403 | ||
| 490 | this->cmd(DALI_INITIALISE,init_arg); | 404 | this->cmd(DALI_INITIALISE,init_arg); |
| 491 | this->cmd(DALI_RANDOMISE,0x00); | 405 | this->cmd(DALI_RANDOMISE,0x00); |
| 492 | - delay(100); | ||
| 493 | 406 | ||
| 494 | - while(cnt<64) { | 407 | + while(1) { |
| 495 | //Serial.print("addr="); | 408 | //Serial.print("addr="); |
| 496 | //Serial.println(this->get_random_address(0xff),HEX); | 409 | //Serial.println(this->get_random_address(0xff),HEX); |
| 497 | 410 | ||
| 498 | uint32_t adr = this->find_addr(); | 411 | uint32_t adr = this->find_addr(); |
| 499 | - if(adr>0xffffff) break; | ||
| 500 | - Serial.print("found adr="); | ||
| 501 | - Serial.println(adr,HEX); | 412 | + if(adr>0xffffff) break; //no more random addresses found -> exit |
| 413 | + //Serial.print("found adr="); | ||
| 414 | + //Serial.println(adr,HEX); | ||
| 502 | 415 | ||
| 503 | //Serial.print("short adr="); | 416 | //Serial.print("short adr="); |
| 504 | //Serial.println(dali_query_short_address()); | 417 | //Serial.println(dali_query_short_address()); |
| @@ -507,17 +420,17 @@ uint8_t Dali::commission(uint8_t init_arg) { | @@ -507,17 +420,17 @@ uint8_t Dali::commission(uint8_t init_arg) { | ||
| 507 | for(sa=0; sa<64; sa++) { | 420 | for(sa=0; sa<64; sa++) { |
| 508 | if(arr[sa]==0) break; | 421 | if(arr[sa]==0) break; |
| 509 | } | 422 | } |
| 510 | - if(sa>=64) break; | 423 | + if(sa>=64) break; //all 64 short addresses assigned -> exit |
| 511 | arr[sa] = 1; | 424 | arr[sa] = 1; |
| 512 | cnt++; | 425 | cnt++; |
| 513 | 426 | ||
| 514 | - Serial.print("program short adr="); | ||
| 515 | - Serial.println(sa); | 427 | + //Serial.print("program short adr="); |
| 428 | + //Serial.println(sa); | ||
| 516 | this->program_short_address(sa); | 429 | this->program_short_address(sa); |
| 517 | //dali_program_short_address(0xff); | 430 | //dali_program_short_address(0xff); |
| 518 | 431 | ||
| 519 | - Serial.print("read short adr="); | ||
| 520 | - Serial.println(this->query_short_address()); | 432 | + //Serial.print("read short adr="); |
| 433 | + //Serial.println(this->query_short_address()); //TODO check read adr, handle if not the same... | ||
| 521 | 434 | ||
| 522 | this->cmd(DALI_WITHDRAW,0x00); | 435 | this->cmd(DALI_WITHDRAW,0x00); |
| 523 | } | 436 | } |
qqqDali.h
| @@ -16,14 +16,24 @@ | @@ -16,14 +16,24 @@ | ||
| 16 | 16 | ||
| 17 | ---------------------------------------------------------------------------- | 17 | ---------------------------------------------------------------------------- |
| 18 | Changelog: | 18 | Changelog: |
| 19 | +2020-11-10 Split off hardware specific code into separate class | ||
| 19 | 2020-11-08 Created & tested on ATMega328 @ 8Mhz | 20 | 2020-11-08 Created & tested on ATMega328 @ 8Mhz |
| 20 | ###########################################################################*/ | 21 | ###########################################################################*/ |
| 21 | #include <inttypes.h> | 22 | #include <inttypes.h> |
| 22 | 23 | ||
| 23 | - | ||
| 24 | class Dali { | 24 | class Dali { |
| 25 | public: | 25 | public: |
| 26 | - void begin(int8_t tx_pin, int8_t rx_pin); | 26 | + //Hardware Abstraction Layer overrides |
| 27 | + virtual void HAL_set_bus_low() const = 0; //set DALI bus to low state | ||
| 28 | + virtual void HAL_set_bus_high() const = 0; //set DALI bus to high state | ||
| 29 | + virtual uint8_t HAL_is_bus_low() const = 0; //is DALI bus in low state? | ||
| 30 | + virtual uint32_t HAL_micros() const = 0; //get microsecond time stamp | ||
| 31 | + void ISR_timer(); //call this function every 417us | ||
| 32 | + void ISR_pinchange(); //call this function on change of DALI bus | ||
| 33 | + | ||
| 34 | + //callback on received data from DALI bus | ||
| 35 | + typedef void (*EventHandlerReceivedDataFuncPtr)(Dali *sender, uint8_t *data, uint8_t len); | ||
| 36 | + EventHandlerReceivedDataFuncPtr EventHandlerReceivedData; | ||
| 27 | 37 | ||
| 28 | //high level functions | 38 | //high level functions |
| 29 | void set_level(uint8_t level, uint8_t adr=0xFF); //set arc level | 39 | void set_level(uint8_t level, uint8_t adr=0xFF); //set arc level |
| @@ -43,24 +53,17 @@ public: | @@ -43,24 +53,17 @@ public: | ||
| 43 | uint8_t query_short_address(); | 53 | uint8_t query_short_address(); |
| 44 | uint32_t find_addr(); | 54 | uint32_t find_addr(); |
| 45 | 55 | ||
| 46 | - | ||
| 47 | //low level functions | 56 | //low level functions |
| 48 | - typedef void (*EventHandlerReceivedDataFuncPtr)(Dali *sender, uint8_t *data, uint8_t len); | ||
| 49 | - EventHandlerReceivedDataFuncPtr EventHandlerReceivedData; | ||
| 50 | - | ||
| 51 | uint8_t send(uint8_t* tx_msg, uint8_t tx_len_bytes); | 57 | uint8_t send(uint8_t* tx_msg, uint8_t tx_len_bytes); |
| 52 | - uint8_t sendwait(uint8_t* tx_msg, uint8_t tx_len_bytes, uint32_t timeout_ms=500); | ||
| 53 | - int16_t tx(uint8_t cmd0, uint8_t cmd1, uint32_t timeout_ms=500); | ||
| 54 | - void ISR_timer(); | ||
| 55 | - void ISR_pinchange(); | 58 | + uint8_t sendwait(uint8_t* tx_msg, uint8_t tx_len_bytes, uint32_t timeout_us=500000); |
| 59 | + int16_t tx(uint8_t cmd0, uint8_t cmd1, uint32_t timeout_us=500000); | ||
| 56 | 60 | ||
| 57 | - #define DALI_HOOK_COUNT 3 | ||
| 58 | - | ||
| 59 | - | ||
| 60 | -private: | 61 | + //initialize variables |
| 62 | + Dali() : tx_state(TX_IDLE), rx_state(RX_IDLE), tx_bus_low(0), tx_len(0), EventHandlerReceivedData(0) {}; | ||
| 63 | + | ||
| 64 | +protected: | ||
| 61 | //low level functions | 65 | //low level functions |
| 62 | enum tx_stateEnum { TX_IDLE=0,TX_START,TX_START_X,TX_BIT,TX_BIT_X,TX_STOP1,TX_STOP1_X,TX_STOP2,TX_STOP2_X,TX_STOP3}; | 66 | enum tx_stateEnum { TX_IDLE=0,TX_START,TX_START_X,TX_BIT,TX_BIT_X,TX_STOP1,TX_STOP1_X,TX_STOP2,TX_STOP2_X,TX_STOP3}; |
| 63 | - uint8_t tx_pin; //transmitter pin | ||
| 64 | uint8_t tx_msg[3]; //message to transmit | 67 | uint8_t tx_msg[3]; //message to transmit |
| 65 | uint8_t tx_len; //number of bits to transmit | 68 | uint8_t tx_len; //number of bits to transmit |
| 66 | volatile uint8_t tx_pos; //current bit transmit position | 69 | volatile uint8_t tx_pos; //current bit transmit position |
| @@ -69,7 +72,6 @@ private: | @@ -69,7 +72,6 @@ private: | ||
| 69 | volatile uint8_t tx_bus_low; //bus is low according to transmitter? | 72 | volatile uint8_t tx_bus_low; //bus is low according to transmitter? |
| 70 | 73 | ||
| 71 | enum rx_stateEnum { RX_IDLE,RX_START,RX_BIT}; | 74 | enum rx_stateEnum { RX_IDLE,RX_START,RX_BIT}; |
| 72 | - uint8_t rx_pin; //receiver pin | ||
| 73 | volatile uint8_t rx_last_bus_low; //receiver as low at last pinchange | 75 | volatile uint8_t rx_last_bus_low; //receiver as low at last pinchange |
| 74 | volatile uint32_t rx_last_change_ts; //timestamp last pinchange | 76 | volatile uint32_t rx_last_change_ts; //timestamp last pinchange |
| 75 | volatile rx_stateEnum rx_state; //current state | 77 | volatile rx_stateEnum rx_state; //current state |
| @@ -88,6 +90,10 @@ private: | @@ -88,6 +90,10 @@ private: | ||
| 88 | }; | 90 | }; |
| 89 | 91 | ||
| 90 | 92 | ||
| 93 | + | ||
| 94 | + | ||
| 95 | +#define DALI_BAUD 1200 | ||
| 96 | + | ||
| 91 | #define DALI_RESULT_TIMEOUT -1 //Timeout waiting for DALI bus | 97 | #define DALI_RESULT_TIMEOUT -1 //Timeout waiting for DALI bus |
| 92 | #define DALI_RESULT_INVALID_TOO_LONG -2 //Trying to send too many bytes (max 3) | 98 | #define DALI_RESULT_INVALID_TOO_LONG -2 //Trying to send too many bytes (max 3) |
| 93 | #define DALI_RESULT_TX_TIMEOUT -3 //Timeout during transmission | 99 | #define DALI_RESULT_TX_TIMEOUT -3 //Timeout during transmission |
qqqDali_ATMega328.h
0 โ 100644
| 1 | +/*########################################################################### | ||
| 2 | + qqqDali_ATMega328.h - copyright qqqlab.com / github.com/qqqlab | ||
| 3 | + | ||
| 4 | + This program is free software: you can redistribute it and/or modify | ||
| 5 | + it under the terms of the GNU General Public License as published by | ||
| 6 | + the Free Software Foundation, either version 3 of the License, or | ||
| 7 | + (at your option) any later version. | ||
| 8 | + | ||
| 9 | + This program is distributed in the hope that it will be useful, | ||
| 10 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | + GNU General Public License for more details. | ||
| 13 | + | ||
| 14 | + You should have received a copy of the GNU General Public License | ||
| 15 | + along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | + | ||
| 17 | +---------------------------------------------------------------------------- | ||
| 18 | +Changelog: | ||
| 19 | +2020-11-10 Created & tested on ATMega328 @ 8Mhz | ||
| 20 | +###########################################################################*/ | ||
| 21 | +#include "arduino.h" | ||
| 22 | +#include "qqqDali.h" | ||
| 23 | + | ||
| 24 | +#define DALI_HOOK_COUNT 3 | ||
| 25 | + | ||
| 26 | +class Dali_ATMega328 : public Dali { | ||
| 27 | +public: | ||
| 28 | + void begin(int8_t tx_pin, int8_t rx_pin); | ||
| 29 | + virtual void HAL_set_bus_low() const override; | ||
| 30 | + virtual void HAL_set_bus_high() const override; | ||
| 31 | + virtual uint8_t HAL_is_bus_low() const override; | ||
| 32 | + virtual uint32_t HAL_micros() const override; | ||
| 33 | + | ||
| 34 | +private: | ||
| 35 | + uint8_t tx_pin; //transmitter pin | ||
| 36 | + uint8_t rx_pin; //receiver pin | ||
| 37 | +}; | ||
| 38 | + | ||
| 39 | +//----------------------------------------- | ||
| 40 | +//Hardware Abstraction Layer | ||
| 41 | +void Dali_ATMega328::HAL_set_bus_low() const { | ||
| 42 | + digitalWrite(this->tx_pin,LOW); | ||
| 43 | +} | ||
| 44 | + | ||
| 45 | +void Dali_ATMega328::HAL_set_bus_high() const { | ||
| 46 | + digitalWrite(this->tx_pin,HIGH); | ||
| 47 | +} | ||
| 48 | + | ||
| 49 | +uint8_t Dali_ATMega328::HAL_is_bus_low() const { | ||
| 50 | + return (digitalRead(this->rx_pin) == LOW); | ||
| 51 | +} | ||
| 52 | + | ||
| 53 | +uint32_t Dali_ATMega328::HAL_micros() const { | ||
| 54 | + return micros(); | ||
| 55 | +} | ||
| 56 | + | ||
| 57 | +//----------------------------------------- | ||
| 58 | +// Transmitter ISR | ||
| 59 | +static Dali *IsrTimerHooks[DALI_HOOK_COUNT+1]; | ||
| 60 | + | ||
| 61 | +// timer compare interrupt service routine | ||
| 62 | +ISR(TIMER1_COMPA_vect) { | ||
| 63 | + | ||
| 64 | + for(uint8_t i=0;i<DALI_HOOK_COUNT;i++) { | ||
| 65 | + if(IsrTimerHooks[i]==NULL) {return;} | ||
| 66 | + IsrTimerHooks[i]->ISR_timer(); | ||
| 67 | + } | ||
| 68 | +} | ||
| 69 | + | ||
| 70 | +//----------------------------------------- | ||
| 71 | +// Receiver ISR | ||
| 72 | +//pin PCINT | ||
| 73 | +//0-7 PCINT2_vect PCINT16-23 | ||
| 74 | +//8-13 PCINT0_vect PCINT0-5 | ||
| 75 | +//14-19 PCINT1_vect PCINT8-13 | ||
| 76 | +static Dali *IsrPCINT0Hook; | ||
| 77 | +static Dali *IsrPCINT1Hook; | ||
| 78 | +static Dali *IsrPCINT2Hook; | ||
| 79 | + | ||
| 80 | +ISR(PCINT0_vect) { | ||
| 81 | + if(IsrPCINT0Hook!=NULL) IsrPCINT0Hook->ISR_pinchange(); | ||
| 82 | +} | ||
| 83 | +ISR(PCINT1_vect) { | ||
| 84 | + if(IsrPCINT1Hook!=NULL) IsrPCINT1Hook->ISR_pinchange(); | ||
| 85 | +} | ||
| 86 | +ISR(PCINT2_vect) { | ||
| 87 | + if(IsrPCINT2Hook!=NULL) IsrPCINT2Hook->ISR_pinchange(); | ||
| 88 | +} | ||
| 89 | + | ||
| 90 | + | ||
| 91 | +//----------------------------------------- | ||
| 92 | +// begin | ||
| 93 | +void Dali_ATMega328::begin(int8_t tx_pin, int8_t rx_pin) { | ||
| 94 | + this->tx_pin = tx_pin; | ||
| 95 | + this->rx_pin = rx_pin; | ||
| 96 | + | ||
| 97 | + //setup tx | ||
| 98 | + if(this->tx_pin>=0) { | ||
| 99 | + //setup tx pin | ||
| 100 | + pinMode(this->tx_pin, OUTPUT); | ||
| 101 | + this->HAL_set_bus_high(); | ||
| 102 | + this->tx_bus_low=0; | ||
| 103 | + | ||
| 104 | + //setup tx timer interrupt | ||
| 105 | + TCCR1A = 0; | ||
| 106 | + TCCR1B = 0; | ||
| 107 | + TCNT1 = 0; | ||
| 108 | + OCR1A = (F_CPU+(DALI_BAUD))/(2*(DALI_BAUD)); // compare match register at baud rate * 2 | ||
| 109 | + TCCR1B |= (1 << WGM12); // CTC mode | ||
| 110 | + TCCR1B |= (1 << CS10); // 1:1 prescaler | ||
| 111 | + TIMSK1 |= (1 << OCIE1A); // enable timer compare interrupt | ||
| 112 | + | ||
| 113 | + //setup timer interrupt hooks | ||
| 114 | + for(uint8_t i=0;i<DALI_HOOK_COUNT;i++) { | ||
| 115 | + if(IsrTimerHooks[i] == NULL) { | ||
| 116 | + IsrTimerHooks[i] = this; | ||
| 117 | + break; | ||
| 118 | + } | ||
| 119 | + } | ||
| 120 | + } | ||
| 121 | + | ||
| 122 | + //setup rx | ||
| 123 | + if(this->rx_pin>=0) { | ||
| 124 | + //setup rx pin | ||
| 125 | + pinMode(this->rx_pin, INPUT); | ||
| 126 | + | ||
| 127 | + //setup rx pinchange interrupt | ||
| 128 | + // 0- 7 PCINT2_vect PCINT16-23 | ||
| 129 | + // 8-13 PCINT0_vect PCINT0-5 | ||
| 130 | + //14-19 PCINT1_vect PCINT8-13 | ||
| 131 | + if(this->rx_pin <= 7){ | ||
| 132 | + PCICR |= (1 << PCIE2); | ||
| 133 | + PCMSK2 |= (1 << (this->rx_pin)); | ||
| 134 | + IsrPCINT2Hook = this; //setup pinchange interrupt hook | ||
| 135 | + }else if(this->rx_pin <= 13) { | ||
| 136 | + PCICR |= (1 << PCIE0); | ||
| 137 | + PCMSK0 |= (1 << (this->rx_pin - 8)); | ||
| 138 | + IsrPCINT0Hook = this; //setup pinchange interrupt hook | ||
| 139 | + }else if(this->rx_pin <= 19) { | ||
| 140 | + PCICR |= (1 << PCIE1); | ||
| 141 | + PCMSK1 |= (1 << (this->rx_pin - 14)); | ||
| 142 | + IsrPCINT1Hook = this; //setup pinchange interrupt hook | ||
| 143 | + } | ||
| 144 | + } | ||
| 145 | +} |