1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#![no_std]

pub mod atmega;

pub type IspCommand = (u8, u8, u8, u8);

pub const PROGRAMMING_ENABLE: IspCommand = (0xac, 0x53, 0x00, 0x00);
pub const CHIP_ERASE: IspCommand = (0xac, 0x80, 0x00, 0x00);
pub const READ_SIGNATURE: IspCommand = (0x30, 0x00, 0x00, 0x00);
pub const READ_FLASH_HIGH: IspCommand = (0x28, 0x00, 0x00, 0x00);
pub const READ_FLASH_LOW: IspCommand = (0x20, 0x00, 0x00, 0x00);
pub const READ_EEPROM: IspCommand = (0xa0, 0x00, 0x00, 0x00);
pub const READ_LOW_FUSE: IspCommand = (0x50, 0x00, 0x00, 0x00);
pub const READ_HIGH_FUSE: IspCommand = (0x58, 0x08, 0x00, 0x00);
pub const READ_EXTENDED_FUSE: IspCommand = (0x50, 0x08, 0x00, 0x00);
pub const READ_LOCK: IspCommand = (0x58, 0x00, 0x00, 0x00);
pub const READ_OSCCAL: IspCommand = (0x38, 0x00, 0x00, 0x00);
pub const LOAD_EXTENDED_ADDRESS: IspCommand = (0x4d, 0x00, 0x00, 0x00);
pub const LOAD_FLASH_PAGE_HIGH: IspCommand = (0x48, 0x00, 0x00, 0x00);
pub const LOAD_FLASH_PAGE_LOW: IspCommand = (0x40, 0x00, 0x00, 0x00);
pub const LOAD_EEPROM_PAGE: IspCommand = (0xc1, 0x00, 0x00, 0x00);
pub const WRITE_FLASH: IspCommand = (0x4c, 0x00, 0x00, 0x00);
pub const WRITE_EEPROM: IspCommand = (0xc0, 0x00, 0x00, 0x00);
pub const WRITE_EEPROM_PAGE: IspCommand = (0xc2, 0x00, 0x00, 0x00);
pub const WRITE_LOW_FUSE: IspCommand = (0xac, 0xa0, 0x00, 0x00);
pub const WRITE_HIGH_FUSE: IspCommand = (0xac, 0xa8, 0x00, 0x00);
pub const WRITE_EXTENDED_FUSE: IspCommand = (0xac, 0xa4, 0x00, 0x00);
pub const WRITE_LOCK: IspCommand = (0xac, 0xe0, 0x00, 0x00);

/// AVR MCU signature.
pub struct Signature {
    pub bytes: (u8, u8, u8),
}

impl From<[u8; 3]> for Signature {
    fn from(bytes: [u8; 3]) -> Signature {
        Signature {
            bytes: (bytes[0], bytes[1], bytes[2]),
        }
    }
}

impl From<(u8, u8, u8)> for Signature {
    fn from(tup: (u8, u8, u8)) -> Signature {
        Signature { bytes: tup }
    }
}

/// Memory segment e.g. EEPROM, flash.
#[allow(dead_code)]
pub struct Memory {
    pub start: usize, // Start address of a given memory section. Given in XML in address-spaces section
    pub size: usize,  // Total number of bytes. Given in XML in address-spaces section
    pub page_size: usize, // Page size in bytes. Given in XML in address-spaces section
    pub block_size: usize, // XML: IspProgramFlash_blockSize as number of 16 bit words
    pub mode: usize,
    pub delay: usize,
    cmd: (u8, u8, u8),
    poll: (u8, u8),
}

/// Parameters used for programming MCU.
///
/// Can be obtained from atdf files found in atpack on http://packs.download.atmel.com/
pub struct Params {
    pub timeout: u8,
    pub stab_delay: u8,
    pub cmd_exe_delay: u8,
    pub synch_loops: u8,
    pub byte_delay: u8,
    pub poll_value: u8,
    pub poll_index: u8,
    pub pre_delay: u8,
    pub post_delay: u8,
    pub reset_polarity: bool,
    pub erase_poll_method: u8,
    pub erase_delay: u8,
    pub signature: Signature,
    pub fuse_poll_index: u8,
    pub lock_poll_index: u8,
    pub osccal_poll_index: u8,
    pub signature_poll_index: u8,
    pub flash: Memory,
    pub eeprom: Memory,
}

/// MCU specs used for programming.
///
/// Can be obtained from atdf files found in atpack on http://packs.download.atmel.com/
pub struct Specs {
    pub timeout: u8,
    pub stab_delay: u8,
    pub cmd_exe_delay: u8,
    pub synch_loops: u8,
    pub byte_delay: u8,
    pub pool_value: u8,
    pub pool_index: u8,
    pub pre_delay: u8,
    pub post_delay: u8,
    pub reset_polarity: bool,
    pub erase_poll_method: u8,
    pub erase_delay: u8,
    pub signature: Signature,
    pub fuse_poll_index: u8,
    pub lock_poll_index: u8,
    pub osccal_poll_index: u8,
    pub signature_poll_index: u8,
    pub flash: Memory,
    pub eeprom: Memory,
}

#[cfg(test)]
mod tests {
    use super::Signature;

    #[test]
    fn signature_from_array_trait() {
        let sign = Signature::from([1, 2, 3]);
        assert_eq!(sign.bytes.0, 1);
        assert_eq!(sign.bytes.1, 2);
        assert_eq!(sign.bytes.2, 3);
    }

    #[test]
    fn signature_from_tuple_trait() {
        let sign = Signature::from((1, 2, 3));
        assert_eq!(sign.bytes.0, 1);
        assert_eq!(sign.bytes.1, 2);
        assert_eq!(sign.bytes.2, 3);
    }
}