From 7241451596ad427642eee4383443a263fa8919fb Mon Sep 17 00:00:00 2001
From: qqqlab <46283638+qqqlab@users.noreply.github.com>
Date: Sat, 14 Nov 2020 04:03:03 +0100
Subject: [PATCH] Delete qqqDali.cpp
---
qqqDali.cpp | 436 ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1 file changed, 0 insertions(+), 436 deletions(-)
delete mode 100644 qqqDali.cpp
diff --git a/qqqDali.cpp b/qqqDali.cpp
deleted file mode 100644
index 1b35ff3..0000000
--- a/qqqDali.cpp
+++ /dev/null
@@ -1,436 +0,0 @@
-/*###########################################################################
- qqqDali.cpp - copyright qqqlab.com / github.com/qqqlab
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
-
-----------------------------------------------------------------------------
-Changelog:
-2020-11-10 Split off hardware specific code into separate class
-2020-11-08 Created & tested on ATMega328 @ 8Mhz
-###########################################################################*/
-#include "qqqDali.h"
-
-//###########################################################################
-// Helpers
-//###########################################################################
-#define DALI_TOL 25 //percentage tolerance on timing. DALI specs call for 10%, but use higher value to allow for implementation micros() jitter. NOTE: Max value is 50% to differentiate between TE and 2TE.
-#define DALI_TE ((1000000+(DALI_BAUD))/(2*(DALI_BAUD))) //417us
-#define DALI_TE_MIN ((100-DALI_TOL)*DALI_TE)/100
-#define DALI_TE_MAX ((100+DALI_TOL)*DALI_TE)/100
-#define DALI_IS_TE(x) ((DALI_TE_MIN)<=(x) && (x)<=(DALI_TE_MAX))
-#define DALI_IS_2TE(x) ((2*(DALI_TE_MIN))<=(x) && (x)<=(2*(DALI_TE_MAX)))
-
-//###########################################################################
-// Transmitter ISR
-//###########################################################################
-//called by derived class every Te period (417us)
-void Dali::ISR_timer() {
- if(this->bus_idle_te_cnt<0xff) this->bus_idle_te_cnt++;
-
- //send starbit, message bytes, 2 stop bits.
- switch(this->tx_state) {
- case TX_IDLE:
- break;
- case TX_START:
- //wait for timeslot, then send start bit
- if(this->bus_idle_te_cnt >= 22) {
- this->HAL_set_bus_low();
- this->tx_bus_low=1;
- this->tx_state = TX_START_X;
- }
- break;
- case TX_START_X:
- this->HAL_set_bus_high();
- this->tx_bus_low=0;
- this->tx_pos=0;
- this->tx_state = TX_BIT;
- break;
- case TX_BIT:
- 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;}
- this->tx_state = TX_BIT_X;
- break;
- case TX_BIT_X:
- 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;}
- this->tx_pos++;
- if(this->tx_pos < this->tx_len) {this->tx_state = TX_BIT;} else {this->tx_state = TX_STOP1;}
- break;
- case TX_STOP1:
- this->HAL_set_bus_high();
- this->tx_bus_low=0;
- this->tx_state = TX_STOP1_X;
- break;
- case TX_STOP1_X:
- this->tx_state = TX_STOP2;
- break;
- case TX_STOP2:
- this->tx_state = TX_STOP2_X;
- break;
- case TX_STOP2_X:
- this->tx_state = TX_STOP3;
- break;
- case TX_STOP3:
- this->bus_idle_te_cnt=0;
- this->tx_state = TX_IDLE;
- this->rx_state = RX_IDLE;
- this->rx_len = 0;
- break;
- }
-
- //handle receiver stop bits
- if(this->rx_state == RX_BIT && this->bus_idle_te_cnt>4) {
- this->rx_state = RX_IDLE;
- //received two stop bits, got message in rx_msg + rx_halfbitlen
- uint8_t bitlen = (this->rx_halfbitlen+1)>>1;
- if((bitlen & 0x7) == 0) {
- this->rx_len = bitlen>>3;
- if(this->EventHandlerReceivedData) this->EventHandlerReceivedData(this, (uint8_t*)this->rx_msg, this->rx_len);
- }else{
- //invalid bitlen
- //TODO handle this
- }
- }
-}
-
-//###########################################################################
-// Receiver ISR
-//###########################################################################
-//called by derived class on bus state change
-void Dali::ISR_pinchange() {
- uint32_t ts = this->HAL_micros(); //get timestamp of change
- this->bus_idle_te_cnt=0; //reset idle counter
- uint8_t bus_low = this->HAL_is_bus_low();
-
- //exit if transmitting
- if(this->tx_state != TX_IDLE) {
- //check tx collision
- if(bus_low && !this->tx_bus_low) {
- this->tx_state = TX_IDLE; //stop transmitter
- this->tx_collision = 1; //mark collision
- }
- return;
- }
-
- //no bus change, ignore
- if(bus_low == this->rx_last_bus_low) return;
-
- //store values for next loop
- uint32_t dt = ts - this->rx_last_change_ts;
- this->rx_last_change_ts = ts;
- this->rx_last_bus_low = bus_low;
-
- switch(this->rx_state) {
- case RX_IDLE:
- if(bus_low) {
- this->rx_state = RX_START;
- }
- break;
- case RX_START:
- if(bus_low || !DALI_IS_TE(dt)) {
- this->rx_state = RX_IDLE;
- }else{
- this->rx_halfbitlen=-1;
- for(uint8_t i=0;i<7;i++) this->rx_msg[0]=0;
- this->rx_state = RX_BIT;
- }
- break;
- case RX_BIT:
- if(DALI_IS_TE(dt)) {
- //got a single Te pulse
- this->push_halfbit(bus_low);
- } else if(DALI_IS_2TE(dt)) {
- //got a double Te pulse
- this->push_halfbit(bus_low);
- this->push_halfbit(bus_low);
- } else {
- //got something else -> no good
- this->rx_state = RX_IDLE;
- //TODO rx error
- return;
- }
- break;
- }
-}
-
-void Dali::push_halfbit(uint8_t bit) {
- bit = (~bit)&1;
- if((this->rx_halfbitlen & 1)==0) {
- uint8_t i = this->rx_halfbitlen>>4;
- if(i<3) {
- this->rx_msg[i] = (this->rx_msg[i]<<1) | bit;
- }
- }
- this->rx_halfbitlen++;
-}
-
-
-//###########################################################################
-// Dali Class
-//###########################################################################
-
-//non blocking send - check tx_state for completion, check tx_collision for collision errors
-uint8_t Dali::send(uint8_t* tx_msg, uint8_t tx_len_bytes) {
- if(tx_len_bytes>3) return -(DALI_RESULT_DATA_TOO_LONG);
- if(this->tx_state != TX_IDLE) return -(DALI_RESULT_TIMEOUT);
- for(uint8_t i=0;itx_msg[i]=tx_msg[i];
- this->tx_len = tx_len_bytes<<3;
- this->tx_collision=0;
- this->tx_state = TX_START; //start transmission
- return 0;
-}
-
-//blocking send - wait until successful send or timeout
-uint8_t Dali::sendwait(uint8_t* tx_msg, uint8_t tx_len_bytes, uint32_t timeout_us) {
- if(tx_len_bytes>3) return -(DALI_RESULT_DATA_TOO_LONG);
- uint32_t ts = HAL_micros();
-
- while(1) {
- //wait for idle
- while(this->tx_state != TX_IDLE) {
- if(HAL_micros() - ts > timeout_us) return -(DALI_RESULT_TIMEOUT);
- }
- //start transmit
- uint8_t rv = this->send(tx_msg,tx_len_bytes);
- if(rv) return rv;
- //wait for completion
- while(this->tx_state != TX_IDLE) {
- if(HAL_micros() - ts > timeout_us) return -(DALI_RESULT_TX_TIMEOUT);
- }
- //check for collisions
- if(this->tx_collision==0) return 0;
- }
- return -(DALI_RESULT_TIMEOUT);
-}
-
-//blocking transmit 2 byte command, receive 1 byte reply (if reply was sent)
-int16_t Dali::tx(uint8_t cmd0, uint8_t cmd1, uint32_t timeout_us) {
- uint8_t tx[2];
- tx[0] = cmd0;
- tx[1] = cmd1;
- int16_t rv = this->sendwait(tx, 2, timeout_us);
- this->rx_halfbitlen = 0;
- if(rv) return -rv;;
-
- //wait up to 10 ms for start of reply
- uint32_t ts = HAL_micros();
- while(this->rx_state == RX_IDLE) {
- if(HAL_micros() - ts > 10000) return DALI_RESULT_NO_REPLY;
- }
- //wait up to 15 ms for completion of reply
- ts = HAL_micros();
- while(this->rx_len == 0) {
- if(HAL_micros() - ts > 15000) return DALI_RESULT_NO_REPLY;
- }
- if(this->rx_len > 1) return DALI_RESULT_INVALID_REPLY;
- return this->rx_msg[0];
-}
-
-//=================================================================
-// High level
-//=================================================================
-//check YAAAAAA: 0000 0000 to 0011 1111 adr, 0100 0000 to 0100 1111 group, x111 1111 broadcast
-uint8_t Dali::check_yaaaaaa(uint8_t yaaaaaa) {
- return (yaaaaaa<=0b01001111 || yaaaaaa==0b01111111 || yaaaaaa==0b11111111);
-}
-
-void Dali::set_level(uint8_t level, uint8_t adr) {
- if(this->check_yaaaaaa(adr)) this->tx(adr<<1,level);
-}
-
-int16_t Dali::cmd(uint16_t cmd, uint8_t arg) {
- //Serial.print("dali_cmd[");Serial.print(cmd,HEX);Serial.print(",");Serial.print(arg,HEX);Serial.print(")");
- uint8_t cmd0,cmd1;
- if(cmd&0x0100) {
- //special commands: MUST NOT have YAAAAAAX pattern for cmd
- //Serial.print(" SPC");
- if(!this->check_yaaaaaa(cmd>>1)) {
- cmd0 = cmd;
- cmd1 = arg;
- }else{
- return DALI_RESULT_INVALID_CMD;
- }
- }else{
- //regular commands: MUST have YAAAAAA pattern for arg
-
- //Serial.print(" REG");
- if(this->check_yaaaaaa(arg)) {
- cmd0 = arg<<1|1;
- cmd1 = cmd;
- }else{
- return DALI_RESULT_INVALID_CMD;
- }
- }
- if(cmd&0x0200) {
- //Serial.print(" REPEAT");
- this->tx(cmd0, cmd1);
- }
- int16_t rv = this->tx(cmd0, cmd1);
- //Serial.print(" rv=");Serial.println(rv);
- return rv;
-}
-
-
-uint8_t Dali::set_operating_mode(uint8_t v, uint8_t adr) {
- return set_value(DALI_SET_OPERATING_MODE, DALI_QUERY_OPERATING_MODE, v, adr);
-}
-
-uint8_t Dali::set_max_level(uint8_t v, uint8_t adr) {
- return set_value(DALI_SET_MAX_LEVEL, DALI_QUERY_MAX_LEVEL, v, adr);
-}
-
-uint8_t Dali::set_min_level(uint8_t v, uint8_t adr) {
- return set_value(DALI_SET_MIN_LEVEL, DALI_QUERY_MIN_LEVEL, v, adr);
-}
-
-
-uint8_t Dali::set_system_failure_level(uint8_t v, uint8_t adr) {
- return set_value(DALI_SET_SYSTEM_FAILURE_LEVEL, DALI_QUERY_SYSTEM_FAILURE_LEVEL, v, adr);
-}
-
-uint8_t Dali::set_power_on_level(uint8_t v, uint8_t adr) {
- return set_value(DALI_SET_POWER_ON_LEVEL, DALI_QUERY_POWER_ON_LEVEL, v, adr);
-}
-
-//set a parameter value, returns 0 on success
-uint8_t Dali::set_value(uint16_t setcmd, uint16_t getcmd, uint8_t v, uint8_t adr) {
- int16_t current_v = this->cmd(getcmd,adr); //get current parameter value
- if(current_v == v) return 0;
- this->cmd(DALI_DATA_TRANSFER_REGISTER0,v); //store value in DTR
- int16_t dtr = this->cmd(DALI_QUERY_CONTENT_DTR0,adr); //get DTR value
- if(dtr != v) return 1;
- this->cmd(setcmd,adr); //set parameter value = DTR
- current_v = this->cmd(getcmd,adr); //get current parameter value
- if(current_v != v) return 2;
- return 0;
-}
-
-
-//======================================================================
-// Commissioning short addresses
-//======================================================================
-
-//Sets the slave Note 1 to the INITIALISE status for15 minutes.
-//Commands 259 to 270 are enabled only for a slave in this
-//status.
-
-//set search address
-void Dali::set_searchaddr(uint32_t adr) {
- this->cmd(DALI_SEARCHADDRH,adr>>16);
- this->cmd(DALI_SEARCHADDRM,adr>>8);
- this->cmd(DALI_SEARCHADDRL,adr);
-}
-
-//set search address, but set only changed bytes (takes less time)
-void Dali::set_searchaddr_diff(uint32_t adr_new,uint32_t adr_current) {
- if( (uint8_t)(adr_new>>16) != (uint8_t)(adr_current>>16) ) this->cmd(DALI_SEARCHADDRH,adr_new>>16);
- if( (uint8_t)(adr_new>>8) != (uint8_t)(adr_current>>8) ) this->cmd(DALI_SEARCHADDRM,adr_new>>8);
- if( (uint8_t)(adr_new) != (uint8_t)(adr_current) ) this->cmd(DALI_SEARCHADDRL,adr_new);
-}
-
-//Is the random address smaller or equal to the search address?
-uint8_t Dali::compare() {
- return (0xff == this->cmd(DALI_COMPARE,0x00));
-}
-
-//The slave shall store the received 6-bit address (AAAAAA) as a short address if it is selected.
-void Dali::program_short_address(uint8_t shortadr) {
- this->cmd(DALI_PROGRAM_SHORT_ADDRESS, (shortadr << 1) | 0x01);
-}
-
-//What is the short address of the slave being selected?
-uint8_t Dali::query_short_address() {
- return this->cmd(DALI_QUERY_SHORT_ADDRESS, 0x00) >> 1;
-}
-
-//find addr with binary search
-uint32_t Dali::find_addr() {
- uint32_t adr = 0x800000;
- uint32_t addsub = 0x400000;
- uint32_t adr_last = adr;
- this->set_searchaddr(adr);
-
- while(addsub) {
- this->set_searchaddr_diff(adr,adr_last);
- adr_last = adr;
- uint8_t cmp = this->compare();
- //Serial.print("cmp ");
- //Serial.print(adr,HEX);
- //Serial.print(" = ");
- //Serial.println(cmp);
- if(cmp) adr-=addsub; else adr+=addsub;
- addsub >>= 1;
- }
- this->set_searchaddr_diff(adr,adr_last);
- adr_last = adr;
- if(!this->compare()) {
- adr++;
- this->set_searchaddr_diff(adr,adr_last);
- }
- return adr;
-}
-
-//init_arg=11111111 : all without short address
-//init_arg=00000000 : all
-//init_arg=0AAAAAA1 : only for this shortadr
-//returns number of new short addresses assigned
-uint8_t Dali::commission(uint8_t init_arg) {
- uint8_t cnt = 0;
- uint8_t arr[64];
- uint8_t sa;
- for(sa=0; sa<64; sa++) arr[sa]=0;
-
- //start commissioning
- this->cmd(DALI_RESET,0x00);
- this->cmd(DALI_INITIALISE,init_arg);
- this->cmd(DALI_RANDOMISE,0x00);
-
- //find used short addresses (run always, seems to work better than without...)
- for(sa = 0; sa<64; sa++) {
- int16_t rv = this->cmd(DALI_QUERY_STATUS,sa);
- if(rv!=DALI_RESULT_NO_REPLY) {
- if(init_arg!=0b00000000) arr[sa]=1; //remove address from list if not in "all" mode
- }
- }
-
- //find random addresses and assign unused short addresses
- while(1) {
- uint32_t adr = this->find_addr();
- if(adr>0xffffff) break; //no more random addresses found -> exit
-
- //find first unused short address
- for(sa=0; sa<64; sa++) {
- if(arr[sa]==0) break;
- }
- if(sa>=64) break; //all 64 short addresses assigned -> exit
-
- //mark short address as used
- arr[sa] = 1;
- cnt++;
-
- //assign short address
- this->program_short_address(sa);
-
- //Serial.println(this->query_short_address()); //TODO check read adr, handle if not the same...
-
- //remove the device from the search
- this->cmd(DALI_WITHDRAW,0x00);
- }
-
- //terminate the DALI_INITIALISE command
- this->cmd(DALI_TERMINATE,0x00);
- return cnt;
-}
-
-
-
-//======================================================================
--
libgit2 0.21.4