Skip to content

Commit

Permalink
Merge pull request #43 from rust-iot/fix/cs-mgmt
Browse files Browse the repository at this point in the history
Add chip select management to SPI interface
  • Loading branch information
ryankurte authored Apr 18, 2024
2 parents fa3c66f + a1c8e7d commit 46f5791
Show file tree
Hide file tree
Showing 7 changed files with 333 additions and 240 deletions.
4 changes: 2 additions & 2 deletions examples/ssd1306.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@
use driver_cp2130::prelude::*;

use embedded_graphics::{
text::Text,
mono_font::{ascii::FONT_6X10, MonoTextStyle},
pixelcolor::BinaryColor,
prelude::*,
text::Text,
};
use linux_embedded_hal::Delay;

use embedded_hal_compat::ReverseCompat as _;
use ssd1306::{prelude::*, Ssd1306};
use embedded_hal_compat::{ReverseCompat as _};

fn main() {
// Find matching devices
Expand Down
112 changes: 59 additions & 53 deletions src/cli.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
//! CP2130 Driver CLI
//!
//!
//!
//!
//! Copyright 2019 Ryan Kurte

extern crate clap;
use clap::Parser;

#[macro_use] extern crate log;
#[macro_use]
extern crate log;
extern crate simplelog;
use simplelog::{TermLogger, LevelFilter, TerminalMode};
use simplelog::{LevelFilter, TermLogger, TerminalMode};

use driver_cp2130::prelude::*;

Expand All @@ -19,12 +20,10 @@ extern crate hex;
extern crate rand;
use crate::rand::Rng;


#[derive(Debug, Parser)]
#[clap(name = "cp2130-util")]
/// CP2130 Utility
pub struct Options {

#[clap(subcommand)]
pub command: Command,

Expand All @@ -34,11 +33,11 @@ pub struct Options {
#[clap(flatten)]
pub options: UsbOptions,

#[clap(long, default_value="0")]
#[clap(long, default_value = "0")]
/// Device index (to select from multiple devices)
pub index: usize,

#[clap(long = "log-level", default_value="info")]
#[clap(long = "log-level", default_value = "info")]
/// Enable verbose logging
pub level: LevelFilter,
}
Expand All @@ -51,21 +50,21 @@ pub enum Command {
Info,
/// Set a GPIO output
SetOutput {
#[clap(long, default_value="6")]
#[clap(long, default_value = "6")]
/// GPIO pin index
pin: u8,

#[clap(long, default_value="push-pull")]
#[clap(long, default_value = "push-pull")]
/// GPIO pin mode to set (input, open drain, push-pull)
mode: GpioMode,

#[clap(default_value="high")]
#[clap(default_value = "high")]
/// GPIO pin state (high, low)
state: GpioLevel,
},
/// Read a GPIO input
ReadInput {
#[clap(long, default_value="6")]
#[clap(long, default_value = "6")]
/// GPIO pin index
pin: u8,

Expand All @@ -92,27 +91,27 @@ pub enum Command {
spi_opts: SpiOpts,
},
/// Test interaction with the CP2130 device
Test(TestOpts)
Test(TestOpts),
}

#[derive(Clone, Debug, PartialEq, Parser)]
pub struct SpiOpts {
#[clap(long, default_value="0")]
#[clap(long, default_value = "0")]
/// SPI Channel
channel: u8,

#[clap(long, default_value="0")]
#[clap(long, default_value = "0")]
/// SPI CS gpio index
cs_pin: u8,
}

#[derive(Debug, Parser)]
pub struct TestOpts {
#[clap(long, default_value="0")]
#[clap(long, default_value = "0")]
/// Pin for GPIO write
write_pin: u8,

#[clap(long, default_value="1")]
#[clap(long, default_value = "1")]
/// Pin for GPIO read
read_pin: u8,
}
Expand All @@ -123,12 +122,16 @@ fn parse_hex_str(src: &str) -> Result<Vec<u8>, hex::FromHexError> {
hex::decode(src)
}


fn main() {
let opts = Options::parse();

// Setup logging
TermLogger::init(opts.level, simplelog::Config::default(), TerminalMode::Mixed).unwrap();
TermLogger::init(
opts.level,
simplelog::Config::default(),
TerminalMode::Mixed,
)
.unwrap();

// Find matching devices
let (device, descriptor) = Manager::device(opts.filter, opts.index).unwrap();
Expand All @@ -146,95 +149,100 @@ fn main() {
Command::Version => {
let v = cp2130.version().unwrap();
info!("Device version: {}", v);
},
Command::SetOutput{pin, mode, state} => {
}
Command::SetOutput { pin, mode, state } => {
cp2130.set_gpio_mode_level(pin, mode, state).unwrap()
},
Command::ReadInput{pin, mode} => {
}
Command::ReadInput { pin, mode } => {
if let Some(m) = mode {
cp2130.set_gpio_mode_level(pin, m, GpioLevel::Low).unwrap();
}
let v = cp2130.get_gpio_level(pin).unwrap();
info!("Pin: {} value: {}", pin, v);
},
Command::SpiTransfer{data, spi_opts} => {
}
Command::SpiTransfer { data, spi_opts } => {
info!("Transmit: {}", hex::encode(&data));

let mut spi = cp2130.spi(spi_opts.channel, SpiConfig::default()).unwrap();

cp2130.set_gpio_mode_level(spi_opts.cs_pin, GpioMode::PushPull, GpioLevel::Low).unwrap();
let mut spi = cp2130
.spi(
spi_opts.channel,
SpiConfig::default(),
Some(spi_opts.cs_pin),
)
.unwrap();

let mut buff = data.clone();

spi.transfer_in_place(&mut buff).unwrap();

cp2130.set_gpio_mode_level(spi_opts.cs_pin, GpioMode::PushPull, GpioLevel::High).unwrap();
spi.transfer_in_place(&mut buff).unwrap();

info!("Received: {}", hex::encode(buff));
},
Command::SpiWrite{data, spi_opts} => {
}
Command::SpiWrite { data, spi_opts } => {
info!("Transmit: {}", hex::encode(&data));

let mut spi = cp2130.spi(spi_opts.channel, SpiConfig::default()).unwrap();

cp2130.set_gpio_mode_level(spi_opts.cs_pin, GpioMode::PushPull, GpioLevel::Low).unwrap();
let mut spi = cp2130
.spi(
spi_opts.channel,
SpiConfig::default(),
Some(spi_opts.cs_pin),
)
.unwrap();

spi.write(&data).unwrap();

cp2130.set_gpio_mode_level(spi_opts.cs_pin, GpioMode::PushPull, GpioLevel::High).unwrap();
},
}
Command::Test(opts) => {
run_tests(&mut cp2130, &opts);
}
}

}


fn run_tests(cp2130: &mut Cp2130, opts: &TestOpts) {
info!("Testing GPIO read/write");

cp2130.set_gpio_mode_level(opts.read_pin, GpioMode::Input, GpioLevel::Low).unwrap();
cp2130
.set_gpio_mode_level(opts.read_pin, GpioMode::Input, GpioLevel::Low)
.unwrap();

cp2130.set_gpio_mode_level(opts.write_pin, GpioMode::PushPull, GpioLevel::Low).unwrap();
cp2130
.set_gpio_mode_level(opts.write_pin, GpioMode::PushPull, GpioLevel::Low)
.unwrap();
let v = cp2130.get_gpio_level(opts.read_pin).unwrap();
if v != false {
error!("GPIO read error");
}

cp2130.set_gpio_mode_level(opts.write_pin, GpioMode::PushPull, GpioLevel::High).unwrap();
cp2130
.set_gpio_mode_level(opts.write_pin, GpioMode::PushPull, GpioLevel::High)
.unwrap();
let v = cp2130.get_gpio_level(opts.read_pin).unwrap();
if v != true {
error!("GPIO read error");
}

info!("GPIO read/write okay");


info!("Testing SPI write (short)");

let mut rng = rand::thread_rng();
let data: Vec<u8> = (0..34).map(|_| rng.gen() ).collect();
let data: Vec<u8> = (0..34).map(|_| rng.gen()).collect();

cp2130.spi_write(&data).unwrap();

info!("SPI write (short) okay");


info!("Testing SPI write (long)");

let mut rng = rand::thread_rng();
let data: Vec<u8> = (0..300).map(|_| rng.gen() ).collect();
let data: Vec<u8> = (0..300).map(|_| rng.gen()).collect();

cp2130.spi_write(&data).unwrap();

info!("SPI write (long) okay");


info!("Testing SPI transfer (short)");

let mut rng = rand::thread_rng();
let data: Vec<u8> = (0..34).map(|_| rng.gen() ).collect();
let data: Vec<u8> = (0..34).map(|_| rng.gen()).collect();
let mut buff = vec![0u8; data.len()];

cp2130.spi_write_read(&data, &mut buff).unwrap();
Expand All @@ -245,11 +253,10 @@ fn run_tests(cp2130: &mut Cp2130, opts: &TestOpts) {

info!("SPI transfer (short) okay");


info!("Testing SPI transfer (long)");

let mut rng = rand::thread_rng();
let data: Vec<u8> = (0..300).map(|_| rng.gen() ).collect();
let data: Vec<u8> = (0..300).map(|_| rng.gen()).collect();
let mut buff = vec![0u8; data.len()];

cp2130.spi_write_read(&data, &mut buff).unwrap();
Expand All @@ -259,5 +266,4 @@ fn run_tests(cp2130: &mut Cp2130, opts: &TestOpts) {
}

info!("SPI transfer (long) okay");

}
Loading

0 comments on commit 46f5791

Please sign in to comment.