Advertisement
Guest User

Untitled

a guest
Jul 30th, 2023
161
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Rust 8.39 KB | None | 0 0
  1. My Code:
  2. ```
  3. #![no_std]
  4. #![no_main]
  5.  
  6. extern crate alloc;
  7.  
  8. use core::ops::Range;
  9. use esp_backtrace as _;
  10. use esp_println::println;
  11. use hal::i2c::Error;
  12. use hal::xtensa_lx::timer::delay;
  13. use hal::{
  14.     clock::ClockControl, i2c::I2C, peripherals::Peripherals, prelude::*, timer::TimerGroup, Delay,
  15.     Rtc, IO,
  16. };
  17.  
  18. #[global_allocator]
  19. static ALLOCATOR: esp_alloc::EspHeap = esp_alloc::EspHeap::empty();
  20.  
  21. fn init_heap() {
  22.     const HEAP_SIZE: usize = 32 * 1024;
  23.  
  24.     extern "C" {
  25.         static mut _heap_start: u32;
  26.         static mut _heap_end: u32;
  27.     }
  28.  
  29.     unsafe {
  30.         let heap_start = &_heap_start as *const _ as usize;
  31.         let heap_end = &_heap_end as *const _ as usize;
  32.         assert!(
  33.             heap_end - heap_start > HEAP_SIZE,
  34.             "Not enough available heap memory."
  35.         );
  36.         ALLOCATOR.init(heap_start as *mut u8, HEAP_SIZE);
  37.     }
  38. }
  39.  
  40. const VALID_ADDR_RANGE: Range<u8> = 0x08..0x78;
  41.  
  42. #[entry]
  43. fn main() -> ! {
  44.     init_heap();
  45.     let peripherals = Peripherals::take();
  46.     let mut system = peripherals.DPORT.split();
  47.     let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
  48.  
  49.     // Disable the RTC and TIMG watchdog timers
  50.     let mut rtc = Rtc::new(peripherals.RTC_CNTL);
  51.     let timer_group0 = TimerGroup::new(
  52.         peripherals.TIMG0,
  53.         &clocks,
  54.         &mut system.peripheral_clock_control,
  55.     );
  56.     let mut wdt0 = timer_group0.wdt;
  57.     let timer_group1 = TimerGroup::new(
  58.         peripherals.TIMG1,
  59.         &clocks,
  60.         &mut system.peripheral_clock_control,
  61.     );
  62.     let mut wdt1 = timer_group1.wdt;
  63.     rtc.rwdt.disable();
  64.     wdt0.disable();
  65.     wdt1.disable();
  66.  
  67.     let io = IO::new(peripherals.GPIO, peripherals.IO_MUX);
  68.  
  69.     let mut i2c = I2C::new(
  70.         peripherals.I2C0,
  71.         io.pins.gpio21,
  72.         io.pins.gpio22,
  73.         400u32.kHz(),
  74.         &mut system.peripheral_clock_control,
  75.         &clocks,
  76.     );
  77.  
  78.     // for addr in 0x00_u8..0x80 {
  79.     //     if VALID_ADDR_RANGE.contains(&addr) && i2c.write(addr, &[]).is_ok() {
  80.     //         println!("{:02x}", addr)
  81.     //     }
  82.     // }
  83.     const buff_size: usize = 4096;
  84.     let mut bytesvailraw: [u8; 2] = [0; 2];
  85.     let mut buf: [u8; 4096] = [0; buff_size];
  86.  
  87.     let mut wait = Delay::new(&clocks);
  88.     // Init
  89.     while i2c.write(0x42_u8, &[0xFD]).is_err() {
  90.         println!("Waiting for init call to GPS...");
  91.         wait.delay_ms(1000_u32);
  92.     }
  93.     println!("Sent init call to GPS...");
  94.  
  95.     wait.delay_ms(40_u32);
  96.  
  97.     // Get number of bytes available (low byte)
  98.     while i2c.read(0x42_u8, &mut bytesvailraw).is_err() {
  99.         println!("Failed to read low byte of bytes avail...");
  100.         wait.delay_ms(500_u32);
  101.     }
  102.     println!("Got high byte of bytes avail: {:b}", bytesvailraw[0]);
  103.  
  104.     wait.delay_ms(40_u32);
  105.  
  106.     // Get number of bytes available (high byte)
  107.     while i2c.read(0x42_u8, &mut bytesvailraw).is_err() {
  108.         println!("Failed to read high byte of bytes avail...");
  109.         wait.delay_ms(500_u32);
  110.     }
  111.     println!("God high byte of bytes avail: {:b}", bytesvailraw[1]);
  112.  
  113.     let mut bytesavail = u16::from_le_bytes(bytesvailraw);
  114.     if bytesavail & (1u16 << 15) != 0 {
  115.         bytesavail &= !(1u16 << 15)
  116.     }
  117.     println!("Bytes available: {:}", bytesavail);
  118.     let mut buf_index: usize = 0;
  119.  
  120.     wait.delay_ms(100_u32);
  121.  
  122.     i2c.write(0x42_u8, &[0xFF])
  123.         .expect("Failed to set register...");
  124.     println!("Selected register...");
  125.  
  126.     wait.delay_ms(40_u32);
  127.  
  128.     println!("Reading data...");
  129.     let mut local_buff: [u8; 1] = [0];
  130.     while bytesavail > 0 && buf_index < buff_size {
  131.         match i2c.read(0x42_u8, &mut local_buff) {
  132.             Ok(_) => {
  133.                 println!("Read a byte: {:X}", local_buff[0]);
  134.                 bytesavail -= 1;
  135.                 println!("{:?} bytes left...", bytesavail);
  136.                 if local_buff[0] == 0xFF_u8 {
  137.                     println!("Device sent 0xFF...GPS buff is empty. Waiting.");
  138.                 }
  139.                 buf[buf_index] = local_buff[0];
  140.                 buf_index += 1;
  141.                 wait.delay_ms(40_u32);
  142.             }
  143.             Err(e) => {
  144.                 println!("Error reading byte: {:?}...\nWaiting...", e);
  145.                 wait.delay_ms(500_u32);
  146.                 continue
  147.             }
  148.         }
  149.     }
  150.     println!("Our buffer: {:?}", buf);
  151.  
  152.     loop {}
  153. }
  154. ```
  155. Integration guide:
  156. https://content.u-blox.com/sites/default/files/NEO-M9N_Integrationmanual_UBX-19014286.pdf
  157.  
  158. 3.7.2 I2C interface
  159. An I2C interface is available for communication with an external host CPU or u-blox cellular modules.
  160. The interface can be operated in slave mode only. The I2C protocol and electrical interface are fully
  161. compatible with Fast-mode of the I2C industry standard. Since the maximum SCL clock frequency
  162. is 400 kHz, the maximum transfer rate is 400 kb/s. The SCL and SDA pins have internal pull-up
  163. resistors which should be sufficient for most applications. However, depending on the speed of the
  164. host and the load on the I2C lines additional external pull-up resistors may be necessary.
  165. To use the I2C interface D_SEL pin must be left open.
  166.  
  167. In designs where the host uses the same I2C bus to communicate with more than one u-blox
  168. receiver, the I2C slave address for each receiver must be configured to a different value. Typically
  169. most u-blox receivers are configured to the same default I2C slave address value. To poll or
  170. set the I2C slave address, use the CFG-I2C-ADDRESS configuration item (see the applicable
  171. interface description [2]).
  172. The CFG-I2C-ADDRESS configuration item is an 8-bit value containing the I2C slave address in
  173. 7 most significant bits, and the read/write flag in the least significant bit.
  174.  
  175. 3.7.2.1 I2C register layout
  176. The I2C interface allows 256 registers to be addressed. As shown in Figure 11, only three of these
  177. are currently implemented.
  178. The data registers 0 to 252 at addresses 0x00 to 0xFC contain reserved information, the result from
  179. their reading is currently undefined. The data registers 0 to 252 are 1 byte wide.
  180. At addresses 0xFD and 0xFE it is possible to read the currently available number of bytes.
  181. The register at address 0xFF allows the data stream to be read. If there is no data awaiting
  182. transmission from the receiver, then this register delivers value 0xFF, which cannot be the first byte
  183. of a valid message. If the message data is ready for transmission, the successive reads of register
  184. 0xFF will deliver the waiting message data.
  185. UBX-19014286 - R08 3 Receiver functionality Page 26 of 94
  186. C1-Public
  187.  
  188. NEO-M9N - Integration manual
  189. Do not use registers 0x00 to 0xFC. They are reserved for future use and they do not currently
  190. provide any meaningful data.
  191. Figure 11: I2C register layout
  192.  
  193. 3.7.2.2 Read access types
  194. There are two I2C read transfer forms:
  195. • The "random access" form: includes a slave register address and allows any register to be read.
  196. • The "current address" form: omits the register address.
  197. Figure 12 shows the format of the first one, the "random access" form of the request. Following
  198. the start condition from the master, the 7-bit device address and the RW bit (which is a logic low
  199. for write access) are clocked onto the bus by the master transmitter. The receiver answers with an
  200. acknowledge (logic low) to indicate that it recognizes the address.
  201. Next, the 8-bit address of the register to be read must be written to the bus. Following the receiver's
  202. acknowledgment, the master again triggers a start condition and writes the device address, but this
  203. time the RW bit is a logic high to initiate the read access. Now, the master can read 1 to N bytes
  204. from the receiver, generating a not-acknowledge and a stop condition after the last byte being read.
  205. UBX-19014286 - R08 3 Receiver functionality Page 27 of 94
  206. C1-Public
  207.  
  208. NEO-M9N - Integration manual
  209. Figure 12: I2C random read access
  210. If the second form, "current address" is used, an address pointer in the receiver is used to determine
  211. which register to read. This address pointer will increment after each read unless it is already
  212. pointing at register 0xFF, the highest addressable register, in which case it remains unaltered.
  213. The initial value of this address pointer at startup is 0xFF, so by default all current address reads
  214. will repeatedly read register 0xFF and receive the next byte of message data (or 0xFF if no message
  215. data is waiting).
  216. Figure 13: I2C current address read access
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement