|
|
@@ -6,31 +6,10 @@
|
|
|
#include "program_memory.h"
|
|
|
#include "serial_output.h"
|
|
|
|
|
|
-#if defined(MECOFFEE_RUST_SHOT)
|
|
|
-#include <avr/io.h>
|
|
|
-#include <avr/interrupt.h>
|
|
|
-#include <stddef.h>
|
|
|
-struct RustShotSettings {uint16_t enabled,closed,pump,pause,maximum;};
|
|
|
-extern "C" {
|
|
|
-void mecoffee_rust_shot_event(meCoffee::ShotState*,uint8_t,uint32_t,uint32_t,void*);
|
|
|
-void mecoffee_rust_shot_active(meCoffee::ShotState*,const RustShotSettings*,uint8_t,uint32_t,uint32_t,void*);
|
|
|
-void mecoffee_rust_poll_input(meCoffee::DebouncedInput*,uint8_t,uint8_t,uint32_t,void*);
|
|
|
-uint16_t mecoffee_rust_shot_layout(uint8_t);
|
|
|
-}
|
|
|
-static_assert(sizeof(meCoffee::ShotState)==5,"shot state ABI");
|
|
|
-static_assert(sizeof(meCoffee::DebouncedInput)==15,"input state ABI");
|
|
|
-static_assert(offsetof(meCoffee::DebouncedInput,beginTimestamp)==3,"input begin ABI");
|
|
|
-#endif
|
|
|
-
|
|
|
namespace meCoffee {
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
-#if defined(MECOFFEE_RUST_TELEMETRY)
|
|
|
-extern "C" void mecoffee_rust_telemetry(void*,uint8_t);
|
|
|
-void reportShotBegin(FirmwareState& state) { mecoffee_rust_telemetry(&state,3); }
|
|
|
-void reportShotEnd(FirmwareState& state) { mecoffee_rust_telemetry(&state,4); }
|
|
|
-#else
|
|
|
void reportShotBegin(FirmwareState& state) {
|
|
|
if (state.alternateModeSelection != 0) {
|
|
|
return;
|
|
|
@@ -52,39 +31,24 @@ void reportShotEnd(FirmwareState& state) {
|
|
|
writeProgramMemoryText(MECOFFEE_PROGRAM_TEXT(" OK"));
|
|
|
writeCarriageReturnLineFeed();
|
|
|
}
|
|
|
-#endif
|
|
|
-
|
|
|
|
|
|
void beginShotEvent(FirmwareState* state, uint32_t timestamp) {
|
|
|
-#if defined(MECOFFEE_RUST_SHOT)
|
|
|
- mecoffee_rust_shot_event(&state->shot,0,timestamp,0,state);
|
|
|
-#else
|
|
|
// Observed in the original: a shot begin counts as user activity for the inactivity timer.
|
|
|
state->powerSchedule.lastActivityTimestamp = timestamp;
|
|
|
state->shot.isTimeoutEventLatched = false;
|
|
|
beginShotFeedForward(state, timestamp);
|
|
|
enqueueDiagnosticCallback(&state->diagnosticQueue, reportShotBegin);
|
|
|
-#endif
|
|
|
}
|
|
|
|
|
|
void endShotEvent(FirmwareState* state, uint32_t endTimestamp, uint32_t beginTimestamp) {
|
|
|
-#if defined(MECOFFEE_RUST_SHOT)
|
|
|
- mecoffee_rust_shot_event(&state->shot,1,endTimestamp,beginTimestamp,state);
|
|
|
-#else
|
|
|
setGroupEnabled(&groupForRole(&state->outputChannels, OutputGroupRole::Pump), false);
|
|
|
setGroupEnabled(&groupForRole(&state->outputChannels, OutputGroupRole::Valve), false);
|
|
|
state->shot.lastShotDuration = endTimestamp - beginTimestamp;
|
|
|
endShotFeedForward(state, endTimestamp);
|
|
|
enqueueDiagnosticCallback(&state->diagnosticQueue, reportShotEnd);
|
|
|
-#endif
|
|
|
}
|
|
|
|
|
|
void runShotActiveCallback(FirmwareState* state, uint32_t foregroundSnapshotMilliseconds, uint32_t beginTimestamp) {
|
|
|
-#if defined(MECOFFEE_RUST_SHOT)
|
|
|
- const auto& s=state->settings;
|
|
|
- const RustShotSettings settings={s.preinfusionEnabled,s.preinfusionValveClosed,s.preinfusionPumpDuration,s.preinfusionPauseDuration,s.maximumShotDuration};
|
|
|
- mecoffee_rust_shot_active(&state->shot,&settings,state->alternateModeSelection,foregroundSnapshotMilliseconds,beginTimestamp,state);
|
|
|
-#else
|
|
|
const uint32_t elapsed = foregroundSnapshotMilliseconds - beginTimestamp;
|
|
|
const ShotOutputRequest request = evaluateShotOutputRequest(state->settings, state->alternateModeSelection, elapsed);
|
|
|
OutputGroup& pump = groupForRole(&state->outputChannels, OutputGroupRole::Pump);
|
|
|
@@ -101,7 +65,6 @@ void runShotActiveCallback(FirmwareState* state, uint32_t foregroundSnapshotMill
|
|
|
state->shot.isTimeoutEventLatched = false;
|
|
|
setGroupEnabled(&pump, request.isPumpRequested);
|
|
|
setGroupEnabled(&valve, request.isValveRequested);
|
|
|
-#endif
|
|
|
}
|
|
|
|
|
|
// Begin (argument 1) and end (argument 0) of an input burst.
|
|
|
@@ -130,9 +93,6 @@ bool isInputQualified(const DebouncedInput& input) {
|
|
|
}
|
|
|
|
|
|
void initializeDebouncedInput(DebouncedInput* input) {
|
|
|
-#if defined(MECOFFEE_RUST_SHOT)
|
|
|
- if(mecoffee_rust_shot_layout(0)!=5 || mecoffee_rust_shot_layout(1)!=15 || mecoffee_rust_shot_layout(2)!=10 || mecoffee_rust_shot_layout(3)!=3) {cli();for(;;){}}
|
|
|
-#endif
|
|
|
*input = DebouncedInput{};
|
|
|
input->isLastLevelHigh = true;
|
|
|
}
|
|
|
@@ -151,9 +111,6 @@ ShotOutputRequest evaluateShotOutputRequest(const SettingsValues& settings, uint
|
|
|
|
|
|
void pollDebouncedInput(FirmwareState* state, DebouncedInput* input, InputRole role, bool isPinHigh,
|
|
|
uint32_t foregroundSnapshotMilliseconds) {
|
|
|
-#if defined(MECOFFEE_RUST_SHOT)
|
|
|
- mecoffee_rust_poll_input(input,static_cast<uint8_t>(role),isPinHigh,foregroundSnapshotMilliseconds,state);
|
|
|
-#else
|
|
|
if (isPinHigh != input->isLastLevelHigh) {
|
|
|
input->isLastLevelHigh = isPinHigh;
|
|
|
input->lastChangeTimestamp = foregroundSnapshotMilliseconds;
|
|
|
@@ -189,31 +146,6 @@ void pollDebouncedInput(FirmwareState* state, DebouncedInput* input, InputRole r
|
|
|
runInputStateChange(state, role, 0, foregroundSnapshotMilliseconds, beginTimestamp);
|
|
|
}
|
|
|
}
|
|
|
-#endif
|
|
|
-}
|
|
|
-
|
|
|
-#if defined(MECOFFEE_RUST_SHOT)
|
|
|
-extern "C" void mecoffee_shot_effect(void* context,uint8_t operation,uint32_t value) {
|
|
|
- auto* state=static_cast<FirmwareState*>(context);
|
|
|
- switch(operation) {
|
|
|
- case 0: state->powerSchedule.lastActivityTimestamp=value;break;
|
|
|
- case 1: {
|
|
|
- const uint8_t saved=SREG;cli();
|
|
|
- setGroupEnabled(&groupForRole(&state->outputChannels,static_cast<OutputGroupRole>(value&255)),(value&256)!=0);
|
|
|
- SREG=saved;break;
|
|
|
- }
|
|
|
- case 2: beginShotFeedForward(state,value);break;
|
|
|
- case 3: endShotFeedForward(state,value);break;
|
|
|
- case 4: enqueueDiagnosticCallback(&state->diagnosticQueue,reportShotBegin);break;
|
|
|
- case 5: enqueueDiagnosticCallback(&state->diagnosticQueue,reportShotEnd);break;
|
|
|
- }
|
|
|
-}
|
|
|
-extern "C" void mecoffee_input_event(void* context,uint8_t role,uint8_t active,uint32_t now,uint32_t begin) {
|
|
|
- auto* state=static_cast<FirmwareState*>(context);
|
|
|
- // Use the supplied timestamp, never read the Rust-borrowed DebouncedInput.
|
|
|
- if(active==2) runShotActiveCallback(state,now,begin);
|
|
|
- else runInputStateChange(state,static_cast<InputRole>(role),active,now,begin);
|
|
|
}
|
|
|
-#endif
|
|
|
|
|
|
} // namespace meCoffee
|