mirror of
https://github.com/DCC-EX/CommandStation-EX.git
synced 2024-11-23 08:06:13 +01:00
9dacd24d27
* Add <D SERVO vpin position> command Allow a PWM servo to be driven to any arbitrary position. * Enhancements for HAL drivers Add state change notification for external GPIO module drivers; Allow drivers to be installed statically by declaration (as an alternative to the 'create' call). * Create IO_HCSR04.h HAL driver for HC-SR04 ultrasonic distance sensor (sonar). * Enable servo commands in NO-HAL mode, but return error. Avoid compile errors in RMFT.cpp when compiled with basic HAL by including the Turnout::createServo function as a stub that returns NULL. * Update IO_HCSR04.h Minor changes * Change <D SERVO> Give the <D SERVO> command an optional parameter of the profile. For example, <D SERVO 100 200 3> will slowly move the servo on pin 100 to PWM position corresponding to 200. If omitted, the servo will move immediately (no animation). * IODevice (HAL) changes 1) Put new devices on the end of the chain instead of the beginning. This will give better performance for devices created first (ArduinoPins and extender GPIO devices, typically). 2) Remove unused functions. * Update IO_HCSR04.h Allow thresholds for ON and OFF to be separately configured at creation. * Update IODevice.cpp Fix compile error on IO_NO_HAL minimal HAL version. * Update IO_PCA9685.cpp Remove unnecessary duplicated call to min() function.
69 lines
2.8 KiB
C++
69 lines
2.8 KiB
C++
/*
|
|
* © 2021, Neil McKechnie. All rights reserved.
|
|
*
|
|
* This file is part of DCC++EX API
|
|
*
|
|
* This 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.
|
|
*
|
|
* It 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 CommandStation. If not, see <https://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "DCC.h"
|
|
#include "IODevice.h"
|
|
#include "DIAG.h"
|
|
|
|
// Note: For DCC Accessory Decoders, a particular output can be specified by
|
|
// a linear address, or by an address/subaddress pair, where the subaddress is
|
|
// in the range 0 to 3 and specifies an output within a group of 4.
|
|
// NMRA and DCC++EX accepts addresses in the range 0-511. Linear addresses
|
|
// are not specified by the NMRA and so different manufacturers may calculate them
|
|
// in different ways. DCC+EX uses a range of 1-2044 which excludes decoder address 0.
|
|
// Therefore, I've avoided using linear addresses here because of the ambiguities
|
|
// involved. Instead I've used the term 'packedAddress'.
|
|
|
|
void DCCAccessoryDecoder::create(VPIN vpin, int nPins, int DCCAddress, int DCCSubaddress) {
|
|
new DCCAccessoryDecoder(vpin, nPins, DCCAddress, DCCSubaddress);
|
|
}
|
|
|
|
// Constructor
|
|
DCCAccessoryDecoder::DCCAccessoryDecoder(VPIN vpin, int nPins, int DCCAddress, int DCCSubaddress) {
|
|
_firstVpin = vpin;
|
|
_nPins = nPins;
|
|
_packedAddress = (DCCAddress << 2) + DCCSubaddress;
|
|
}
|
|
|
|
void DCCAccessoryDecoder::_begin() {
|
|
int endAddress = _packedAddress + _nPins - 1;
|
|
int DCCAddress = _packedAddress >> 2;
|
|
int DCCSubaddress = _packedAddress & 3;
|
|
DIAG(F("DCC Accessory Decoder configured Vpins:%d-%d Linear Address:%d-%d (%d/%d-%d/%d)"), _firstVpin, _firstVpin+_nPins-1,
|
|
_packedAddress, _packedAddress+_nPins-1,
|
|
DCCAddress, DCCSubaddress, endAddress >> 2, endAddress % 4);
|
|
}
|
|
|
|
// Device-specific write function.
|
|
void DCCAccessoryDecoder::_write(VPIN id, int state) {
|
|
int packedAddress = _packedAddress + id - _firstVpin;
|
|
#ifdef DIAG_IO
|
|
DIAG(F("DCC Write Linear Address:%d State:%d"), packedAddress, state);
|
|
#endif
|
|
DCC::setAccessory(packedAddress >> 2, packedAddress % 4, state);
|
|
}
|
|
|
|
void DCCAccessoryDecoder::_display() {
|
|
int endAddress = _packedAddress + _nPins - 1;
|
|
DIAG(F("DCC Accessory Vpins:%d-%d Linear Address:%d-%d (%d/%d-%d/%d)"), _firstVpin, _firstVpin+_nPins-1,
|
|
_packedAddress, _packedAddress+_nPins-1,
|
|
_packedAddress >> 2, _packedAddress % 4, endAddress >> 2, endAddress % 4);
|
|
}
|
|
|