mirror of
https://github.com/DCC-EX/CommandStation-EX.git
synced 2025-04-21 12:31:19 +02:00
Compare commits
1 Commits
332dbf2861
...
e2fc57422d
Author | SHA1 | Date | |
---|---|---|---|
|
e2fc57422d |
45
DCC.cpp
45
DCC.cpp
@ -38,7 +38,6 @@
|
|||||||
#include "TrackManager.h"
|
#include "TrackManager.h"
|
||||||
#include "DCCTimer.h"
|
#include "DCCTimer.h"
|
||||||
#include "Railcom.h"
|
#include "Railcom.h"
|
||||||
#include "DCCQueue.h"
|
|
||||||
|
|
||||||
// This module is responsible for converting API calls into
|
// This module is responsible for converting API calls into
|
||||||
// messages to be sent to the waveform generator.
|
// messages to be sent to the waveform generator.
|
||||||
@ -158,8 +157,8 @@ void DCC::setThrottle2( uint16_t cab, byte speedCode) {
|
|||||||
b[nB++] = speedCode; // for encoding see setThrottle
|
b[nB++] = speedCode; // for encoding see setThrottle
|
||||||
|
|
||||||
}
|
}
|
||||||
if ((speedCode & 0x7F) == 1) DCCQueue::scheduleEstopPacket(b, nB, 4, cab); // highest priority
|
|
||||||
else DCCQueue::scheduleDCCSpeedPacket( b, nB, 4, cab);
|
DCCWaveform::mainTrack.schedulePacket(b, nB, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DCC::setFunctionInternal(int cab, byte byte1, byte byte2, byte count) {
|
void DCC::setFunctionInternal(int cab, byte byte1, byte byte2, byte count) {
|
||||||
@ -173,7 +172,7 @@ void DCC::setFunctionInternal(int cab, byte byte1, byte byte2, byte count) {
|
|||||||
if (byte1!=0) b[nB++] = byte1;
|
if (byte1!=0) b[nB++] = byte1;
|
||||||
b[nB++] = byte2;
|
b[nB++] = byte2;
|
||||||
|
|
||||||
DCCQueue::scheduleDCCPacket(b, nB, count);
|
DCCWaveform::mainTrack.schedulePacket(b, nB, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
// returns speed steps 0 to 127 (1 == emergency stop)
|
// returns speed steps 0 to 127 (1 == emergency stop)
|
||||||
@ -239,7 +238,7 @@ bool DCC::setFn( int cab, int16_t functionNumber, bool on) {
|
|||||||
b[nB++] = (functionNumber & 0x7F) | (on ? 0x80 : 0); // low order bits and state flag
|
b[nB++] = (functionNumber & 0x7F) | (on ? 0x80 : 0); // low order bits and state flag
|
||||||
b[nB++] = functionNumber >>7 ; // high order bits
|
b[nB++] = functionNumber >>7 ; // high order bits
|
||||||
}
|
}
|
||||||
DCCQueue::scheduleDCCPacket(b, nB, 4);
|
DCCWaveform::mainTrack.schedulePacket(b, nB, 4);
|
||||||
}
|
}
|
||||||
// We use the reminder table up to 28 for normal functions.
|
// We use the reminder table up to 28 for normal functions.
|
||||||
// We use 29 to 31 for DC frequency as well so up to 28
|
// We use 29 to 31 for DC frequency as well so up to 28
|
||||||
@ -340,17 +339,16 @@ void DCC::setAccessory(int address, byte port, bool gate, byte onoff /*= 2*/) {
|
|||||||
// second byte is of the form 1AAACPPG, where C is 1 for on, PP the ports 0 to 3 and G the gate (coil).
|
// second byte is of the form 1AAACPPG, where C is 1 for on, PP the ports 0 to 3 and G the gate (coil).
|
||||||
b[0] = address % 64 + 128;
|
b[0] = address % 64 + 128;
|
||||||
b[1] = ((((address / 64) % 8) << 4) + (port % 4 << 1) + gate % 2) ^ 0xF8;
|
b[1] = ((((address / 64) % 8) << 4) + (port % 4 << 1) + gate % 2) ^ 0xF8;
|
||||||
if (onoff==0) { // off packet only
|
if (onoff != 0) {
|
||||||
b[1] &= ~0x08; // set C to 0
|
DCCWaveform::mainTrack.schedulePacket(b, 2, 3); // Repeat on packet three times
|
||||||
DCCQueue::scheduleDCCPacket(b, 2, 3);
|
|
||||||
} else if (onoff==1) { // on packet only
|
|
||||||
DCCQueue::scheduleDCCPacket(b, 2, 3);
|
|
||||||
} else { // auto timed on then off
|
|
||||||
DCCQueue::scheduleAccOnOffPacket(b, 2, 3, 100); // On then off after 100mS
|
|
||||||
}
|
|
||||||
#if defined(EXRAIL_ACTIVE)
|
#if defined(EXRAIL_ACTIVE)
|
||||||
if (onoff !=0) RMFT2::activateEvent(address<<2|port,gate);
|
RMFT2::activateEvent(address<<2|port,gate);
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
if (onoff != 1) {
|
||||||
|
b[1] &= ~0x08; // set C to 0
|
||||||
|
DCCWaveform::mainTrack.schedulePacket(b, 2, 3); // Repeat off packet three times
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DCC::setExtendedAccessory(int16_t address, int16_t value, byte repeats) {
|
bool DCC::setExtendedAccessory(int16_t address, int16_t value, byte repeats) {
|
||||||
@ -400,7 +398,7 @@ whole range of the 11 bits sent to track.
|
|||||||
| (((~(address>>8)) & 0x07)<<4) // shift out 8, invert, mask 3 bits, shift up 4
|
| (((~(address>>8)) & 0x07)<<4) // shift out 8, invert, mask 3 bits, shift up 4
|
||||||
| ((address & 0x03)<<1); // mask 2 bits, shift up 1
|
| ((address & 0x03)<<1); // mask 2 bits, shift up 1
|
||||||
b[2]=value;
|
b[2]=value;
|
||||||
DCCQueue::scheduleDCCPacket(b, sizeof(b), repeats);
|
DCCWaveform::mainTrack.schedulePacket(b, sizeof(b), repeats);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -419,7 +417,7 @@ void DCC::writeCVByteMain(int cab, int cv, byte bValue) {
|
|||||||
b[nB++] = cv2(cv);
|
b[nB++] = cv2(cv);
|
||||||
b[nB++] = bValue;
|
b[nB++] = bValue;
|
||||||
|
|
||||||
DCCQueue::scheduleDCCPacket(b, nB, 4);
|
DCCWaveform::mainTrack.schedulePacket(b, nB, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -437,7 +435,7 @@ void DCC::readCVByteMain(int cab, int cv, ACK_CALLBACK callback) {
|
|||||||
b[nB++] = cv2(cv);
|
b[nB++] = cv2(cv);
|
||||||
b[nB++] = 0;
|
b[nB++] = 0;
|
||||||
|
|
||||||
DCCQueue::scheduleDCCPacket(b, nB, 4);
|
DCCWaveform::mainTrack.schedulePacket(b, nB, 4);
|
||||||
Railcom::anticipate(cab,cv,callback);
|
Railcom::anticipate(cab,cv,callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -459,7 +457,7 @@ void DCC::writeCVBitMain(int cab, int cv, byte bNum, bool bValue) {
|
|||||||
b[nB++] = cv2(cv);
|
b[nB++] = cv2(cv);
|
||||||
b[nB++] = WRITE_BIT | (bValue ? BIT_ON : BIT_OFF) | bNum;
|
b[nB++] = WRITE_BIT | (bValue ? BIT_ON : BIT_OFF) | bNum;
|
||||||
|
|
||||||
DCCQueue::scheduleDCCPacket(b, nB, 4);
|
DCCWaveform::mainTrack.schedulePacket(b, nB, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DCC::setTime(uint16_t minutes,uint8_t speed, bool suddenChange) {
|
bool DCC::setTime(uint16_t minutes,uint8_t speed, bool suddenChange) {
|
||||||
@ -496,7 +494,7 @@ b[1]=0b11000001; // 1100-0001 (model time)
|
|||||||
b[2]=minutes % 60 ; // MM
|
b[2]=minutes % 60 ; // MM
|
||||||
b[3]= 0b11100000 | (minutes/60); // 111H-HHHH weekday not supported
|
b[3]= 0b11100000 | (minutes/60); // 111H-HHHH weekday not supported
|
||||||
b[4]= (suddenChange ? 0b10000000 : 0) | speed;
|
b[4]= (suddenChange ? 0b10000000 : 0) | speed;
|
||||||
DCCQueue::scheduleDCCPacket(b, sizeof(b), 2);
|
DCCWaveform::mainTrack.schedulePacket(b, sizeof(b), 2);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -846,17 +844,12 @@ byte DCC::loopStatus=0;
|
|||||||
|
|
||||||
void DCC::loop() {
|
void DCC::loop() {
|
||||||
TrackManager::loop(); // power overload checks
|
TrackManager::loop(); // power overload checks
|
||||||
if (DCCWaveform::mainTrack.isReminderWindowOpen()) {
|
|
||||||
// Now is a good time to choose a packet to be sent
|
|
||||||
// Either highest priority from the queues or a reminder
|
|
||||||
if (!DCCQueue::scheduleNext()) {
|
|
||||||
issueReminders();
|
issueReminders();
|
||||||
DCCQueue::scheduleNext(); // push through any just created reminder
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DCC::issueReminders() {
|
void DCC::issueReminders() {
|
||||||
|
// if the main track transmitter still has a pending packet, skip this time around.
|
||||||
|
if (!DCCWaveform::mainTrack.isReminderWindowOpen()) return;
|
||||||
// Move to next loco slot. If occupied, send a reminder.
|
// Move to next loco slot. If occupied, send a reminder.
|
||||||
auto slot = nextLocoReminder;
|
auto slot = nextLocoReminder;
|
||||||
if (slot >= &speedTable[MAX_LOCOS]) slot=&speedTable[0]; // Go to start of table
|
if (slot >= &speedTable[MAX_LOCOS]) slot=&speedTable[0]; // Go to start of table
|
||||||
|
185
DCCQueue.cpp
185
DCCQueue.cpp
@ -1,185 +0,0 @@
|
|||||||
/*
|
|
||||||
* © 2025 Chris Harlow
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* This file is part of CommandStation-EX
|
|
||||||
*
|
|
||||||
* 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 "Arduino.h"
|
|
||||||
#include "defines.h"
|
|
||||||
#include "DCCQueue.h"
|
|
||||||
#include "DCCWaveform.h"
|
|
||||||
#include "DIAG.h"
|
|
||||||
|
|
||||||
// create statics
|
|
||||||
DCCQueue* DCCQueue::lowPriorityQueue=new DCCQueue();
|
|
||||||
DCCQueue* DCCQueue::highPriorityQueue=new DCCQueue();
|
|
||||||
PendingSlot* DCCQueue::recycleList=nullptr;
|
|
||||||
|
|
||||||
DCCQueue::DCCQueue() {
|
|
||||||
head=nullptr;
|
|
||||||
tail=nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DCCQueue::addQueue(PendingSlot* p) {
|
|
||||||
if (tail) tail->next=p;
|
|
||||||
else head=p;
|
|
||||||
tail=p;
|
|
||||||
p->next=nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DCCQueue::jumpQueue(PendingSlot* p) {
|
|
||||||
p->next=head;
|
|
||||||
head=p;
|
|
||||||
if (!tail) tail=p;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void DCCQueue::recycle(PendingSlot* p) {
|
|
||||||
p->next=recycleList;
|
|
||||||
recycleList=p;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Packet joins end of low priority queue.
|
|
||||||
void DCCQueue::scheduleDCCPacket(byte* packet, byte length, byte repeats) {
|
|
||||||
lowPriorityQueue->addQueue(getSlot(NORMAL_PACKET,packet,length,repeats,0));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Packet replaces existing loco speed packet or joins end of high priority queue.
|
|
||||||
|
|
||||||
void DCCQueue::scheduleDCCSpeedPacket(byte* packet, byte length, byte repeats, uint16_t loco) {
|
|
||||||
for (auto p=highPriorityQueue->head;p;p=p->next) {
|
|
||||||
if (p->locoId==loco) {
|
|
||||||
// replace existing packet
|
|
||||||
memcpy(p->packet,packet,length);
|
|
||||||
p->packetLength=length;
|
|
||||||
p->packetRepeat=repeats;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
highPriorityQueue->addQueue(getSlot(NORMAL_PACKET,packet,length,repeats,loco));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ESTOP -
|
|
||||||
// any outstanding throttle packet for this loco (all if loco=0) discarded
|
|
||||||
// Packet joins start of queue,
|
|
||||||
|
|
||||||
|
|
||||||
void DCCQueue::scheduleEstopPacket(byte* packet, byte length, byte repeats,uint16_t loco) {
|
|
||||||
|
|
||||||
// DIAG(F("DCC ESTOP loco=%d"),loco);
|
|
||||||
|
|
||||||
// kill any existing throttle packets for this loco
|
|
||||||
PendingSlot * previous=nullptr;
|
|
||||||
auto p=highPriorityQueue->head;
|
|
||||||
while(p) {
|
|
||||||
if (loco==0 || p->locoId==loco) {
|
|
||||||
// drop this packet from the highPriority queue
|
|
||||||
if (previous) previous->next=p->next;
|
|
||||||
else highPriorityQueue->head=p->next;
|
|
||||||
|
|
||||||
recycle(p); // recycle this slot
|
|
||||||
|
|
||||||
// address next packet
|
|
||||||
p=previous?previous->next : highPriorityQueue->head;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
previous=p;
|
|
||||||
p=p->next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// add the estop packet to the start of the queue
|
|
||||||
highPriorityQueue->jumpQueue(getSlot(NORMAL_PACKET,packet,length,repeats,0));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Accessory gate-On Packet joins end of queue as normal.
|
|
||||||
// When dequeued, packet is retained at start of queue
|
|
||||||
// but modified to gate-off and given the delayed start.
|
|
||||||
// getNext will ignore this packet until the requested start time.
|
|
||||||
void DCCQueue::scheduleAccOnOffPacket(byte* packet, byte length, byte repeats,int16_t delayms) {
|
|
||||||
auto p=getSlot(ACC_ON_PACKET,packet,length,repeats,0);
|
|
||||||
p->delayOff=delayms;
|
|
||||||
lowPriorityQueue->addQueue(p);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// Obtain packet (fills packet, length and repeats)
|
|
||||||
// returns 0 length if nothing in queue.
|
|
||||||
|
|
||||||
bool DCCQueue::scheduleNext() {
|
|
||||||
// check high priority queue first
|
|
||||||
if (!DCCWaveform::mainTrack.isReminderWindowOpen()) return false;
|
|
||||||
PendingSlot* previous=nullptr;
|
|
||||||
for (auto p=highPriorityQueue->head;p;p=p->next) {
|
|
||||||
// skip over pending ACC_OFF packets which are still delayed
|
|
||||||
if (p->type == ACC_OFF_PACKET && millis()<p->startTime) continue;
|
|
||||||
// use this slot
|
|
||||||
DCCWaveform::mainTrack.schedulePacket(p->packet,p->packetLength,p->packetRepeat);
|
|
||||||
// remove this slot from the queue
|
|
||||||
if (previous) previous->next=p->next;
|
|
||||||
else highPriorityQueue->head=p->next;
|
|
||||||
if (!highPriorityQueue->head) highPriorityQueue->tail=nullptr;
|
|
||||||
|
|
||||||
// and recycle it.
|
|
||||||
recycle(p);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// No high priopity packets found, check low priority queue
|
|
||||||
auto p=lowPriorityQueue->head;
|
|
||||||
if (!p) return false; // nothing in queues
|
|
||||||
|
|
||||||
// schedule first packet in queue
|
|
||||||
DCCWaveform::mainTrack.schedulePacket(p->packet,p->packetLength,p->packetRepeat);
|
|
||||||
|
|
||||||
// remove from queue
|
|
||||||
lowPriorityQueue->head=p->next;
|
|
||||||
if (!lowPriorityQueue->head) lowPriorityQueue->tail=nullptr;
|
|
||||||
|
|
||||||
if (p->type == ACC_ON_PACKET) {
|
|
||||||
// convert to a delayed off packet and jump the high priority queue
|
|
||||||
p->type= ACC_OFF_PACKET;
|
|
||||||
p->packet[1] &= ~0x08; // set C to 0 (gate off)
|
|
||||||
p->startTime=millis()+p->delayOff;
|
|
||||||
highPriorityQueue->jumpQueue(p);
|
|
||||||
}
|
|
||||||
else recycle(p); // recycle this slot
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// obtain and initialise slot for a PendingSlot.
|
|
||||||
PendingSlot* DCCQueue::getSlot(PendingType type, byte* packet, byte length, byte repeats,uint16_t loco) {
|
|
||||||
PendingSlot * p;
|
|
||||||
if (recycleList) {
|
|
||||||
p=recycleList;
|
|
||||||
recycleList=p->next;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
DIAG(F("New DCC queue slot"));
|
|
||||||
p=new PendingSlot; // need a queue entry
|
|
||||||
}
|
|
||||||
p->next=nullptr;
|
|
||||||
p->type=type;
|
|
||||||
p->packetLength=length;
|
|
||||||
p->packetRepeat=repeats;
|
|
||||||
memcpy((void*)p->packet,packet,length);
|
|
||||||
p->locoId=loco;
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
84
DCCQueue.h
84
DCCQueue.h
@ -1,84 +0,0 @@
|
|||||||
/*
|
|
||||||
* © 2025 Chris Harlow
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* This file is part of CommandStation-EX
|
|
||||||
*
|
|
||||||
* 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/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef DCCQueue_h
|
|
||||||
#define DCCQueue_h
|
|
||||||
#include "Arduino.h"
|
|
||||||
#include "DCCWaveform.h"
|
|
||||||
|
|
||||||
enum PendingType:byte {NORMAL_PACKET,ACC_ON_PACKET,ACC_OFF_PACKET,DEAD_PACKET};
|
|
||||||
struct PendingSlot {
|
|
||||||
PendingSlot* next;
|
|
||||||
PendingType type;
|
|
||||||
byte packetLength;
|
|
||||||
byte packetRepeat;
|
|
||||||
byte packet[MAX_PACKET_SIZE];
|
|
||||||
|
|
||||||
union { // use depends on packet type
|
|
||||||
uint16_t locoId; // NORMAL_PACKET .. only set >0 for speed change packets
|
|
||||||
// so they can be easily discarded if an estop jumps the queue.
|
|
||||||
uint16_t delayOff; // ACC_ON_PACKET delay to apply between on/off
|
|
||||||
uint32_t startTime; // ACC_OFF_PACKET time (mS) to transmit
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
class DCCQueue {
|
|
||||||
public:
|
|
||||||
|
|
||||||
|
|
||||||
// Non-speed packets are queued in the main queue
|
|
||||||
static void scheduleDCCPacket(byte* packet, byte length, byte repeats);
|
|
||||||
|
|
||||||
// Speed packets are queued in the high priority queue
|
|
||||||
static void scheduleDCCSpeedPacket(byte* packet, byte length, byte repeats, uint16_t loco);
|
|
||||||
|
|
||||||
// ESTOP packets jump the high priority queue and discard any outstanding throttle packets for this loco
|
|
||||||
static void scheduleEstopPacket(byte* packet, byte length, byte repeats,uint16_t loco);
|
|
||||||
|
|
||||||
// Accessory gate-On Packet joins end of main queue as normal.
|
|
||||||
// When dequeued, packet is modified to gate-off and given the delayed start in the high priority queue.
|
|
||||||
// getNext will ignore this packet until the requested start time.
|
|
||||||
static void scheduleAccOnOffPacket(byte* packet, byte length, byte repeats,int16_t delayms);
|
|
||||||
|
|
||||||
|
|
||||||
// Schedules a main track packet from the queues if none pending.
|
|
||||||
// returns true if a packet was scheduled.
|
|
||||||
static bool scheduleNext();
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
// statics to manage high and low priority queues and recycleing of PENDINGs
|
|
||||||
static PendingSlot* recycleList;
|
|
||||||
static DCCQueue* highPriorityQueue;
|
|
||||||
static DCCQueue* lowPriorityQueue;
|
|
||||||
|
|
||||||
DCCQueue();
|
|
||||||
|
|
||||||
PendingSlot* head;
|
|
||||||
PendingSlot * tail;
|
|
||||||
|
|
||||||
// obtain and initialise slot for a PendingSlot.
|
|
||||||
static PendingSlot* getSlot(PendingType type, byte* packet, byte length, byte repeats, uint16_t loco);
|
|
||||||
static void recycle(PendingSlot* p);
|
|
||||||
void addQueue(PendingSlot * p);
|
|
||||||
void jumpQueue(PendingSlot * p);
|
|
||||||
|
|
||||||
};
|
|
||||||
#endif
|
|
@ -194,7 +194,7 @@ monitor_speed = 115200
|
|||||||
monitor_echo = yes
|
monitor_echo = yes
|
||||||
|
|
||||||
[env:Nucleo-F411RE]
|
[env:Nucleo-F411RE]
|
||||||
platform = ststm32 @ 19.0.0
|
platform = ststm32 @ 17.6.0
|
||||||
board = nucleo_f411re
|
board = nucleo_f411re
|
||||||
framework = arduino
|
framework = arduino
|
||||||
lib_deps = ${env.lib_deps}
|
lib_deps = ${env.lib_deps}
|
||||||
@ -203,7 +203,7 @@ monitor_speed = 115200
|
|||||||
monitor_echo = yes
|
monitor_echo = yes
|
||||||
|
|
||||||
[env:Nucleo-F446RE]
|
[env:Nucleo-F446RE]
|
||||||
platform = ststm32 @ 19.0.0
|
platform = ststm32 @ 17.6.0
|
||||||
board = nucleo_f446re
|
board = nucleo_f446re
|
||||||
framework = arduino
|
framework = arduino
|
||||||
lib_deps = ${env.lib_deps}
|
lib_deps = ${env.lib_deps}
|
||||||
@ -215,7 +215,7 @@ monitor_echo = yes
|
|||||||
; tested as yet
|
; tested as yet
|
||||||
;
|
;
|
||||||
[env:Nucleo-F401RE]
|
[env:Nucleo-F401RE]
|
||||||
platform = ststm32 @ 19.0.0
|
platform = ststm32 @ 17.6.0
|
||||||
board = nucleo_f401re
|
board = nucleo_f401re
|
||||||
framework = arduino
|
framework = arduino
|
||||||
lib_deps = ${env.lib_deps}
|
lib_deps = ${env.lib_deps}
|
||||||
@ -228,7 +228,7 @@ monitor_echo = yes
|
|||||||
; installed before you can let PlatformIO see this
|
; installed before you can let PlatformIO see this
|
||||||
;
|
;
|
||||||
; [env:Nucleo-F413ZH]
|
; [env:Nucleo-F413ZH]
|
||||||
; platform = ststm32 @ 19.0.0
|
; platform = ststm32 @ 17.6.0
|
||||||
; board = nucleo_f413zh
|
; board = nucleo_f413zh
|
||||||
; framework = arduino
|
; framework = arduino
|
||||||
; lib_deps = ${env.lib_deps}
|
; lib_deps = ${env.lib_deps}
|
||||||
@ -240,7 +240,7 @@ monitor_echo = yes
|
|||||||
; installed before you can let PlatformIO see this
|
; installed before you can let PlatformIO see this
|
||||||
;
|
;
|
||||||
[env:Nucleo-F446ZE]
|
[env:Nucleo-F446ZE]
|
||||||
platform = ststm32 @ 19.0.0
|
platform = ststm32 @ 17.6.0
|
||||||
board = nucleo_f446ze
|
board = nucleo_f446ze
|
||||||
framework = arduino
|
framework = arduino
|
||||||
lib_deps = ${env.lib_deps}
|
lib_deps = ${env.lib_deps}
|
||||||
@ -252,7 +252,7 @@ monitor_echo = yes
|
|||||||
; installed before you can let PlatformIO see this
|
; installed before you can let PlatformIO see this
|
||||||
;
|
;
|
||||||
; [env:Nucleo-F412ZG]
|
; [env:Nucleo-F412ZG]
|
||||||
; platform = ststm32 @ 19.0.0
|
; platform = ststm32 @ 17.6.0
|
||||||
; board = nucleo_f412zg
|
; board = nucleo_f412zg
|
||||||
; framework = arduino
|
; framework = arduino
|
||||||
; lib_deps = ${env.lib_deps}
|
; lib_deps = ${env.lib_deps}
|
||||||
@ -264,7 +264,7 @@ monitor_echo = yes
|
|||||||
; Experimental - Ethernet work still in progress
|
; Experimental - Ethernet work still in progress
|
||||||
;
|
;
|
||||||
[env:Nucleo-F429ZI]
|
[env:Nucleo-F429ZI]
|
||||||
platform = ststm32 @ 19.0.0
|
platform = ststm32 @ 17.6.0
|
||||||
board = nucleo_f429zi
|
board = nucleo_f429zi
|
||||||
framework = arduino
|
framework = arduino
|
||||||
lib_deps = ${env.lib_deps}
|
lib_deps = ${env.lib_deps}
|
||||||
@ -276,7 +276,7 @@ lib_ignore = WiFi101
|
|||||||
WiFiEspAT
|
WiFiEspAT
|
||||||
WiFiMulti_Generic
|
WiFiMulti_Generic
|
||||||
WiFiNINA_Generic
|
WiFiNINA_Generic
|
||||||
build_flags = -std=c++17 -Os -g2 -Wunused-variable -DCUSTOM_PERIPHERAL_PINS
|
build_flags = -std=c++17 -Os -g2 -Wunused-variable
|
||||||
monitor_speed = 115200
|
monitor_speed = 115200
|
||||||
monitor_echo = yes
|
monitor_echo = yes
|
||||||
upload_protocol = stlink
|
upload_protocol = stlink
|
||||||
@ -284,7 +284,7 @@ upload_protocol = stlink
|
|||||||
; Experimental - Ethernet work still in progress
|
; Experimental - Ethernet work still in progress
|
||||||
;
|
;
|
||||||
[env:Nucleo-F439ZI]
|
[env:Nucleo-F439ZI]
|
||||||
platform = ststm32 @ 19.0.0
|
platform = ststm32 @ 17.6.0
|
||||||
; board = nucleo_f439zi
|
; board = nucleo_f439zi
|
||||||
; Temporarily treat it as an F429ZI (they are code compatible) until
|
; Temporarily treat it as an F429ZI (they are code compatible) until
|
||||||
; the PR to PlatformIO to update the F439ZI JSON file is available
|
; the PR to PlatformIO to update the F439ZI JSON file is available
|
||||||
@ -300,7 +300,7 @@ lib_ignore = WiFi101
|
|||||||
WiFiEspAT
|
WiFiEspAT
|
||||||
WiFiMulti_Generic
|
WiFiMulti_Generic
|
||||||
WiFiNINA_Generic
|
WiFiNINA_Generic
|
||||||
build_flags = -std=c++17 -Os -g2 -Wunused-variable -DCUSTOM_PERIPHERAL_PINS
|
build_flags = -std=c++17 -Os -g2 -Wunused-variable
|
||||||
monitor_speed = 115200
|
monitor_speed = 115200
|
||||||
monitor_echo = yes
|
monitor_echo = yes
|
||||||
upload_protocol = stlink
|
upload_protocol = stlink
|
||||||
|
@ -3,9 +3,7 @@
|
|||||||
|
|
||||||
#include "StringFormatter.h"
|
#include "StringFormatter.h"
|
||||||
|
|
||||||
#define VERSION "5.5.14"
|
#define VERSION "5.5.12"
|
||||||
// 5.5.14 - DCC Non-blocking packet queue with priority
|
|
||||||
// 5.5.13 - Update STM32duino core to v19.0.0. for updated PeripheralPins.c in preparation for F429/439ZI Ethernet support
|
|
||||||
// 5.5.12 - Websocket support (wifi only)
|
// 5.5.12 - Websocket support (wifi only)
|
||||||
// 5.5.11 - (5.4.2) accessory command reverse
|
// 5.5.11 - (5.4.2) accessory command reverse
|
||||||
// 5.5.10 - CamParser fix
|
// 5.5.10 - CamParser fix
|
||||||
|
Loading…
x
Reference in New Issue
Block a user