1#![no_std]
2
3extern crate bitflags;
4extern crate byteorder;
5extern crate embedded_hal as hal;
6
7use byteorder::{ByteOrder, LittleEndian};
8use hal::blocking::i2c;
9
10pub mod pdo;
11pub mod rdo;
12pub mod registers;
13
14use pdo::*;
15use rdo::*;
16use registers::*;
17
18pub const STUSB4500_ADDR: u8 = 0x28;
19
20pub enum Address {
22 Default,
24 Strap(bool, bool),
26 Custom(u8),
28}
29
30impl Address {
31 pub(crate) fn addr(&self) -> u8 {
32 match self {
33 Address::Default => STUSB4500_ADDR,
34 Address::Strap(a1, a0) => STUSB4500_ADDR | (*a1 as u8) << 1 | (*a0 as u8) << 0,
35 Address::Custom(addr) => *addr,
36 }
37 }
38}
39
40impl Default for Address {
41 fn default() -> Self {
42 Address::Default
43 }
44}
45
46#[derive(Debug)]
47pub enum Error<I2C> {
48 I2CError(I2C),
49 InvalidPdo,
50 OutaRangePdo,
51}
52
53pub enum PdoChannel {
54 PDO1,
55 PDO2,
56 PDO3,
57}
58
59pub struct STUSB4500<I2C> {
60 i2c: I2C,
61 address: u8,
62}
63
64impl<I2C, E> STUSB4500<I2C>
65where
66 I2C: i2c::Write<Error = E> + i2c::Read<Error = E>,
67{
68 pub fn new(i2c: I2C, address: Address) -> Self {
69 STUSB4500 {
70 i2c,
71 address: address.addr(),
72 }
73 }
74
75 pub fn clear_interrupts(&mut self) -> Result<(), Error<E>> {
77 let mut _buf = [0x00; 10];
79 self.i2c
80 .write(self.address, &[Register::PortStatus0 as u8])
81 .map_err(|err| Error::I2CError(err))?;
82 self.i2c
83 .read(self.address, &mut _buf)
84 .map_err(|err| Error::I2CError(err))
85 }
86
87 pub fn set_alerts_mask(&mut self, alerts: AlertMask) -> Result<(), Error<E>> {
89 self.write(Register::AlertStatus1Mask, alerts.bits())
90 }
91
92 pub fn get_alerts(&mut self) -> Result<Alert, Error<E>> {
94 Ok(Alert::from_bits_truncate(
95 self.read(Register::AlertStatus1)?,
96 ))
97 }
98
99 pub fn soft_reset(&mut self) -> Result<(), Error<E>> {
102 self.write(Register::TXHeaderL, 0x0D)?;
103 self.write(Register::PDCommandCtrl, 0x26)?;
104 Ok(())
105 }
106
107 pub fn set_pdo(&mut self, pdo: PdoChannel, data: &Pdo) -> Result<(), Error<E>> {
108 if let Pdo::Fixed { .. } = data {
109 self.write_word(
110 match pdo {
111 PdoChannel::PDO1 => Register::DPMSNKPDO1,
112 PdoChannel::PDO2 => Register::DPMSNKPDO2,
113 PdoChannel::PDO3 => Register::DPMSNKPDO3,
114 },
115 data.bits(),
116 )
117 } else {
118 Err(Error::InvalidPdo)
120 }
121 }
122
123 pub fn get_pdo(&mut self, pdo: PdoChannel) -> Result<Pdo, Error<E>> {
124 Pdo::from_bits(self.read_word(match pdo {
125 PdoChannel::PDO1 => Register::DPMSNKPDO1,
126 PdoChannel::PDO2 => Register::DPMSNKPDO2,
127 PdoChannel::PDO3 => Register::DPMSNKPDO3,
128 })?)
129 .ok_or(Error::InvalidPdo)
130 }
131
132 pub fn get_current_rdo(&mut self) -> Result<Rdo, Error<E>> {
133 Ok(Rdo(self.read_word(Register::RDORegStatus)?))
134 }
135
136 pub fn set_num_pdo(&mut self, num: u8) -> Result<(), Error<E>> {
137 match num {
138 1..=3 => self.write(Register::DPMPDONumb, num),
139 _ => Err(Error::OutaRangePdo),
140 }
141 }
142
143 pub fn unlock_nvm(&mut self) -> Result<STUSB4500Nvm<I2C>, Error<E>> {
145 STUSB4500Nvm::unlock(self)
146 }
147
148 pub(crate) fn write(&mut self, register: Register, value: u8) -> Result<(), Error<E>> {
153 let buf = [register as u8, value];
154 self.i2c
155 .write(self.address, &buf)
156 .map_err(|err| Error::I2CError(err))
157 }
158
159 pub(crate) fn write_word(&mut self, register: Register, word: u32) -> Result<(), Error<E>> {
161 let mut buf = [0x00; 5];
162 buf[0] = register as u8;
163 LittleEndian::write_u32(&mut buf[1..], word);
164 self.i2c
165 .write(self.address, &buf)
166 .map_err(|err| Error::I2CError(err))
167 }
168
169 pub(crate) fn read(&mut self, register: Register) -> Result<u8, Error<E>> {
171 let mut buf = [0x00; 1];
172 self.i2c
173 .write(self.address, &[register as u8])
174 .map_err(|err| Error::I2CError(err))?;
175 self.i2c
176 .read(self.address, &mut buf)
177 .map_err(|err| Error::I2CError(err))?;
178 Ok(buf[0])
179 }
180
181 pub(crate) fn read_word(&mut self, register: Register) -> Result<u32, Error<E>> {
183 let mut buf = [0x00; 4];
184 self.i2c
185 .write(self.address, &[register as u8])
186 .map_err(|err| Error::I2CError(err))?;
187 self.i2c
188 .read(self.address, &mut buf)
189 .map_err(|err| Error::I2CError(err))?;
190 Ok(LittleEndian::read_u32(&buf))
191 }
192}
193
194pub struct STUSB4500Nvm<'a, I2C> {
195 inner: &'a mut STUSB4500<I2C>,
196}
197
198impl<I2C, E> STUSB4500Nvm<'_, I2C>
199where
200 I2C: i2c::Write<Error = E> + i2c::Read<Error = E>,
201{
202 const DEFAULT_PASSWORD: u8 = 0x47;
203
204 pub(crate) fn unlock(inner: &mut STUSB4500<I2C>) -> Result<STUSB4500Nvm<I2C>, Error<E>> {
205 inner.write(Register::NvmPassword, STUSB4500Nvm::<I2C>::DEFAULT_PASSWORD)?;
206 inner.write(Register::NvmCtrl0, 0x00)?;
207 inner.write(
208 Register::NvmCtrl0,
209 (NvmCtrl0::Power | NvmCtrl0::Enable).bits(),
210 )?;
211
212 Ok(STUSB4500Nvm { inner })
213 }
214
215 pub fn lock(self) -> Result<(), Error<E>> {
217 self.inner
218 .write(Register::NvmCtrl0, NvmCtrl0::Enable.bits())?;
219 self.inner.write(Register::NvmCtrl1, 0x00)?;
220 self.inner.write(Register::NvmPassword, 0x00)
221 }
222
223 pub fn read_sectors(&mut self) -> Result<[[u8; 8]; 5], Error<E>> {
230 let mut buf = [[0x00; 8]; 5];
231 for (i, sector) in buf.iter_mut().enumerate() {
232 *sector = self.read_sector(i as u8)?;
233 }
234 Ok(buf)
235 }
236
237 pub fn write_sectors(&mut self, sectors: [[u8; 8]; 5]) -> Result<(), Error<E>> {
244 self.erase_sectors()?;
245 for (i, sector) in sectors.iter().enumerate() {
246 self.write_sector(i as u8, sector)?;
247 }
248 Ok(())
249 }
250
251 fn issue_request(&mut self) -> Result<(), Error<E>> {
252 self.issue_request_with_sector(0)
253 }
254
255 fn issue_request_with_sector(&mut self, sector: u8) -> Result<(), Error<E>> {
256 self.inner.write(
257 Register::NvmCtrl0,
258 sector | (NvmCtrl0::Power | NvmCtrl0::Enable | NvmCtrl0::Request).bits(),
259 )?;
260
261 while NvmCtrl0::from_bits_truncate(self.inner.read(Register::NvmCtrl0)?)
262 .contains(NvmCtrl0::Request)
263 {}
264
265 Ok(())
266 }
267
268 fn read_sector(&mut self, sector: u8) -> Result<[u8; 8], Error<E>> {
269 self.inner
270 .write(Register::NvmCtrl1, NvmCtrl1Opcode::ReadSector as u8)?;
271 self.issue_request_with_sector(sector)?;
272
273 let mut buf = [0x00; 8];
274 self.inner
275 .i2c
276 .write(self.inner.address, &[Register::RWBuffer as u8])
277 .map_err(|err| Error::I2CError(err))?;
278 self.inner
279 .i2c
280 .read(self.inner.address, &mut buf)
281 .map_err(|err| Error::I2CError(err))?;
282 Ok(buf)
283 }
284
285 fn write_sector(&mut self, sector: u8, data: &[u8; 8]) -> Result<(), Error<E>> {
286 let mut buf = [0x00; 9];
287 buf[0] = Register::RWBuffer as u8;
288 buf[1..].copy_from_slice(data);
289
290 self.inner
291 .i2c
292 .write(self.inner.address, &buf)
293 .map_err(|err| Error::I2CError(err))?;
294 self.inner
295 .write(Register::NvmCtrl1, NvmCtrl1Opcode::LoadPlr as u8)?;
296 self.issue_request()?;
297
298 self.inner
299 .write(Register::NvmCtrl1, NvmCtrl1Opcode::WriteSector as u8)?;
300 self.issue_request_with_sector(sector)
301 }
302
303 fn erase_sectors(&mut self) -> Result<(), Error<E>> {
304 self.inner.write(
305 Register::NvmCtrl1,
306 NvmCtrl1Opcode::LoadSer as u8
307 | (NvmCtrl1::EraseSector0
308 | NvmCtrl1::EraseSector1
309 | NvmCtrl1::EraseSector2
310 | NvmCtrl1::EraseSector3
311 | NvmCtrl1::EraseSector4)
312 .bits(),
313 )?;
314 self.issue_request()?;
315
316 self.inner
317 .write(Register::NvmCtrl1, NvmCtrl1Opcode::EraseSectors as u8)?;
318 self.issue_request()
319 }
320}