Skip to content

Commit

Permalink
Merge pull request #50 from pmnxis/dev/i49_eeprom_factory_reset
Browse files Browse the repository at this point in the history
Eeprom factory reset
  • Loading branch information
pmnxis committed Nov 10, 2023
2 parents 60fbb99 + 7a3e9db commit a230821
Show file tree
Hide file tree
Showing 3 changed files with 124 additions and 35 deletions.
1 change: 1 addition & 0 deletions card-terminal-adapter/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ pub enum CardTerminalDisplayWarning {
RequireLatestTerminalVersion,
WarnExperimentalVesion,
WarnUnknown,
WarnEepromFactoryReset,
}

pub const TID_LEN: usize = 10;
Expand Down
91 changes: 57 additions & 34 deletions src/application/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ mod player_to_vend_led;
use card_terminal_adapter::types::*;
use card_terminal_adapter::*;
use embassy_futures::yield_now;
use embassy_time::Duration;
use embassy_time::Timer;
use embassy_time::{Duration, Instant, Timer};
use io_card::PaymentReceive;

use self::mutual_inhibit::MutualInhibit;
use crate::boards::*;
use crate::components::eeprom;
use crate::semi_layer;
use crate::semi_layer::buffered_wait::InputEventKind;
use crate::types::dip_switch_config::{AppMode0V3, TimingOverride};
Expand All @@ -43,6 +43,7 @@ impl Application {
// this function should be inside of loop.
let board = self.board;
let hardware = &self.board.hardware;
let card_reader = &hardware.card_reader;
let shared = self.board.shared_resource;
let async_input_event_ch = &shared.async_input_event_ch;
let mut timing = TimingOverride::default();
Expand All @@ -51,6 +52,10 @@ impl Application {
let mut income_backup: Option<PaymentReceive> = None; // for StartButtonDecideSerialToVend
let mut mutual_inhibit = MutualInhibit::new();
let mut did_we_ask: u8 = 0;
#[cfg(feature = "svc_button")]
let (mut last_svc_pressed, mut is_svc_pressed): (Instant, bool) = (Instant::now(), false);
#[cfg(feature = "svc_button")]
let eeprom = &hardware.eeprom;

loop {
// timing flag would be used in future implementation.
Expand Down Expand Up @@ -93,32 +98,24 @@ impl Application {
income_backup = None;

if appmode_latest == AppMode0V3::DisplayRom {
hardware
.card_reader
.send(CardTerminalTxCmd::DisplayRom)
.await;
card_reader.send(CardTerminalTxCmd::DisplayRom).await;
} else if appmode == AppMode0V3::DisplayRom {
hardware
.card_reader
.send(CardTerminalTxCmd::DisplayHwInfo)
.await;
card_reader.send(CardTerminalTxCmd::DisplayHwInfo).await;
}

appmode = appmode_latest;
}

if let Ok(x) = hardware.card_reader.recv_channel.try_receive() {
if let Ok(x) = card_reader.recv_channel.try_receive() {
match x {
CardTerminalRxCmd::RequestDeviceInfo => {
hardware
.card_reader
card_reader
.send(CardTerminalTxCmd::ResponseDeviceInfo)
.await;

// todo! - don't care did_we_ask var, and just backup PortBackup always for inhibit action.
if (did_we_ask & 0b111) == 0 {
hardware
.card_reader
card_reader
.send(CardTerminalTxCmd::RequestTerminalInfo)
.await;
}
Expand All @@ -133,20 +130,20 @@ impl Application {
match income_backup.is_some() {
true => {
defmt::warn!("StartButtonDecideSerialToVend - duplicated income received, player should press start button.");
hardware.card_reader.send_nack().await; // even send nack, it doesn't cancel payment with NDA device.
card_reader.send_nack().await; // even send nack, it doesn't cancel payment with NDA device.
}
false => {
defmt::info!("StartButtonDecideSerialToVend - income received, wait for start button");
income_backup = Some(payment);
hardware.card_reader.send_ack().await;
card_reader.send_ack().await;
}
}
} else {
payment
// .override_player_by_duration()
.apply_output(board, timing.is_override_force())
.await;
hardware.card_reader.send_ack().await;
card_reader.send_ack().await;
}
}
CardTerminalRxCmd::AlertPaymentIncomePrice(raw_price) => {
Expand All @@ -165,20 +162,20 @@ impl Application {
match income_backup.is_some() {
true => {
defmt::warn!("StartButtonDecideSerialToVend - duplicated income received, player should press start button.");
hardware.card_reader.send_nack().await; // even send nack, it doesn't cancel payment with NDA device.
card_reader.send_nack().await; // even send nack, it doesn't cancel payment with NDA device.
}
false => {
defmt::info!("StartButtonDecideSerialToVend - income received, wait for start button");
income_backup = Some(payment);
hardware.card_reader.send_ack().await;
card_reader.send_ack().await;
}
}
} else {
payment
// .override_player_by_duration()
.apply_output(board, timing.is_override_force())
.await;
hardware.card_reader.send_ack().await;
card_reader.send_ack().await;
}
}
CardTerminalRxCmd::ResponseSaleSlotInfo => {
Expand All @@ -188,8 +185,7 @@ impl Application {
// read from lock_read for do something
// handle different TID/and something
CardTerminalRxCmd::ResponseTerminalInfo(TidStatus::Changed) => {
hardware
.card_reader
card_reader
.send(CardTerminalTxCmd::RequestSaleSlotInfo)
.await;
}
Expand All @@ -207,18 +203,45 @@ impl Application {
#[cfg(feature = "svc_button")]
Ok(InputEvent {
port: InputPortKind::SvcButton,
event: InputEventKind::LongPressed(t),
event,
}) => {
if (2 < t) && (t < 120) {
hardware
.card_reader
.send(CardTerminalTxCmd::DisplayRom)
.await;
} else {
hardware
.card_reader
.send(CardTerminalTxCmd::DisplayHwInfo)
.await;
match event {
InputEventKind::Pressed => {
is_svc_pressed = true;
last_svc_pressed = Instant::now();
}
InputEventKind::LongPressed(t) => {
if t < 2 {
} else if (2 < t) && (t < 120) {
card_reader.send(CardTerminalTxCmd::DisplayRom).await;
} else {
// Factory reset by SvcButton
// but this clear only 1/2p credit and coin count
if ((Instant::now() - last_svc_pressed)
> Duration::from_secs(10))
&& is_svc_pressed
{
defmt::info!("Factory reset EEPROM");

card_reader
.send(CardTerminalTxCmd::DisplayWarning(
CardTerminalDisplayWarning::WarnEepromFactoryReset,
))
.await;

eeprom.lock_write_zero(eeprom::select::P1_CARD_CNT).await;
eeprom.lock_write_zero(eeprom::select::P2_CARD_CNT).await;
eeprom.lock_write_zero(eeprom::select::P1_COIN_CNT).await;
eeprom.lock_write_zero(eeprom::select::P2_COIN_CNT).await;
} else {
card_reader.send(CardTerminalTxCmd::DisplayHwInfo).await;
}
}
is_svc_pressed = false;
}
InputEventKind::Released => {
is_svc_pressed = false;
}
}

yield_now().await;
Expand Down
67 changes: 66 additions & 1 deletion src/components/eeprom.rs
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ pub mod select {

// #[async_trait]
pub trait NovellaRw {
type InnerType: Sized;
type InnerType: Sized + Zeroable;
async fn lock_read(
&self,
mutex: &Mutex<ThreadModeRawMutex, NovellaModuleControlBlock>,
Expand All @@ -220,6 +220,8 @@ pub trait NovellaRw {
mutex: &Mutex<ThreadModeRawMutex, NovellaModuleControlBlock>,
src: Self::InnerType,
);

async fn lock_write_zero(&self, mutex: &Mutex<ThreadModeRawMutex, NovellaModuleControlBlock>);
}

fn should_not_happen() -> ! {
Expand Down Expand Up @@ -286,6 +288,23 @@ impl NovellaRw for NovellaSelector<u32> {

cb.control_mut(self.section).set_dirty();
}

async fn lock_write_zero(&self, mutex: &Mutex<ThreadModeRawMutex, NovellaModuleControlBlock>) {
let mut cb = mutex.lock().await;

*(match self.section {
NvMemSectionKind::P1CardCnt => &mut cb.data.p1_card_cnt,
NvMemSectionKind::P2CardCnt => &mut cb.data.p2_card_cnt,
NvMemSectionKind::P1CoinCnt => &mut cb.data.p1_coin_cnt,
NvMemSectionKind::P2CoinCnt => &mut cb.data.p2_coin_cnt,
NvMemSectionKind::HwBootCount => &mut cb.data.hw_boot_cnt,
_ => {
should_not_happen();
}
}) = Self::InnerType::zeroed();

cb.control_mut(self.section).set_dirty();
}
}

impl NovellaRw for NovellaSelector<FaultLog> {
Expand Down Expand Up @@ -322,6 +341,19 @@ impl NovellaRw for NovellaSelector<FaultLog> {

cb.control_mut(self.section).set_dirty();
}

async fn lock_write_zero(&self, mutex: &Mutex<ThreadModeRawMutex, NovellaModuleControlBlock>) {
let mut cb = mutex.lock().await;

*(match self.section {
NvMemSectionKind::FaultLog => &mut cb.data.fault_log,
_ => {
should_not_happen();
}
}) = Self::InnerType::zeroed();

cb.control_mut(self.section).set_dirty();
}
}

impl NovellaRw for NovellaSelector<RawTerminalId> {
Expand Down Expand Up @@ -358,6 +390,19 @@ impl NovellaRw for NovellaSelector<RawTerminalId> {

cb.control_mut(self.section).set_dirty();
}

async fn lock_write_zero(&self, mutex: &Mutex<ThreadModeRawMutex, NovellaModuleControlBlock>) {
let mut cb = mutex.lock().await;

*(match self.section {
NvMemSectionKind::TerminalId => &mut cb.data.raw_terminal,
_ => {
should_not_happen();
}
}) = Self::InnerType::zeroed();

cb.control_mut(self.section).set_dirty();
}
}

impl NovellaRw for NovellaSelector<CardReaderPortBackup> {
Expand Down Expand Up @@ -394,6 +439,19 @@ impl NovellaRw for NovellaSelector<CardReaderPortBackup> {

cb.control_mut(self.section).set_dirty();
}

async fn lock_write_zero(&self, mutex: &Mutex<ThreadModeRawMutex, NovellaModuleControlBlock>) {
let mut cb = mutex.lock().await;

*(match self.section {
NvMemSectionKind::CardPortBackup => &mut cb.data.card_reader_port_backup,
_ => {
should_not_happen();
}
}) = Self::InnerType::zeroed();

cb.control_mut(self.section).set_dirty();
}
}

impl NovellaSectionControlBlock {
Expand Down Expand Up @@ -600,6 +658,13 @@ impl Novella {
slot.lock_write(&self.mem_storage, src).await
}

pub async fn lock_write_zero<R>(&self, slot: R)
where
R: NovellaRw,
{
slot.lock_write_zero(&self.mem_storage).await
}

#[inline]
fn consider_initial_uptime(page_idx: u8) -> bool {
page_idx == 0
Expand Down

0 comments on commit a230821

Please sign in to comment.