Reorganisation fichiers
This commit is contained in:
411
PacoMouseCYD/Platformio/Arduino.old/accessories.ino
Normal file
411
PacoMouseCYD/Platformio/Arduino.old/accessories.ino
Normal file
@@ -0,0 +1,411 @@
|
||||
|
||||
/**
|
||||
* @file accessories.ino
|
||||
* @brief Accessory FIFO and control functions for PacoMouseCYD throttle.
|
||||
* @author F. Cañada
|
||||
* @date 2025-2026
|
||||
* @copyright https://usuaris.tinet.cat/fmco/
|
||||
*
|
||||
* This file contains functions to manage accessory commands using a FIFO buffer,
|
||||
* and to send accessory commands to the model train system.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// API Documentation
|
||||
////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* @brief Initializes the accessory FIFO buffer.
|
||||
*
|
||||
* Resets FIFO indices and state to empty.
|
||||
*/
|
||||
void initFIFO();
|
||||
|
||||
/**
|
||||
* @brief Reads the next accessory command from the FIFO.
|
||||
* @return The next accessory command in the FIFO.
|
||||
*/
|
||||
unsigned int readFIFO();
|
||||
|
||||
/**
|
||||
* @brief Writes an accessory command to the FIFO.
|
||||
* @param FAdr The accessory address.
|
||||
* @param pos The position or state to set.
|
||||
*/
|
||||
void writeFIFO(uint16_t FAdr, uint8_t pos);
|
||||
|
||||
/**
|
||||
* @brief Processes and sends accessory commands from the FIFO.
|
||||
*
|
||||
* Handles timing and state transitions for accessory activation and deactivation.
|
||||
*/
|
||||
void sendAccessoryFIFO();
|
||||
|
||||
/**
|
||||
* @brief Adds an accessory command to the FIFO for later execution.
|
||||
* @param FAdr The accessory address.
|
||||
* @param pos The position or state to set.
|
||||
*/
|
||||
void moveAccessory(uint16_t FAdr, uint8_t pos);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// End API Documentation
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
/* PacoMouseCYD throttle -- F. Cañada 2025-2026 -- https://usuaris.tinet.cat/fmco/
|
||||
*/
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// ***** ACCESSORY FIFO *****
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
void initFIFO() {
|
||||
lastInFIFO = 0;
|
||||
firstOutFIFO = 0;
|
||||
cntFIFO = 0;
|
||||
stateFIFO = FIFO_EMPTY;
|
||||
}
|
||||
|
||||
|
||||
unsigned int readFIFO () {
|
||||
firstOutFIFO = (firstOutFIFO + 1 ) & 0x1F; // next one (hardcoded)
|
||||
cntFIFO--;
|
||||
return (accessoryFIFO[firstOutFIFO]);
|
||||
}
|
||||
|
||||
|
||||
void writeFIFO (uint16_t FAdr, uint8_t pos) {
|
||||
lastInFIFO = (lastInFIFO + 1 ) & 0x1F; // next one (hardcoded)
|
||||
cntFIFO++;
|
||||
if (pos > 0)
|
||||
FAdr |= 0x8000;
|
||||
accessoryFIFO[lastInFIFO] = FAdr; // save in FIFO
|
||||
}
|
||||
|
||||
|
||||
void sendAccessoryFIFO () {
|
||||
switch (stateFIFO) {
|
||||
case FIFO_ACC_CDU: // wait for CDU recharge
|
||||
case FIFO_EMPTY:
|
||||
if (cntFIFO > 0) { // activate accessory from FIFO
|
||||
lastAccessory = readFIFO();
|
||||
sendAccessory(lastAccessory & 0x7FFF, bitRead(lastAccessory, 15), true);
|
||||
setTimer(TMR_ACCESSORY, TIME_ACC_ON, TMR_ONESHOT);
|
||||
stateFIFO = FIFO_ACC_ON;
|
||||
DEBUG_MSG("Moving acc. %d-%d", lastAccessory & 0x7FFF, lastAccessory >> 15);
|
||||
}
|
||||
else
|
||||
stateFIFO = FIFO_EMPTY;
|
||||
break;
|
||||
case FIFO_ACC_ON: // deactivate accessory
|
||||
sendAccessory(lastAccessory & 0x7FFF, bitRead(lastAccessory, 15), false);
|
||||
setTimer(TMR_ACCESSORY, TIME_ACC_CDU, TMR_ONESHOT);
|
||||
stateFIFO = FIFO_ACC_CDU;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// ***** ACCESSORY *****
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
void moveAccessory(uint16_t FAdr, uint8_t pos) {
|
||||
writeFIFO(FAdr, pos); // put accessory in FIFO
|
||||
if (stateFIFO == FIFO_EMPTY) // if not pending accessories, force sending now
|
||||
sendAccessoryFIFO();
|
||||
}
|
||||
|
||||
void setAccAspect(uint16_t FAdr, uint16_t FAdr2, uint8_t aspect, uint16_t outs) {
|
||||
uint8_t pos;
|
||||
pos = aspect * 4;
|
||||
if (FAdr > 0) {
|
||||
if (bitRead(outs, pos)) {
|
||||
moveAccessory(FAdr, 0);
|
||||
}
|
||||
else {
|
||||
if (bitRead(outs, pos + 1))
|
||||
moveAccessory(FAdr, 1);
|
||||
}
|
||||
}
|
||||
if (FAdr2 > 0) {
|
||||
if (bitRead(outs, pos + 2)) {
|
||||
moveAccessory(FAdr2, 0);
|
||||
}
|
||||
else {
|
||||
if (bitRead(outs, pos + 3))
|
||||
moveAccessory(FAdr2, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// ***** PANEL *****
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
void deleteAccPanelElement(uint8_t pos) {
|
||||
accPanel[pos].type = ACC_UNDEF;
|
||||
accPanel[pos].currAspect = 0;
|
||||
accPanel[pos].addr = 0;
|
||||
accPanel[pos].addr2 = 0;
|
||||
accPanel[pos].activeOutput = 0;
|
||||
accPanel[pos].accName[0] = '\0';
|
||||
}
|
||||
|
||||
void loadDefaultAccPanel() {
|
||||
uint8_t n;
|
||||
for (n = 0; n < 16; n++) { // Default panel is all blank with only a keypad button
|
||||
deleteAccPanelElement(n);
|
||||
}
|
||||
accPanel[15].type = ACC_KEYPAD;
|
||||
}
|
||||
|
||||
|
||||
void updateAccPanel() {
|
||||
uint8_t n, type, aspect;
|
||||
|
||||
snprintf(panelNameBuf, PANEL_LNG + 1, panelNamesBuf[currPanel]);
|
||||
for (n = 0; n < 16; n++) {
|
||||
type = accPanel[n].type;
|
||||
aspect = accPanel[n].currAspect;
|
||||
snprintf(accNamesBuf[n], ACC_LNG + 1, accPanel[n].accName);
|
||||
fncData[FNC_ACC0 + n].num = accDef[type].num;
|
||||
fncData[FNC_ACC0 + n].idIcon = accDef[type].icon[aspect].fncIcon;
|
||||
fncData[FNC_ACC0 + n].color = accDef[type].icon[aspect].color;
|
||||
fncData[FNC_ACC0 + n].colorOn = accDef[type].icon[aspect].colorOn;
|
||||
fncData[FNC_ACC0 + n].backgnd = (type == ACC_UNDEF) ? COLOR_WHITE : COLOR_LIGHTGREY;
|
||||
buttonData[BUT_ACC_0 + n].backgnd = (type == ACC_UNDEF) ? COLOR_WHITE : COLOR_LIGHTGREY;
|
||||
}
|
||||
}
|
||||
|
||||
void saveCurrentAspects() {
|
||||
uint8_t n;
|
||||
for (n = 0; n < 16; n++)
|
||||
savedAspect[currPanel][n] = accPanel[n].currAspect;
|
||||
}
|
||||
|
||||
void getLastAspects() {
|
||||
uint8_t n;
|
||||
for (n = 0; n < 16; n++)
|
||||
accPanel[n].currAspect = savedAspect[currPanel][n];
|
||||
}
|
||||
|
||||
void deleteLastAspects() {
|
||||
uint8_t n;
|
||||
for (n = 0; n < 16; n++)
|
||||
accPanel[n].currAspect = 0;
|
||||
}
|
||||
|
||||
void initLastAspects() {
|
||||
uint8_t i, j;
|
||||
for (i = 0; i < 16; i++)
|
||||
for (j = 0; j < 16; j++)
|
||||
savedAspect[i][j] = 0;;
|
||||
}
|
||||
|
||||
void populateAccPanel() {
|
||||
loadDefaultAccPanel(); // Load panel data
|
||||
if (sdDetected) {
|
||||
if (loadAccPanel(SD))
|
||||
getLastAspects();
|
||||
else
|
||||
deleteLastAspects();
|
||||
}
|
||||
else {
|
||||
if (loadAccPanel(LittleFS))
|
||||
getLastAspects();
|
||||
else
|
||||
deleteLastAspects();
|
||||
}
|
||||
updateAccPanel();
|
||||
}
|
||||
|
||||
void accPanelClick(uint8_t pos) {
|
||||
uint16_t addr, outs;
|
||||
uint8_t type, aspect;
|
||||
currPanelAcc = pos;
|
||||
if (editAccessory) {
|
||||
paramChild = pos;
|
||||
type = accPanel[pos].type;
|
||||
fncData[FNC_ACC_TYPE].num = accDef[type].num;
|
||||
fncData[FNC_ACC_TYPE].idIcon = accDef[type].icon[0].fncIcon;
|
||||
fncData[FNC_ACC_TYPE].color = accDef[type].icon[0].color;
|
||||
fncData[FNC_ACC_TYPE].colorOn = accDef[type].icon[0].colorOn;
|
||||
encoderValue = type;
|
||||
encoderMax = ACC_MAX - 1;
|
||||
openWindow(WIN_ACC_TYPE);
|
||||
}
|
||||
else {
|
||||
type = accPanel[pos].type;
|
||||
switch (type) {
|
||||
case ACC_UNDEF:
|
||||
break;
|
||||
case ACC_KEYPAD:
|
||||
openWindow(WIN_ACC_CTRL);
|
||||
break;
|
||||
default:
|
||||
addr = accPanel[pos].addr;
|
||||
outs = accPanel[pos].activeOutput;
|
||||
switch (accDef[type].aspects) {
|
||||
case 2:
|
||||
aspect = (accPanel[pos].currAspect > 0) ? 0 : 1;
|
||||
accPanel[pos].currAspect = aspect;
|
||||
fncData[FNC_ACC0 + pos].idIcon = accDef[type].icon[aspect].fncIcon;
|
||||
fncData[FNC_ACC0 + pos].color = accDef[type].icon[aspect].color;
|
||||
fncData[FNC_ACC0 + pos].colorOn = accDef[type].icon[aspect].colorOn;
|
||||
setAccAspect(addr, 0, aspect, outs);
|
||||
newEvent(OBJ_BUTTON, BUT_ACC_0 + pos, EVNT_DRAW);
|
||||
break;
|
||||
case 3:
|
||||
currAccAspects = 3;
|
||||
winData[WIN_ACC_ASPECT].x = 30;
|
||||
winData[WIN_ACC_ASPECT].w = 180;
|
||||
buttonData[BUT_ACC_ASPECT0].x = 50;
|
||||
buttonData[BUT_ACC_ASPECT1].x = 100;
|
||||
buttonData[BUT_ACC_ASPECT2].x = 150;
|
||||
fncData[FNC_ASPECT0].x = 54;
|
||||
fncData[FNC_ASPECT0].idIcon = accDef[type].icon[0].fncIcon;
|
||||
fncData[FNC_ASPECT0].color = accDef[type].icon[0].color;
|
||||
fncData[FNC_ASPECT0].colorOn = accDef[type].icon[0].colorOn;
|
||||
fncData[FNC_ASPECT1].x = 104;
|
||||
fncData[FNC_ASPECT1].idIcon = accDef[type].icon[1].fncIcon;
|
||||
fncData[FNC_ASPECT1].color = accDef[type].icon[1].color;
|
||||
fncData[FNC_ASPECT1].colorOn = accDef[type].icon[1].colorOn;
|
||||
fncData[FNC_ASPECT2].x = 154;
|
||||
fncData[FNC_ASPECT2].idIcon = accDef[type].icon[2].fncIcon;
|
||||
fncData[FNC_ASPECT2].color = accDef[type].icon[2].color;
|
||||
fncData[FNC_ASPECT2].colorOn = accDef[type].icon[2].colorOn;
|
||||
openWindow(WIN_ACC_ASPECT);
|
||||
break;
|
||||
case 4:
|
||||
currAccAspects = 4;
|
||||
winData[WIN_ACC_ASPECT].x = 5;
|
||||
winData[WIN_ACC_ASPECT].w = 230;
|
||||
buttonData[BUT_ACC_ASPECT0].x = 25;
|
||||
buttonData[BUT_ACC_ASPECT1].x = 75;
|
||||
buttonData[BUT_ACC_ASPECT2].x = 125;
|
||||
buttonData[BUT_ACC_ASPECT3].x = 175;
|
||||
fncData[FNC_ASPECT0].x = 29;
|
||||
fncData[FNC_ASPECT0].idIcon = accDef[type].icon[0].fncIcon;
|
||||
fncData[FNC_ASPECT0].color = accDef[type].icon[0].color;
|
||||
fncData[FNC_ASPECT0].colorOn = accDef[type].icon[0].colorOn;
|
||||
fncData[FNC_ASPECT1].x = 79;
|
||||
fncData[FNC_ASPECT1].idIcon = accDef[type].icon[1].fncIcon;
|
||||
fncData[FNC_ASPECT1].color = accDef[type].icon[1].color;
|
||||
fncData[FNC_ASPECT1].colorOn = accDef[type].icon[1].colorOn;
|
||||
fncData[FNC_ASPECT2].x = 129;
|
||||
fncData[FNC_ASPECT2].idIcon = accDef[type].icon[2].fncIcon;
|
||||
fncData[FNC_ASPECT2].color = accDef[type].icon[2].color;
|
||||
fncData[FNC_ASPECT2].colorOn = accDef[type].icon[2].colorOn;
|
||||
fncData[FNC_ASPECT3].x = 179;
|
||||
fncData[FNC_ASPECT3].idIcon = accDef[type].icon[3].fncIcon;
|
||||
fncData[FNC_ASPECT3].color = accDef[type].icon[3].color;
|
||||
fncData[FNC_ASPECT3].colorOn = accDef[type].icon[3].colorOn;
|
||||
openWindow(WIN_ACC_ASPECT);
|
||||
break;
|
||||
default:
|
||||
buttonData[BUT_ACC_0 + pos].backgnd = COLOR_BLACK;
|
||||
drawObject(OBJ_BUTTON, BUT_ACC_0 + pos);
|
||||
buttonData[BUT_ACC_0 + pos].backgnd = COLOR_LIGHTGREY;
|
||||
setAccAspect(addr, 0, 0, outs);
|
||||
newEvent(OBJ_BUTTON, BUT_ACC_0 + pos, EVNT_DRAW);
|
||||
delay(80);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void accAspectClick(uint8_t aspect) {
|
||||
uint16_t addr, addr2, outs;
|
||||
uint8_t type;
|
||||
type = accPanel[currPanelAcc].type;
|
||||
accPanel[currPanelAcc].currAspect = aspect;
|
||||
fncData[FNC_ACC0 + currPanelAcc].idIcon = accDef[type].icon[aspect].fncIcon;
|
||||
fncData[FNC_ACC0 + currPanelAcc].color = accDef[type].icon[aspect].color;
|
||||
fncData[FNC_ACC0 + currPanelAcc].colorOn = accDef[type].icon[aspect].colorOn;
|
||||
addr = accPanel[currPanelAcc].addr;
|
||||
addr2 = accPanel[currPanelAcc].addr2;
|
||||
outs = accPanel[currPanelAcc].activeOutput;
|
||||
setAccAspect(addr, addr2, aspect, outs);
|
||||
}
|
||||
|
||||
|
||||
void accTypeClick() {
|
||||
uint8_t index, n;
|
||||
index = encoderValue;
|
||||
switch (index) {
|
||||
case ACC_UNDEF:
|
||||
alertWindow(ERR_ASK_SURE);
|
||||
break;
|
||||
case ACC_KEYPAD:
|
||||
editAccessory = false;
|
||||
winData[WIN_ACCESSORY].backgnd = COLOR_WHITE;
|
||||
deleteAccPanelElement(paramChild);
|
||||
accPanel[paramChild].type = ACC_KEYPAD;
|
||||
updateAccPanel();
|
||||
updateSpeedHID(); // set encoder
|
||||
closeWindow(WIN_ACC_TYPE);
|
||||
break;
|
||||
default:
|
||||
if (index != accPanel[paramChild].type) {
|
||||
currAccEdit.type = (accType)index;
|
||||
currAccEdit.addr = 0;
|
||||
currAccEdit.addr2 = 0;
|
||||
currAccEdit.currAspect = 0;
|
||||
currAccEdit.activeOutput = accOutDefault[index];
|
||||
currAccEdit.accName[0] = '\0';
|
||||
}
|
||||
else {
|
||||
currAccEdit = accPanel[paramChild];
|
||||
}
|
||||
snprintf(accKeybName, ACC_LNG + 1, currAccEdit.accName);
|
||||
snprintf(accKeybAddr1, ADDR_LNG + 1, "%d", currAccEdit.addr);
|
||||
snprintf(accKeybAddr2, ADDR_LNG + 1, "%d", currAccEdit.addr2);
|
||||
for (n = 0; n < 4; n++) {
|
||||
fncData[FNC_EDIT_ASPECT0 + n].idIcon = accDef[index].icon[n].fncIcon;
|
||||
fncData[FNC_EDIT_ASPECT0 + n].color = accDef[index].icon[n].color;
|
||||
fncData[FNC_EDIT_ASPECT0 + n].colorOn = accDef[index].icon[n].colorOn;
|
||||
}
|
||||
accOutUpdate();
|
||||
closeWindow(WIN_ACC_TYPE);
|
||||
openWindow(WIN_ACC_EDIT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void accOutUpdate() {
|
||||
uint8_t n;
|
||||
for (n = 0; n < 16; n += 2) {
|
||||
buttonData[BUT_ACC_OUT0 + n].backgnd = bitRead(currAccEdit.activeOutput, n) ? COLOR_RED : COLOR_LIGHTBLACK;
|
||||
buttonData[BUT_ACC_OUT0 + n + 1].backgnd = bitRead(currAccEdit.activeOutput, n + 1) ? COLOR_GREEN : COLOR_LIGHTBLACK;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void accOutClick(uint8_t out) {
|
||||
uint8_t outR, outG;
|
||||
outR = out & 0xFE;
|
||||
outG = out | 0x01;
|
||||
currAccEdit.activeOutput ^= bit(out);
|
||||
if (bitRead(out, 0)) { // green
|
||||
if (bitRead(currAccEdit.activeOutput, outG))
|
||||
bitClear(currAccEdit.activeOutput, outR);
|
||||
}
|
||||
else { // red
|
||||
if (bitRead(currAccEdit.activeOutput, outR))
|
||||
bitClear(currAccEdit.activeOutput, outG);
|
||||
}
|
||||
accOutUpdate();
|
||||
newEvent(OBJ_BUTTON, BUT_ACC_OUT0 + outR, EVNT_DRAW);
|
||||
newEvent(OBJ_BUTTON, BUT_ACC_OUT0 + outG, EVNT_DRAW);
|
||||
}
|
||||
|
||||
|
||||
void updateAccChange() {
|
||||
accPanel[paramChild] = currAccEdit;
|
||||
updateAccPanel();
|
||||
accPanelChanged = true;
|
||||
}
|
||||
Reference in New Issue
Block a user