1#![doc = include_str!("../README.md")]
2#![no_std]
3#![warn(missing_docs)]
4
5#[macro_use]
6mod macros;
7mod crc;
8pub mod error;
9pub mod gpio;
10mod hif;
11#[doc(hidden)]
12pub mod registers;
13pub mod socket;
14#[doc(hidden)]
15pub mod spi;
16pub mod types;
17pub mod wifi;
18
19use embedded_hal::blocking::{delay::DelayMs, spi::Transfer};
20use embedded_hal::digital::v2::{InputPin, OutputPin};
21use embedded_nal::{SocketAddr, TcpClientStack, TcpFullStack};
22
23use error::Error;
24use gpio::{AtwincGpio, GpioDirection, GpioValue};
25use hif::{commands, group_ids, HifHeader, HostInterface};
26use socket::TcpSocket;
27use spi::SpiBus;
28use types::{FirmwareVersion, MacAddress};
29use wifi::{ConnectionParameters, OldConnection};
30
31pub struct Atwinc1500<SPI, D, O, I>
33where
34 SPI: Transfer<u8>,
35 D: DelayMs<u32>,
36 O: OutputPin,
37 I: InputPin,
38{
39 delay: D,
40 spi_bus: SpiBus<SPI, O>,
41 hif: HostInterface,
42 _irq: I,
43 reset: O,
44 wake: O,
45 crc: bool,
46}
47
48impl<SPI, D, O, I> Atwinc1500<SPI, D, O, I>
51where
52 SPI: Transfer<u8>,
53 D: DelayMs<u32>,
54 O: OutputPin,
55 I: InputPin,
56{
57 pub fn new(
76 spi: SPI,
77 delay: D,
78 cs: O,
79 _irq: I,
80 reset: O,
81 wake: O,
82 crc: bool,
83 ) -> Result<Self, Error> {
84 let mut s = Self {
85 delay,
86 spi_bus: SpiBus::new(spi, cs, crc),
87 hif: HostInterface {},
88 _irq,
89 reset,
90 wake,
91 crc,
92 };
93 s.initialize()?;
94 Ok(s)
95 }
96
97 fn initialize(&mut self) -> Result<(), Error> {
105 const FINISH_BOOT_VAL: u32 = 0x10add09e;
106 const DRIVER_VER_INFO: u32 = 0x13521330;
107 const CONF_VAL: u32 = 0x102;
108 const START_FIRMWARE: u32 = 0xef522f61;
109 const FINISH_INIT_VAL: u32 = 0x02532636;
110 self.init_pins()?;
111 self.disable_crc()?;
112 let mut efuse_value: u32 = 0;
113 retry_while!((efuse_value & 0x80000000) == 0, retries = 10, {
114 efuse_value = self.spi_bus.read_register(registers::EFUSE_REG)?;
115 self.delay.delay_ms(1000);
116 });
117 let wait: u32 = self
118 .spi_bus
119 .read_register(registers::M2M_WAIT_FOR_HOST_REG)?;
120 if (wait & 1) == 0 {
121 let mut bootrom: u32 = 0;
122 retry_while!(bootrom != FINISH_BOOT_VAL, retries = 3, {
123 bootrom = self.spi_bus.read_register(registers::BOOTROM_REG)?;
124 self.delay.delay_ms(1000);
125 });
126 }
127 self.spi_bus
128 .write_register(registers::NMI_STATE_REG, DRIVER_VER_INFO)?;
129 self.spi_bus
130 .write_register(registers::rNMI_GP_REG_1, CONF_VAL)?;
131 self.spi_bus
132 .write_register(registers::BOOTROM_REG, START_FIRMWARE)?;
133 let mut state: u32 = 0;
134 retry_while!(state != FINISH_INIT_VAL, retries = 20, {
135 state = self.spi_bus.read_register(registers::NMI_STATE_REG)?;
136 self.delay.delay_ms(1000);
137 });
138 self.spi_bus.write_register(registers::NMI_STATE_REG, 0)?;
139 self.enable_chip_interrupt()?;
140 Ok(())
141 }
142
143 fn init_pins(&mut self) -> Result<(), Error> {
147 self.spi_bus.init_cs()?;
148 if self.wake.set_high().is_err() {
149 return Err(Error::PinStateError);
150 }
151 if self.reset.set_low().is_err() {
152 return Err(Error::PinStateError);
153 }
154 self.delay.delay_ms(1000);
155 if self.reset.set_high().is_err() {
156 return Err(Error::PinStateError);
157 }
158 self.delay.delay_ms(1000);
159 Ok(())
160 }
161
162 fn disable_crc(&mut self) -> Result<(), Error> {
164 if !self.crc {
165 self.spi_bus
166 .write_register(registers::NMI_SPI_PROTOCOL_CONFIG, 0x52)?;
167 self.spi_bus.crc_disabled()?;
168 }
169 Ok(())
170 }
171
172 fn enable_chip_interrupt(&mut self) -> Result<(), Error> {
173 let mux: u32 = self.spi_bus.read_register(registers::NMI_PIN_MUX_0)?;
174 self.spi_bus
175 .write_register(registers::NMI_PIN_MUX_0, mux | 0x100)?;
176 let base: u32 = self.spi_bus.read_register(registers::NMI_INTR_REG_BASE)?;
177 self.spi_bus
178 .write_register(registers::NMI_INTR_REG_BASE, base | 0x10000)?;
179 Ok(())
180 }
181
182 pub fn get_firmware_version(&mut self) -> Result<FirmwareVersion, Error> {
185 let mut reg_value = self.spi_bus.read_register(registers::NMI_REV_REG)?;
186 if reg_value == registers::M2M_ATE_FW_IS_UP_VALUE {
187 reg_value = self.spi_bus.read_register(registers::NMI_REV_REG_ATE)?;
188 }
189 Ok(FirmwareVersion([
190 ((reg_value >> 8) & 0xff) as u8, ((reg_value >> 4) & 0x0f) as u8, (reg_value & 0x0f) as u8, ]))
194 }
195
196 pub fn get_otp_mac_address(&mut self) -> Result<MacAddress, Error> {
199 todo!()
200 }
201
202 pub fn get_mac_address(&mut self) -> Result<MacAddress, Error> {
205 const MAC_SIZE: usize = 6;
206 const DATA_SIZE: usize = 8;
207 let mut mac: MacAddress = MacAddress([0; MAC_SIZE]);
208 let mut data: [u8; DATA_SIZE] = [0; DATA_SIZE];
209 let mut reg_value = self.spi_bus.read_register(registers::rNMI_GP_REG_2)?;
210 reg_value |= 0x30000;
211 self.spi_bus
212 .read_data(&mut data, reg_value, DATA_SIZE as u32)?;
213 reg_value = combine_bytes_lsb!(data[0..4]);
214 reg_value &= 0x0000ffff;
215 reg_value |= 0x30000;
216 self.spi_bus
217 .read_data(&mut mac.0, reg_value, MAC_SIZE as u32)?;
218 Ok(mac)
219 }
220
221 pub fn set_gpio_direction(
224 &mut self,
225 gpio: AtwincGpio,
226 direction: GpioDirection,
227 ) -> Result<(), Error> {
228 const GPIO_DIR_REG: u32 = 0x20108;
229 let mut value = self.spi_bus.read_register(GPIO_DIR_REG)?;
230 if direction == GpioDirection::Output {
231 value |= 1 << gpio as u8;
232 } else {
233 value &= !(1 << gpio as u8);
234 }
235 self.spi_bus.write_register(GPIO_DIR_REG, value)
236 }
237
238 pub fn set_gpio_value(&mut self, gpio: AtwincGpio, value: GpioValue) -> Result<(), Error> {
241 const GPIO_VAL_REG: u32 = 0x20100;
242 let mut response = self.spi_bus.read_register(GPIO_VAL_REG)?;
243 if value == GpioValue::Low {
244 response |= 1 << gpio as u8;
245 } else {
246 response &= !(1 << gpio as u8);
247 }
248 self.spi_bus.write_register(GPIO_VAL_REG, response)
249 }
250
251 pub fn get_gpio_direction(&mut self, gpio: AtwincGpio) -> Result<GpioDirection, Error> {
254 const GPIO_GET_DIR_REG: u32 = 0x20104;
255 match self.spi_bus.read_register(GPIO_GET_DIR_REG) {
256 Ok(v) => Ok(GpioDirection::from(((v >> gpio as u8) & 0x01) as u8)),
257 Err(e) => Err(e),
258 }
259 }
260
261 pub fn connect_network(&mut self, connection: ConnectionParameters) -> Result<(), Error> {
264 let mut conn_header: OldConnection = connection.into();
265 let hif_header = HifHeader::new(
266 group_ids::WIFI,
267 commands::wifi::REQ_CONNECT,
268 conn_header.len() as u16,
269 );
270 self.hif
271 .send(&mut self.spi_bus, hif_header, &mut conn_header, &mut [])?;
272 Ok(())
273 }
274
275 pub fn disconnect_network(&mut self) -> Result<(), Error> {
277 let hif_header = HifHeader::new(group_ids::WIFI, commands::wifi::REQ_DISCONNECT, 0);
278 self.hif
279 .send(&mut self.spi_bus, hif_header, &mut [], &mut [])?;
280 Ok(())
281 }
282
283 pub fn connect_default_network(&mut self) -> Result<(), Error> {
285 let hif_header = HifHeader::new(group_ids::WIFI, commands::wifi::REQ_DEFAULT_CONNECT, 0);
286 self.hif
287 .send(&mut self.spi_bus, hif_header, &mut [], &mut [])?;
288 Ok(())
289 }
290}
291
292impl<SPI, D, O, I> TcpClientStack for Atwinc1500<SPI, D, O, I>
293where
294 SPI: Transfer<u8>,
295 D: DelayMs<u32>,
296 O: OutputPin,
297 I: InputPin,
298{
299 type TcpSocket = TcpSocket;
300 type Error = Error;
301
302 fn socket(&mut self) -> Result<TcpSocket, Error> {
303 todo!()
304 }
305
306 fn connect(
307 &mut self,
308 _socket: &mut TcpSocket,
309 _address: SocketAddr,
310 ) -> Result<(), embedded_nal::nb::Error<Error>> {
311 todo!()
312 }
313
314 fn is_connected(&mut self, _socket: &TcpSocket) -> Result<bool, Error> {
315 todo!()
316 }
317
318 fn send(
319 &mut self,
320 _socket: &mut TcpSocket,
321 _data: &[u8],
322 ) -> Result<usize, embedded_nal::nb::Error<Error>> {
323 todo!()
324 }
325
326 fn receive(
327 &mut self,
328 _socket: &mut TcpSocket,
329 _data: &mut [u8],
330 ) -> Result<usize, embedded_nal::nb::Error<Error>> {
331 todo!()
332 }
333
334 fn close(&mut self, _socket: TcpSocket) -> Result<(), Error> {
335 todo!()
336 }
337}
338
339impl<SPI, D, O, I> TcpFullStack for Atwinc1500<SPI, D, O, I>
340where
341 SPI: Transfer<u8>,
342 D: DelayMs<u32>,
343 O: OutputPin,
344 I: InputPin,
345{
346 fn bind(&mut self, _socket: &mut TcpSocket, _port: u16) -> Result<(), Error> {
347 todo!()
348 }
349
350 fn listen(&mut self, _socket: &mut TcpSocket) -> Result<(), Error> {
351 todo!()
352 }
353
354 fn accept(
355 &mut self,
356 _socket: &mut TcpSocket,
357 ) -> Result<(TcpSocket, SocketAddr), embedded_nal::nb::Error<Error>> {
358 todo!()
359 }
360}