enc28j60.rs.disabled 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. //! ENC28J60 demo: pong server + UDP echo server
  2. //!
  3. //! This program:
  4. //!
  5. //! - Responds to ARP requests
  6. //! - Responds to ICMP echo requests, thus you can `ping` the device
  7. //! - Responds to *all* UDP datagrams by sending them back
  8. //!
  9. //! You can test this program by running the following commands:
  10. //!
  11. //! - `ping 192.168.1.33`. The device should respond and toggle the state of the LED on every `ping`
  12. //! request.
  13. //! - `nc -u 192.168.1.33 1337` and sending any string. The device should respond back by sending
  14. //! back the received string; the LED will toggle each time a UDP datagram is sent.
  15. #![deny(unsafe_code)]
  16. #![deny(warnings)]
  17. #![feature(nll)]
  18. #![no_std]
  19. #![no_main]
  20. extern crate cortex_m_rt as rt;
  21. #[macro_use]
  22. extern crate cortex_m;
  23. extern crate enc28j60;
  24. extern crate heapless;
  25. extern crate jnet;
  26. extern crate panic_itm;
  27. extern crate stm32f1xx_hal as hal;
  28. use enc28j60::Enc28j60;
  29. use hal::delay::Delay;
  30. use hal::prelude::*;
  31. use hal::spi::Spi;
  32. use hal::stm32f103xx;
  33. use heapless::consts::*;
  34. use heapless::FnvIndexMap;
  35. use jnet::{arp, ether, icmp, ipv4, mac, udp, Buffer};
  36. use rt::{entry, exception, ExceptionFrame};
  37. // uncomment to disable tracing
  38. // macro_rules! iprintln {
  39. // ($($tt: tt)*) => {};
  40. // }
  41. /* Configuration */
  42. const MAC: mac::Addr = mac::Addr([0x20, 0x18, 0x03, 0x01, 0x00, 0x00]);
  43. const IP: ipv4::Addr = ipv4::Addr([192, 168, 1, 33]);
  44. /* Constants */
  45. const KB: u16 = 1024; // bytes
  46. #[entry]
  47. fn main() -> ! {
  48. let mut cp = cortex_m::Peripherals::take().unwrap();
  49. let dp = stm32f103xx::Peripherals::take().unwrap();
  50. let mut rcc = dp.RCC.constrain();
  51. let mut afio = dp.AFIO.constrain(&mut rcc.apb2);
  52. let mut flash = dp.FLASH.constrain();
  53. let mut gpioa = dp.GPIOA.split(&mut rcc.apb2);
  54. let _stim = &mut cp.ITM.stim[0];
  55. let clocks = rcc.cfgr.freeze(&mut flash.acr);
  56. cp.DWT.enable_cycle_counter();
  57. // LED
  58. let mut gpioc = dp.GPIOC.split(&mut rcc.apb2);
  59. let mut led = gpioc.pc13.into_push_pull_output(&mut gpioc.crh);
  60. // turn the LED off during initialization
  61. led.set_high();
  62. // SPI
  63. let mut ncs = gpioa.pa4.into_push_pull_output(&mut gpioa.crl);
  64. ncs.set_high();
  65. let sck = gpioa.pa5.into_alternate_push_pull(&mut gpioa.crl);
  66. let miso = gpioa.pa6;
  67. let mosi = gpioa.pa7.into_alternate_push_pull(&mut gpioa.crl);
  68. let spi = Spi::spi1(
  69. dp.SPI1,
  70. (sck, miso, mosi),
  71. &mut afio.mapr,
  72. enc28j60::MODE,
  73. 1.mhz(),
  74. clocks,
  75. &mut rcc.apb2,
  76. );
  77. // ENC28J60
  78. let mut reset = gpioa.pa3.into_push_pull_output(&mut gpioa.crl);
  79. reset.set_high();
  80. let mut delay = Delay::new(cp.SYST, clocks);
  81. let mut enc28j60 = Enc28j60::new(
  82. spi,
  83. ncs,
  84. enc28j60::Unconnected,
  85. reset,
  86. &mut delay,
  87. 7 * KB,
  88. MAC.0,
  89. )
  90. .ok()
  91. .unwrap();
  92. // LED on after initialization
  93. led.set_low();
  94. // FIXME some frames are lost when sent right after initialization
  95. delay.delay_ms(100_u8);
  96. // ARP cache
  97. let mut cache = FnvIndexMap::<_, _, U8>::new();
  98. let mut buf = [0; 256];
  99. loop {
  100. let mut buf = Buffer::new(&mut buf);
  101. let len = enc28j60.receive(buf.as_mut()).ok().unwrap();
  102. buf.truncate(len);
  103. if let Ok(mut eth) = ether::Frame::parse(buf) {
  104. iprintln!(_stim, "\nRx({})", eth.as_bytes().len());
  105. iprintln!(_stim, "* {:?}", eth);
  106. let src_mac = eth.get_source();
  107. match eth.get_type() {
  108. ether::Type::Arp => {
  109. if let Ok(arp) = arp::Packet::parse(eth.payload_mut()) {
  110. match arp.downcast() {
  111. Ok(mut arp) => {
  112. iprintln!(_stim, "** {:?}", arp);
  113. if !arp.is_a_probe() {
  114. cache.insert(arp.get_spa(), arp.get_sha()).ok();
  115. }
  116. // are they asking for us?
  117. if arp.get_oper() == arp::Operation::Request && arp.get_tpa() == IP
  118. {
  119. // reply to the ARP request
  120. let tha = arp.get_sha();
  121. let tpa = arp.get_spa();
  122. arp.set_oper(arp::Operation::Reply);
  123. arp.set_sha(MAC);
  124. arp.set_spa(IP);
  125. arp.set_tha(tha);
  126. arp.set_tpa(tpa);
  127. iprintln!(_stim, "\n** {:?}", arp);
  128. let arp_len = arp.len();
  129. // update the Ethernet header
  130. eth.set_destination(tha);
  131. eth.set_source(MAC);
  132. eth.truncate(arp_len);
  133. iprintln!(_stim, "* {:?}", eth);
  134. iprintln!(_stim, "Tx({})", eth.as_bytes().len());
  135. enc28j60.transmit(eth.as_bytes()).ok().unwrap();
  136. }
  137. }
  138. Err(_arp) => {
  139. // Not a Ethernet/IPv4 ARP packet
  140. iprintln!(_stim, "** {:?}", _arp);
  141. }
  142. }
  143. } else {
  144. // malformed ARP packet
  145. iprintln!(_stim, "Err(A)");
  146. }
  147. }
  148. ether::Type::Ipv4 => {
  149. if let Ok(mut ip) = ipv4::Packet::parse(eth.payload_mut()) {
  150. iprintln!(_stim, "** {:?}", ip);
  151. let src_ip = ip.get_source();
  152. if !src_mac.is_broadcast() {
  153. cache.insert(src_ip, src_mac).ok();
  154. }
  155. match ip.get_protocol() {
  156. ipv4::Protocol::Icmp => {
  157. if let Ok(icmp) = icmp::Packet::parse(ip.payload_mut()) {
  158. match icmp.downcast::<icmp::EchoRequest>() {
  159. Ok(request) => {
  160. // is an echo request
  161. iprintln!(_stim, "*** {:?}", request);
  162. let src_mac = cache
  163. .get(&src_ip)
  164. .unwrap_or_else(|| unimplemented!());
  165. let _reply: icmp::Packet<_, icmp::EchoReply, _> =
  166. request.into();
  167. iprintln!(_stim, "\n*** {:?}", _reply);
  168. // update the IP header
  169. let mut ip = ip.set_source(IP);
  170. ip.set_destination(src_ip);
  171. let _ip = ip.update_checksum();
  172. iprintln!(_stim, "** {:?}", _ip);
  173. // update the Ethernet header
  174. eth.set_destination(*src_mac);
  175. eth.set_source(MAC);
  176. iprintln!(_stim, "* {:?}", eth);
  177. led.toggle();
  178. iprintln!(_stim, "Tx({})", eth.as_bytes().len());
  179. enc28j60.transmit(eth.as_bytes()).ok().unwrap();
  180. }
  181. Err(_icmp) => {
  182. iprintln!(_stim, "*** {:?}", _icmp);
  183. }
  184. }
  185. } else {
  186. // Malformed ICMP packet
  187. iprintln!(_stim, "Err(B)");
  188. }
  189. }
  190. ipv4::Protocol::Udp => {
  191. if let Ok(mut udp) = udp::Packet::parse(ip.payload_mut()) {
  192. iprintln!(_stim, "*** {:?}", udp);
  193. if let Some(src_mac) = cache.get(&src_ip) {
  194. let src_port = udp.get_source();
  195. let dst_port = udp.get_destination();
  196. // update the UDP header
  197. udp.set_source(dst_port);
  198. udp.set_destination(src_port);
  199. udp.zero_checksum();
  200. iprintln!(_stim, "\n*** {:?}", udp);
  201. // update the IP header
  202. let mut ip = ip.set_source(IP);
  203. ip.set_destination(src_ip);
  204. let ip = ip.update_checksum();
  205. let ip_len = ip.len();
  206. iprintln!(_stim, "** {:?}", ip);
  207. // update the Ethernet header
  208. eth.set_destination(*src_mac);
  209. eth.set_source(MAC);
  210. eth.truncate(ip_len);
  211. iprintln!(_stim, "* {:?}", eth);
  212. led.toggle();
  213. iprintln!(_stim, "Tx({})", eth.as_bytes().len());
  214. enc28j60.transmit(eth.as_bytes()).ok().unwrap();
  215. }
  216. } else {
  217. // malformed UDP packet
  218. iprintln!(_stim, "Err(C)");
  219. }
  220. }
  221. _ => {}
  222. }
  223. } else {
  224. // malformed IPv4 packet
  225. iprintln!(_stim, "Err(D)");
  226. }
  227. }
  228. _ => {}
  229. }
  230. } else {
  231. // malformed Ethernet frame
  232. iprintln!(_stim, "Err(E)");
  233. }
  234. }
  235. }
  236. #[exception]
  237. fn HardFault(ef: &ExceptionFrame) -> ! {
  238. panic!("{:#?}", ef);
  239. }
  240. #[exception]
  241. fn DefaultHandler(irqn: i16) {
  242. panic!("Unhandled exception (IRQn = {})", irqn);
  243. }