tcp_client: init

This commit is contained in:
occheung 2020-09-02 11:00:04 +08:00
parent 9a42674bf9
commit 3b83b6560f
3 changed files with 268 additions and 1 deletions

View File

@ -1,5 +1,5 @@
[target.thumbv7em-none-eabihf] [target.thumbv7em-none-eabihf]
runner = "gdb -q -x gdb_config/openocd.gdb" runner = "gdb -q -x gdb_config/fpga_config.gdb"
rustflags = [ rustflags = [
"-C", "link-arg=-Tlink.x", "-C", "link-arg=-Tlink.x",
] ]

View File

@ -20,6 +20,9 @@ lexical-core = { version="0.7.1", features=["radix"], default-features=false }
libm = "0.2.0" libm = "0.2.0"
embedded-nal = "0.1.0" embedded-nal = "0.1.0"
minimq = "0.1.0" minimq = "0.1.0"
enum-iterator = "0.6.0"
heapless = "0.5.5"
generic-array = "0.14.3"
# Logging and Panicking # Logging and Panicking
panic-itm = "0.4.1" panic-itm = "0.4.1"
@ -33,6 +36,9 @@ name = "ethernet"
[[example]] [[example]]
name = "fpga_config" name = "fpga_config"
[[example]]
name = "tcp_client"
# Uncomment for the allocator example. # Uncomment for the allocator example.
# alloc-cortex-m = "0.3.5" # alloc-cortex-m = "0.3.5"

261
examples/tcp_client.rs Normal file
View 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();
}
}