Skip to content
Snippets Groups Projects
Select Git revision
  • 537b53f278fc802bf382e5424b774dc9113d9ae2
  • master default protected
  • v5
  • stable
4 results

modify.rs

Blame
  • rtt_rtic_i2c.rs 5.79 KiB
    //! cargo run --examples rtt-pwm
    
    #![deny(unsafe_code)]
    // #![deny(warnings)]
    #![no_main]
    #![no_std]
    
    use cortex_m::asm::delay;
    use panic_halt as _;
    use rtt_target::{rprintln, rtt_init_print};
    
    use stm32f4xx_hal::{
        gpio::{
            gpiob::{PB8, PB9},
            gpioc::PC13,
            AlternateOD, Edge, ExtiPin, Input, PullUp, Speed, AF4,
        },
        i2c::I2c,
        prelude::*,
        stm32::I2C1,
    };
    
    #[rtic::app(device = stm32f4xx_hal::stm32, peripherals = true)]
    const APP: () = {
        #[init]
        fn init(cx: init::Context) {
            rtt_init_print!();
            rprintln!("init");
            let dp = cx.device;
    
            // Set up the system clock, 48MHz
            let rcc = dp.RCC.constrain();
            // let clocks = rcc.cfgr.sysclk(48.mhz()).freeze();
            let clocks = rcc.cfgr.freeze();
            // let clocks = rcc
            //     .cfgr
            //     .hclk(48.mhz())
            //     .sysclk(48.mhz())
            //     .pclk1(24.mhz())
            //     .pclk2(24.mhz())
            //     .freeze();
    
            // Set up I2C.
            let gpiob = dp.GPIOB.split();
            let scl = gpiob.pb8.into_alternate_af4().set_open_drain();
            let sda = gpiob.pb9.into_alternate_af4().set_open_drain();
            let mut i2c = I2c::i2c1(dp.I2C1, (scl, sda), 400.khz(), clocks);
    
            rprintln!("here");
    
            // configure
            // 7:6 -     reserved
            // 5   ORDER logic 0, the MSB of the data word is transmitted first.
            //           logic 1, the LSB of the data word is transmitted first.
            // 4   -     reserved
            // 3:3 M1:M0 Mode selection
            //           00 - SPICLK LOW when idle; data clocked in on leading edge (CPOL = 0, CPHA = 0)
            //           01 - SPICLK LOW when idle; data clocked in on trailing edge (CPOL = 0, CPHA = 1)
            //           10 - SPICLK HIGH when idle; data clocked in on trailing edge (CPOL = 1, CPHA = 0)
            //           11 - SPICLK HIGH when idle; data clocked in on leading edge (CPOL = 1, CPHA = 1)
            // 1:0 F1:F0 SPI clock rate
            //           00 - 1843 kHz
            //           01 - 461 kHz
            //           10 - 115 kHz
            //           11 - 58 kHz
    
            let i2c_addr = 0x50 >> 1;
            let i2c_command_conf = 0xF0;
    
            let i2c_conf_reg = (0b0 << 5) /* MSB First */ |
                               (0b11 << 2) /* Mode 3 */ |
                               (0b00 << 0) /* 1843 kHz */;
            // (0b01 << 0) /* 461 kHz */;
    
            let x = i2c.write(i2c_addr, &[i2c_command_conf, i2c_conf_reg]);
            rprintln!("configure {:?}", x);
            cortex_m::asm::delay(100_000);
    
            // write to spi with CS0 (command 01..0f)
            let i2c_command_cs0 = 0x01; // bit 0 set
            let pmw_command_product_id = 0x00;
    
            let x = i2c.write(i2c_addr, &[i2c_command_cs0, pmw_command_product_id]);
            rprintln!("request product_id {:?}", x);
            cortex_m::asm::delay(10000);
    
            // send an extra byte, to actually read (data can be 0)
            let x = i2c.write(i2c_addr, &[i2c_command_cs0, 0x00u8]);
            // read the buffer
            cortex_m::asm::delay(10000);
    
            // read the result
            let mut buff = [0u8, 1];
            let x = i2c.read(i2c_addr, &mut buff);
            // read the buffer
            cortex_m::asm::delay(10000);
            rprintln!("data received {:?}", x);
            rprintln!("data received {:?}", buff);
        }
    
        #[idle]
        fn idle(_cx: idle::Context) -> ! {
            rprintln!("idle");
            loop {
                continue;
            }
        }
    };
    
    // SC18IS602
    mod SC18IS602 {
        enum Function {
            SpiReadWrite = 0x00, // 0F..01, where lowest 4 bits are the CSs
            SpiConfigure = 0xF0,
            ClearInterrupt = 0xF1,
            IdleMode = 0xF2,
            GpioWrite = 0xF4,
            GpioRead = 0xF5,
            GpioEnable = 0xF6,
            GpioConfigure = 0xF7,
        }
    
        impl Function {
            fn id(self) -> u8 {
                self as u8
            }
        }
    
        enum GpioMode {
            QuasiBiDirectional = 0b00,
            PushPull = 0b01,
            InputOnly = 0b10,
            OpenDrain = 0b11,
        }
    
        impl GpioMode {
            fn val(self) -> u8 {
                self as u8
            }
        }
    
        use embedded_hal::{blocking::i2c, digital::v2::OutputPin};
    
        enum Error {
            NotConfigured,
        }
        // struct SH18IS602<PINS> {
        struct SH18IS602<I2C>
        where
            I2C: i2c::Write,
        {
            addr: u8,
            cs: bool,
            i2c: I2C,
        }
    
        impl<I2C> SH18IS602<I2C>
        where
            I2C: i2c::Write,
        {
            fn new(mut i2c: I2C, addr: u8, cs: bool) -> SH18IS602<I2C> {
                if cs {
                    let addr = (0x50 + addr) >> 1;
                    // Configure SS0 as GPIO
                    i2c.write(addr, &[Function::GpioEnable.id(), 0x1]).ok();
    
                    // Configure SS0 as a PushPull Output
                    i2c.write(
                        addr,
                        &[Function::GpioConfigure.id(), GpioMode::PushPull.val()],
                    )
                    .ok();
                }
                SH18IS602 { addr, cs, i2c }
            }
        }
    
        // fn set<I2C>(i2c: I2C, data: u8)
        // where
        //     I2C: i2c::Write,
        // {
        //     i2c.write(self.addr, &[Function::GpioWrite.id(), 0x0]).ok();
        // }
    
        impl<I2C> OutputPin for SH18IS602<I2C>
        where
            I2C: i2c::Write,
        {
            type Error = Error;
    
            fn set_low(&mut self) -> Result<(), Self::Error> {
                if !self.cs {
                    Err(Error::NotConfigured)
                } else {
                    self.i2c
                        .write(self.addr, &[Function::GpioWrite.id(), 0x0])
                        .ok();
                    Ok(())
                }
            }
    
            fn set_high(&mut self) -> Result<(), Self::Error> {
                if !self.cs {
                    Err(Error::NotConfigured)
                } else {
                    self.i2c
                        .write(self.addr, &[Function::GpioWrite.id(), 0x1])
                        .ok();
                    Ok(())
                }
            }
        }
    }