forked from M-Labs/humpback-dds
tcp_client: init
This commit is contained in:
parent
9a42674bf9
commit
3b83b6560f
@ -1,5 +1,5 @@
|
||||
[target.thumbv7em-none-eabihf]
|
||||
runner = "gdb -q -x gdb_config/openocd.gdb"
|
||||
runner = "gdb -q -x gdb_config/fpga_config.gdb"
|
||||
rustflags = [
|
||||
"-C", "link-arg=-Tlink.x",
|
||||
]
|
||||
|
@ -20,6 +20,9 @@ lexical-core = { version="0.7.1", features=["radix"], default-features=false }
|
||||
libm = "0.2.0"
|
||||
embedded-nal = "0.1.0"
|
||||
minimq = "0.1.0"
|
||||
enum-iterator = "0.6.0"
|
||||
heapless = "0.5.5"
|
||||
generic-array = "0.14.3"
|
||||
|
||||
# Logging and Panicking
|
||||
panic-itm = "0.4.1"
|
||||
@ -33,6 +36,9 @@ name = "ethernet"
|
||||
[[example]]
|
||||
name = "fpga_config"
|
||||
|
||||
[[example]]
|
||||
name = "tcp_client"
|
||||
|
||||
# Uncomment for the allocator example.
|
||||
# alloc-cortex-m = "0.3.5"
|
||||
|
||||
|
261
examples/tcp_client.rs
Normal file
261
examples/tcp_client.rs
Normal file
@ -0,0 +1,261 @@
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use smoltcp as net;
|
||||
use stm32h7_ethernet as ethernet;
|
||||
use stm32h7xx_hal::{gpio::Speed, prelude::*, spi, pac};
|
||||
use embedded_hal::{blocking::spi::Transfer};
|
||||
|
||||
use heapless::{consts, String};
|
||||
|
||||
use cortex_m;
|
||||
use cortex_m_rt::{
|
||||
entry,
|
||||
exception,
|
||||
};
|
||||
use cortex_m_semihosting::hprintln;
|
||||
|
||||
use panic_halt as _;
|
||||
|
||||
use rtic::cyccnt::{Instant, U32Ext};
|
||||
|
||||
use minimq::{
|
||||
embedded_nal::{IpAddr, Ipv4Addr},
|
||||
MqttClient, QoS,
|
||||
};
|
||||
|
||||
use firmware::nal_tcp_client::{NetworkStack, NetStorage, NetworkInterface};
|
||||
use firmware::{Urukul};
|
||||
use firmware::cpld::{CPLD};
|
||||
|
||||
static mut NET_STORE: NetStorage = NetStorage {
|
||||
// Placeholder for the real IP address, which is initialized at runtime.
|
||||
ip_addrs: [net::wire::IpCidr::Ipv6(
|
||||
net::wire::Ipv6Cidr::SOLICITED_NODE_PREFIX,
|
||||
)],
|
||||
neighbor_cache: [None; 8],
|
||||
};
|
||||
|
||||
#[link_section = ".sram3.eth"]
|
||||
static mut DES_RING: ethernet::DesRing = ethernet::DesRing::new();
|
||||
|
||||
macro_rules! add_socket {
|
||||
($sockets:ident, $tx_storage:ident, $rx_storage:ident) => {
|
||||
let mut $rx_storage = [0; 4096];
|
||||
let mut $tx_storage = [0; 4096];
|
||||
|
||||
let tcp_socket = {
|
||||
let tx_buffer = net::socket::TcpSocketBuffer::new(&mut $tx_storage[..]);
|
||||
let rx_buffer = net::socket::TcpSocketBuffer::new(&mut $rx_storage[..]);
|
||||
|
||||
net::socket::TcpSocket::new(tx_buffer, rx_buffer)
|
||||
};
|
||||
|
||||
let _handle = $sockets.add(tcp_socket);
|
||||
};
|
||||
}
|
||||
|
||||
pub type UrukulType = Urukul<
|
||||
firmware::spi_slave::SPISlave<
|
||||
'static,
|
||||
firmware::cpld::CPLD<
|
||||
stm32h7xx_hal::spi::Spi<stm32h7xx_hal::device::SPI1>,
|
||||
stm32h7xx_hal::gpio::gpiob::PB12<stm32h7xx_hal::gpio::Output<stm32h7xx_hal::gpio::PushPull>>,
|
||||
stm32h7xx_hal::gpio::gpioa::PA15<stm32h7xx_hal::gpio::Output<stm32h7xx_hal::gpio::PushPull>>,
|
||||
stm32h7xx_hal::gpio::gpioc::PC7<stm32h7xx_hal::gpio::Output<stm32h7xx_hal::gpio::PushPull>>,
|
||||
stm32h7xx_hal::gpio::gpiob::PB15<stm32h7xx_hal::gpio::Output<stm32h7xx_hal::gpio::PushPull>>
|
||||
>,
|
||||
stm32h7xx_hal::spi::Spi<stm32h7xx_hal::device::SPI1>,
|
||||
stm32h7xx_hal::gpio::gpiob::PB12<stm32h7xx_hal::gpio::Output<stm32h7xx_hal::gpio::PushPull>>,
|
||||
stm32h7xx_hal::gpio::gpioa::PA15<stm32h7xx_hal::gpio::Output<stm32h7xx_hal::gpio::PushPull>>,
|
||||
stm32h7xx_hal::gpio::gpioc::PC7<stm32h7xx_hal::gpio::Output<stm32h7xx_hal::gpio::PushPull>>,
|
||||
stm32h7xx_hal::gpio::gpiob::PB15<stm32h7xx_hal::gpio::Output<stm32h7xx_hal::gpio::PushPull>>
|
||||
>
|
||||
>;
|
||||
|
||||
pub type CPLDType = CPLD<
|
||||
stm32h7xx_hal::spi::Spi<stm32h7xx_hal::device::SPI1>,
|
||||
stm32h7xx_hal::gpio::gpiob::PB12<stm32h7xx_hal::gpio::Output<stm32h7xx_hal::gpio::PushPull>>,
|
||||
stm32h7xx_hal::gpio::gpioa::PA15<stm32h7xx_hal::gpio::Output<stm32h7xx_hal::gpio::PushPull>>,
|
||||
stm32h7xx_hal::gpio::gpioc::PC7<stm32h7xx_hal::gpio::Output<stm32h7xx_hal::gpio::PushPull>>,
|
||||
stm32h7xx_hal::gpio::gpiob::PB15<stm32h7xx_hal::gpio::Output<stm32h7xx_hal::gpio::PushPull>>
|
||||
>;
|
||||
|
||||
pub type IoUpdateType = stm32h7xx_hal::gpio::gpiob::PB15<stm32h7xx_hal::gpio::Output<stm32h7xx_hal::gpio::PushPull>>;
|
||||
pub type SpiType = stm32h7xx_hal::spi::Spi<stm32h7xx_hal::device::SPI1, u8>;
|
||||
pub type PartsType = firmware::spi_slave::Parts<
|
||||
'static,
|
||||
firmware::cpld::CPLD<
|
||||
stm32h7xx_hal::spi::Spi<stm32h7xx_hal::device::SPI1>,
|
||||
stm32h7xx_hal::gpio::gpiob::PB12<stm32h7xx_hal::gpio::Output<stm32h7xx_hal::gpio::PushPull>>,
|
||||
stm32h7xx_hal::gpio::gpioa::PA15<stm32h7xx_hal::gpio::Output<stm32h7xx_hal::gpio::PushPull>>,
|
||||
stm32h7xx_hal::gpio::gpioc::PC7<stm32h7xx_hal::gpio::Output<stm32h7xx_hal::gpio::PushPull>>,
|
||||
stm32h7xx_hal::gpio::gpiob::PB15<stm32h7xx_hal::gpio::Output<stm32h7xx_hal::gpio::PushPull>>
|
||||
>,
|
||||
stm32h7xx_hal::spi::Spi<stm32h7xx_hal::device::SPI1>,
|
||||
stm32h7xx_hal::gpio::gpiob::PB12<stm32h7xx_hal::gpio::Output<stm32h7xx_hal::gpio::PushPull>>,
|
||||
stm32h7xx_hal::gpio::gpioa::PA15<stm32h7xx_hal::gpio::Output<stm32h7xx_hal::gpio::PushPull>>,
|
||||
stm32h7xx_hal::gpio::gpioc::PC7<stm32h7xx_hal::gpio::Output<stm32h7xx_hal::gpio::PushPull>>,
|
||||
stm32h7xx_hal::gpio::gpiob::PB15<stm32h7xx_hal::gpio::Output<stm32h7xx_hal::gpio::PushPull>>
|
||||
>;
|
||||
|
||||
#[entry]
|
||||
fn main() -> ! {
|
||||
let mut cp = cortex_m::Peripherals::take().unwrap();
|
||||
let dp = pac::Peripherals::take().unwrap();
|
||||
|
||||
cp.DWT.enable_cycle_counter();
|
||||
|
||||
// Enable SRAM3 for the descriptor ring.
|
||||
dp.RCC.ahb2enr.modify(|_, w| w.sram3en().set_bit());
|
||||
|
||||
let rcc = dp.RCC.constrain();
|
||||
let pwr = dp.PWR.constrain();
|
||||
let vos = pwr.freeze();
|
||||
|
||||
let ccdr = rcc
|
||||
.sysclk(400.mhz())
|
||||
.hclk(200.mhz())
|
||||
.per_ck(100.mhz())
|
||||
.pll1_q_ck(48.mhz()) // for SPI
|
||||
.pll2_p_ck(100.mhz())
|
||||
.pll2_q_ck(100.mhz())
|
||||
.freeze(vos, &dp.SYSCFG);
|
||||
|
||||
let gpioa = dp.GPIOA.split(ccdr.peripheral.GPIOA);
|
||||
let gpiob = dp.GPIOB.split(ccdr.peripheral.GPIOB);
|
||||
let gpioc = dp.GPIOC.split(ccdr.peripheral.GPIOC);
|
||||
let gpiod = dp.GPIOD.split(ccdr.peripheral.GPIOD);
|
||||
let gpioe = dp.GPIOE.split(ccdr.peripheral.GPIOE);
|
||||
let gpiof = dp.GPIOF.split(ccdr.peripheral.GPIOF);
|
||||
let gpiog = dp.GPIOG.split(ccdr.peripheral.GPIOG);
|
||||
|
||||
// Configure ethernet IO
|
||||
{
|
||||
let _rmii_refclk = gpioa.pa1.into_alternate_af11().set_speed(Speed::VeryHigh);
|
||||
let _rmii_mdio = gpioa.pa2.into_alternate_af11().set_speed(Speed::VeryHigh);
|
||||
let _rmii_mdc = gpioc.pc1.into_alternate_af11().set_speed(Speed::VeryHigh);
|
||||
let _rmii_crs_dv = gpioa.pa7.into_alternate_af11().set_speed(Speed::VeryHigh);
|
||||
let _rmii_rxd0 = gpioc.pc4.into_alternate_af11().set_speed(Speed::VeryHigh);
|
||||
let _rmii_rxd1 = gpioc.pc5.into_alternate_af11().set_speed(Speed::VeryHigh);
|
||||
let _rmii_tx_en = gpiog.pg11.into_alternate_af11().set_speed(Speed::VeryHigh);
|
||||
let _rmii_txd0 = gpiog.pg13.into_alternate_af11().set_speed(Speed::VeryHigh);
|
||||
let _rmii_txd1 = gpiob.pb13.into_alternate_af11().set_speed(Speed::VeryHigh);
|
||||
}
|
||||
|
||||
// Configure ethernet
|
||||
let mut net_interface = {
|
||||
let mac_addr = net::wire::EthernetAddress([0xAC, 0x6F, 0x7A, 0xDE, 0xD6, 0xC8]);
|
||||
let (eth_dma, _eth_mac) = unsafe {
|
||||
ethernet::ethernet_init(
|
||||
dp.ETHERNET_MAC,
|
||||
dp.ETHERNET_MTL,
|
||||
dp.ETHERNET_DMA,
|
||||
&mut DES_RING,
|
||||
mac_addr.clone(),
|
||||
)
|
||||
};
|
||||
|
||||
unsafe { ethernet::enable_interrupt() }
|
||||
|
||||
let store = unsafe { &mut NET_STORE };
|
||||
|
||||
store.ip_addrs[0] = net::wire::IpCidr::new(net::wire::IpAddress::v4(192, 168, 1, 200), 24);
|
||||
|
||||
let neighbor_cache = net::iface::NeighborCache::new(&mut store.neighbor_cache[..]);
|
||||
|
||||
net::iface::EthernetInterfaceBuilder::new(eth_dma)
|
||||
.ethernet_addr(mac_addr)
|
||||
.neighbor_cache(neighbor_cache)
|
||||
.ip_addrs(&mut store.ip_addrs[..])
|
||||
.finalize()
|
||||
};
|
||||
|
||||
/*
|
||||
* Using SPI1, AF5
|
||||
* SCLK -> PA5
|
||||
* MOSI -> PB5
|
||||
* MISO -> PA6
|
||||
* CS -> 0: PB12, 1: PA15, 2: PC7
|
||||
* I/O_Update -> PB15
|
||||
*/
|
||||
let sclk = gpioa.pa5.into_alternate_af5();
|
||||
let mosi = gpiob.pb5.into_alternate_af5();
|
||||
let miso = gpioa.pa6.into_alternate_af5();
|
||||
|
||||
let (cs0, cs1, cs2) = (
|
||||
gpiob.pb12.into_push_pull_output(),
|
||||
gpioa.pa15.into_push_pull_output(),
|
||||
gpioc.pc7.into_push_pull_output(),
|
||||
);
|
||||
|
||||
let io_update = gpiob.pb15.into_push_pull_output();
|
||||
|
||||
let spi = dp.SPI1.spi(
|
||||
(sclk, miso, mosi),
|
||||
spi::MODE_0,
|
||||
3.mhz(),
|
||||
ccdr.peripheral.SPI1,
|
||||
&ccdr.clocks,
|
||||
);
|
||||
|
||||
let cpld = CPLD::new(spi, (cs0, cs1, cs2), io_update);
|
||||
let parts = cpld.split();
|
||||
|
||||
let urukul = Urukul::new(
|
||||
parts.spi1, parts.spi2, parts.spi3, parts.spi4, parts.spi5, parts.spi6, parts.spi7,
|
||||
[25_000_000, 25_000_000, 25_000_000, 25_000_000]
|
||||
);
|
||||
|
||||
cp.SCB.enable_icache();
|
||||
|
||||
let mut time: u32 = 0;
|
||||
let mut next_ms = Instant::now();
|
||||
|
||||
next_ms += 400_00.cycles();
|
||||
|
||||
let mut socket_set_entries: [_; 8] = Default::default();
|
||||
let mut sockets = net::socket::SocketSet::new(&mut socket_set_entries[..]);
|
||||
add_socket!(sockets, rx_storage, tx_storage);
|
||||
|
||||
let tcp_stack = NetworkStack::new(&mut net_interface, sockets);
|
||||
let mut client = MqttClient::<consts::U256, _>::new(
|
||||
IpAddr::V4(Ipv4Addr::new(192, 168, 1, 125)),
|
||||
"nucleo",
|
||||
tcp_stack,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
loop {
|
||||
let tick = Instant::now() > next_ms;
|
||||
|
||||
if tick {
|
||||
next_ms += 400_000.cycles();
|
||||
time += 1;
|
||||
}
|
||||
|
||||
if tick && (time % 1000) == 0 {
|
||||
client
|
||||
.publish("nucleo", "Hello, World!".as_bytes(), QoS::AtMostOnce, &[])
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
client
|
||||
.poll(|_client, topic, message, _properties| match topic {
|
||||
_ => hprintln!("On '{:?}', received: {:?}", topic, message).unwrap(),
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
// Update the TCP stack.
|
||||
let sleep = client.network_stack.update(time);
|
||||
if sleep {
|
||||
//cortex_m::asm::wfi();
|
||||
cortex_m::asm::nop();
|
||||
}
|
||||
|
||||
match client.is_connected() {
|
||||
true => hprintln!("Connected"),
|
||||
false => hprintln!("No Connection"),
|
||||
}.unwrap();
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user