mirror of
https://github.com/DCC-EX/CommandStation-EX.git
synced 2024-11-27 01:56:14 +01:00
Fix hanging turnouts
Caused by tt->activate call when Turnouts was a struct not a class!
This commit is contained in:
parent
928a9d834a
commit
964f39d376
|
@ -46,30 +46,42 @@ const uint8_t PRESCALE_50HZ = (uint8_t)(((FREQUENCY_OSCILLATOR / (50.0 * 4096.0)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
byte PWMServoDriver::setupFlags=0; // boards that have been initialised
|
byte PWMServoDriver::setupFlags=0; // boards that have been initialised
|
||||||
|
byte PWMServoDriver::failFlags=0; // boards that have faild initialisation
|
||||||
|
|
||||||
|
bool PWMServoDriver::setup(int board) {
|
||||||
|
if (board>3 || (failFlags & (1<<board))) return false;
|
||||||
|
if (setupFlags & (1<<board)) return true;
|
||||||
|
|
||||||
void PWMServoDriver::setup(int board) {
|
|
||||||
if (board>3 || setupFlags & (1<<board)) return;
|
|
||||||
Wire.begin();
|
Wire.begin();
|
||||||
uint8_t i2caddr=PCA9685_I2C_ADDRESS + board;
|
uint8_t i2caddr=PCA9685_I2C_ADDRESS + board;
|
||||||
|
|
||||||
|
// Terst if device is available
|
||||||
|
Wire.beginTransmission(i2caddr);
|
||||||
|
byte error = Wire.endTransmission();
|
||||||
|
if (error!=0) {
|
||||||
|
DIAG(F("\nI2C Servo device 0x%x Not Found %d\n"),i2caddr, error);
|
||||||
|
failFlags|=1<<board;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
//DIAG(F("\nPWMServoDriver::setup %x prescale=%d"),i2caddr,PRESCALE_50HZ);
|
//DIAG(F("\nPWMServoDriver::setup %x prescale=%d"),i2caddr,PRESCALE_50HZ);
|
||||||
writeRegister(i2caddr,PCA9685_MODE1, MODE1_SLEEP | MODE1_AI);
|
writeRegister(i2caddr,PCA9685_MODE1, MODE1_SLEEP | MODE1_AI);
|
||||||
writeRegister(i2caddr,PCA9685_PRESCALE, PRESCALE_50HZ);
|
writeRegister(i2caddr,PCA9685_PRESCALE, PRESCALE_50HZ);
|
||||||
writeRegister(i2caddr,PCA9685_MODE1,MODE1_AI);
|
writeRegister(i2caddr,PCA9685_MODE1,MODE1_AI);
|
||||||
writeRegister(i2caddr,PCA9685_MODE1, MODE1_RESTART | MODE1_AI);
|
writeRegister(i2caddr,PCA9685_MODE1, MODE1_RESTART | MODE1_AI);
|
||||||
setupFlags|=1<<board;
|
setupFlags|=1<<board;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @brief Sets the PWM output to a servo
|
* @brief Sets the PWM output to a servo
|
||||||
*/
|
*/
|
||||||
void PWMServoDriver::setServo(byte servoNum, uint16_t value) {
|
void PWMServoDriver::setServo(byte servoNum, uint16_t value) {
|
||||||
//DIAG(F("\nsetServo %d %d\n"),servoNum,value);
|
DIAG(F("\nsetServo %d %d\n"),servoNum,value);
|
||||||
int board=servoNum/16;
|
int board=servoNum/16;
|
||||||
int pin=servoNum%16;
|
int pin=servoNum%16;
|
||||||
|
|
||||||
if ( board>3) return; // safe dropout
|
if (setup(board)) {
|
||||||
setup(board); // in case not already done
|
|
||||||
|
|
||||||
Wire.beginTransmission(PCA9685_I2C_ADDRESS + board);
|
Wire.beginTransmission(PCA9685_I2C_ADDRESS + board);
|
||||||
Wire.write(PCA9685_FIRST_SERVO + 4 * pin); // 4 registers per pin
|
Wire.write(PCA9685_FIRST_SERVO + 4 * pin); // 4 registers per pin
|
||||||
Wire.write(0);
|
Wire.write(0);
|
||||||
|
@ -78,6 +90,7 @@ void PWMServoDriver::setServo(byte servoNum, uint16_t value) {
|
||||||
Wire.write(value >> 8);
|
Wire.write(value >> 8);
|
||||||
Wire.endTransmission();
|
Wire.endTransmission();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void PWMServoDriver::writeRegister(uint8_t i2caddr,uint8_t hardwareRegister, uint8_t d) {
|
void PWMServoDriver::writeRegister(uint8_t i2caddr,uint8_t hardwareRegister, uint8_t d) {
|
||||||
Wire.beginTransmission(i2caddr);
|
Wire.beginTransmission(i2caddr);
|
||||||
|
|
|
@ -13,7 +13,8 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static byte setupFlags;
|
static byte setupFlags;
|
||||||
static void setup(int board);
|
static byte failFlags;
|
||||||
|
static bool setup(int board);
|
||||||
static void writeRegister(uint8_t i2caddr,uint8_t hardwareRegister, uint8_t d);
|
static void writeRegister(uint8_t i2caddr,uint8_t hardwareRegister, uint8_t d);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include "PWMServoDriver.h"
|
#include "PWMServoDriver.h"
|
||||||
|
|
||||||
bool Turnout::activate(int n,bool state){
|
bool Turnout::activate(int n,bool state){
|
||||||
|
//DIAG(F("\nTurnout::activate(%d,%d)\n"),n,state);
|
||||||
Turnout * tt=get(n);
|
Turnout * tt=get(n);
|
||||||
if (tt==NULL) return false;
|
if (tt==NULL) return false;
|
||||||
tt->activate(state);
|
tt->activate(state);
|
||||||
|
@ -32,9 +33,10 @@
|
||||||
|
|
||||||
// activate is virtual here so that it can be overridden by a non-DCC turnout mechanism
|
// activate is virtual here so that it can be overridden by a non-DCC turnout mechanism
|
||||||
void Turnout::activate(bool state) {
|
void Turnout::activate(bool state) {
|
||||||
|
//DIAG(F("\nTurnout::activate\n"));
|
||||||
if (state) data.tStatus|=STATUS_ACTIVE;
|
if (state) data.tStatus|=STATUS_ACTIVE;
|
||||||
else data.tStatus &= ~STATUS_ACTIVE;
|
else data.tStatus &= ~STATUS_ACTIVE;
|
||||||
if (data.tStatus & STATUS_PWM) PWMServoDriver::setServo(data.tStatus & STATUS_PWMPIN, (data.inactiveAngle+state?data.moveAngle:0));
|
if (data.tStatus & STATUS_PWM) PWMServoDriver::setServo(data.tStatus & STATUS_PWMPIN, (data.inactiveAngle+(state?data.moveAngle:0)));
|
||||||
else DCC::setAccessory(data.address,data.subAddress, state);
|
else DCC::setAccessory(data.address,data.subAddress, state);
|
||||||
}
|
}
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -33,7 +33,8 @@ struct TurnoutData {
|
||||||
union {int address; int inactiveAngle;}; // DCC address or PWM servo angle
|
union {int address; int inactiveAngle;}; // DCC address or PWM servo angle
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Turnout{
|
class Turnout {
|
||||||
|
public:
|
||||||
static Turnout *firstTurnout;
|
static Turnout *firstTurnout;
|
||||||
TurnoutData data;
|
TurnoutData data;
|
||||||
Turnout *nextTurnout;
|
Turnout *nextTurnout;
|
||||||
|
@ -47,7 +48,7 @@ struct Turnout{
|
||||||
static Turnout *create(int id);
|
static Turnout *create(int id);
|
||||||
static void show(Print & stream, int n);
|
static void show(Print & stream, int n);
|
||||||
static bool showAll(Print & stream);
|
static bool showAll(Print & stream);
|
||||||
virtual void activate(bool state);
|
void activate(bool state);
|
||||||
}; // Turnout
|
}; // Turnout
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue
Block a user