use super::flash_properties::FlashProperties;
use crate::serialize::{hex_map, hex_map_deserialize, hex_option, hex_u_int};
use base64::{Engine as _, engine::general_purpose as base64_engine};
use indexmap::IndexMap;
use serde::{Deserialize, Serialize};
#[derive(Debug, Default, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, Hash)]
#[serde(rename_all = "snake_case")]
pub enum TransferEncoding {
#[default]
Raw,
Miniz,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(deny_unknown_fields)]
pub struct RawFlashAlgorithm {
pub name: String,
pub description: String,
#[serde(default)]
pub default: bool,
#[serde(deserialize_with = "deserialize")]
#[serde(serialize_with = "serialize")]
pub instructions: Vec<u8>,
#[serde(serialize_with = "hex_option")]
pub load_address: Option<u64>,
#[serde(serialize_with = "hex_option")]
pub data_load_address: Option<u64>,
#[serde(serialize_with = "hex_option")]
pub pc_init: Option<u64>,
#[serde(serialize_with = "hex_option")]
pub pc_uninit: Option<u64>,
#[serde(serialize_with = "hex_u_int")]
pub pc_program_page: u64,
#[serde(serialize_with = "hex_u_int")]
pub pc_erase_sector: u64,
#[serde(serialize_with = "hex_option")]
pub pc_erase_all: Option<u64>,
#[serde(serialize_with = "hex_option")]
pub pc_verify: Option<u64>,
#[serde(serialize_with = "hex_option")]
pub pc_blank_check: Option<u64>,
#[serde(serialize_with = "hex_option")]
pub pc_read: Option<u64>,
#[serde(
default,
serialize_with = "hex_map",
deserialize_with = "hex_map_deserialize"
)]
pub vendor_functions: IndexMap<String, u64>,
#[serde(serialize_with = "hex_u_int")]
pub data_section_offset: u64,
#[serde(serialize_with = "hex_option")]
pub rtt_location: Option<u64>,
#[serde(default = "default_rtt_poll_interval")]
pub rtt_poll_interval: u64,
pub flash_properties: FlashProperties,
#[serde(default)]
pub cores: Vec<String>,
pub stack_size: Option<u32>,
#[serde(default)]
pub stack_overflow_check: Option<bool>,
#[serde(default)]
pub transfer_encoding: Option<TransferEncoding>,
#[serde(default)]
pub big_endian: bool,
}
impl Default for RawFlashAlgorithm {
fn default() -> Self {
Self {
rtt_poll_interval: default_rtt_poll_interval(),
name: Default::default(),
description: Default::default(),
default: Default::default(),
instructions: Default::default(),
load_address: Default::default(),
data_load_address: Default::default(),
pc_init: Default::default(),
pc_uninit: Default::default(),
pc_program_page: Default::default(),
pc_erase_sector: Default::default(),
pc_erase_all: Default::default(),
pc_verify: Default::default(),
pc_blank_check: Default::default(),
pc_read: Default::default(),
vendor_functions: Default::default(),
data_section_offset: Default::default(),
rtt_location: Default::default(),
flash_properties: Default::default(),
cores: Default::default(),
stack_size: Default::default(),
stack_overflow_check: Default::default(),
transfer_encoding: Default::default(),
big_endian: Default::default(),
}
}
}
impl RawFlashAlgorithm {
pub fn stack_overflow_check(&self) -> bool {
self.stack_overflow_check.unwrap_or(true)
}
}
pub fn serialize<S>(bytes: &[u8], serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
if serializer.is_human_readable() {
Base64::serialize(bytes, serializer)
} else {
Bytes::serialize(bytes, serializer)
}
}
pub fn deserialize<'de, D>(deserializer: D) -> Result<Vec<u8>, D::Error>
where
D: serde::Deserializer<'de>,
{
if deserializer.is_human_readable() {
Base64::deserialize(deserializer)
} else {
Bytes::deserialize(deserializer)
}
}
struct Base64;
impl Base64 {
fn serialize<S>(bytes: &[u8], serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serializer.serialize_str(base64_engine::STANDARD.encode(bytes).as_str())
}
fn deserialize<'de, D>(deserializer: D) -> Result<Vec<u8>, D::Error>
where
D: serde::Deserializer<'de>,
{
deserializer.deserialize_str(Base64)
}
}
impl serde::de::Visitor<'_> for Base64 {
type Value = Vec<u8>;
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(formatter, "base64 ASCII text")
}
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
base64_engine::STANDARD
.decode(v)
.map_err(serde::de::Error::custom)
}
}
struct Bytes;
impl Bytes {
fn serialize<S>(bytes: &[u8], serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serializer.serialize_bytes(bytes)
}
fn deserialize<'de, D>(deserializer: D) -> Result<Vec<u8>, D::Error>
where
D: serde::Deserializer<'de>,
{
deserializer.deserialize_bytes(Bytes)
}
}
impl serde::de::Visitor<'_> for Bytes {
type Value = Vec<u8>;
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(formatter, "binary data")
}
fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(v.to_vec())
}
}
fn default_rtt_poll_interval() -> u64 {
20
}