Add tx_stm32f407 example
This commit is contained in:
parent
82f4bef09f
commit
6b9f58a98f
|
@ -0,0 +1,12 @@
|
||||||
|
[target.thumbv7em-none-eabihf]
|
||||||
|
runner = "gdb -q -x openocd.gdb"
|
||||||
|
rustflags = [
|
||||||
|
"-C", "link-arg=-Tlink.x",
|
||||||
|
]
|
||||||
|
|
||||||
|
[build]
|
||||||
|
# Pick ONE of these compilation targets
|
||||||
|
# target = "thumbv6m-none-eabi" # Cortex-M0 and Cortex-M0+
|
||||||
|
# target = "thumbv7m-none-eabi" # Cortex-M3
|
||||||
|
# target = "thumbv7em-none-eabi" # Cortex-M4 and Cortex-M7 (no FPU)
|
||||||
|
target = "thumbv7em-none-eabihf" # Cortex-M4F and Cortex-M7F (with FPU)
|
|
@ -1,5 +1,11 @@
|
||||||
# This file is automatically @generated by Cargo.
|
# This file is automatically @generated by Cargo.
|
||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
|
[[package]]
|
||||||
|
name = "aligned"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d39da9b88ae1a81c03c9c082b8db83f1d0e93914126041962af61034ab44c4a5"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "aligned"
|
name = "aligned"
|
||||||
version = "0.3.2"
|
version = "0.3.2"
|
||||||
|
@ -56,13 +62,25 @@ version = "0.1.10"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cortex-m"
|
||||||
|
version = "0.5.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3c0b159a1e8306949579de3698c841dba58058197b65c60807194e4fa1e7a554"
|
||||||
|
dependencies = [
|
||||||
|
"aligned 0.2.0",
|
||||||
|
"bare-metal",
|
||||||
|
"cortex-m 0.6.2",
|
||||||
|
"volatile-register",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cortex-m"
|
name = "cortex-m"
|
||||||
version = "0.6.2"
|
version = "0.6.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2954942fbbdd49996704e6f048ce57567c3e1a4e2dc59b41ae9fde06a01fc763"
|
checksum = "2954942fbbdd49996704e6f048ce57567c3e1a4e2dc59b41ae9fde06a01fc763"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aligned",
|
"aligned 0.3.2",
|
||||||
"bare-metal",
|
"bare-metal",
|
||||||
"volatile-register",
|
"volatile-register",
|
||||||
]
|
]
|
||||||
|
@ -102,8 +120,12 @@ dependencies = [
|
||||||
name = "enc424j600"
|
name = "enc424j600"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aligned",
|
"aligned 0.3.2",
|
||||||
|
"cortex-m 0.5.10",
|
||||||
|
"cortex-m-rt",
|
||||||
|
"embedded-hal",
|
||||||
"log",
|
"log",
|
||||||
|
"panic-itm",
|
||||||
"smoltcp",
|
"smoltcp",
|
||||||
"stm32f4xx-hal",
|
"stm32f4xx-hal",
|
||||||
"volatile-register",
|
"volatile-register",
|
||||||
|
@ -148,6 +170,15 @@ version = "0.1.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b1411551beb3c11dedfb0a90a0fa256b47d28b9ec2cdff34c25a2fa59e45dbdc"
|
checksum = "b1411551beb3c11dedfb0a90a0fa256b47d28b9ec2cdff34c25a2fa59e45dbdc"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "panic-itm"
|
||||||
|
version = "0.4.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "98830d17a95587207e41edaa3009b143d326ce134b0e3538ac98246a67d66cc3"
|
||||||
|
dependencies = [
|
||||||
|
"cortex-m 0.6.2",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.18"
|
version = "1.0.18"
|
||||||
|
@ -227,7 +258,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "11460b4de3a84f072e2cf6e76306c64d27f405a0e83bace0a726f555ddf4bf33"
|
checksum = "11460b4de3a84f072e2cf6e76306c64d27f405a0e83bace0a726f555ddf4bf33"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bare-metal",
|
"bare-metal",
|
||||||
"cortex-m",
|
"cortex-m 0.6.2",
|
||||||
"vcell",
|
"vcell",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -239,7 +270,7 @@ checksum = "b3a2f044469d1e3aff2cd02bee8b2724f3d5d91f3175e5d1ec99770320d16192"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bare-metal",
|
"bare-metal",
|
||||||
"cast",
|
"cast",
|
||||||
"cortex-m",
|
"cortex-m 0.6.2",
|
||||||
"cortex-m-rt",
|
"cortex-m-rt",
|
||||||
"embedded-hal",
|
"embedded-hal",
|
||||||
"nb",
|
"nb",
|
||||||
|
|
10
Cargo.toml
10
Cargo.toml
|
@ -20,6 +20,16 @@ smoltcp-phy = ["smoltcp"]
|
||||||
stm32f407 = ["stm32f4xx-hal/stm32f407"]
|
stm32f407 = ["stm32f4xx-hal/stm32f407"]
|
||||||
default = []
|
default = []
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
cortex-m = "0.5"
|
||||||
|
cortex-m-rt = "0.6"
|
||||||
|
embedded-hal = "0.2"
|
||||||
|
panic-itm = "0.4"
|
||||||
|
|
||||||
|
[[example]]
|
||||||
|
name = "tx_stm32f407"
|
||||||
|
required-features = ["stm32f407"]
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
codegen-units = 1
|
codegen-units = 1
|
||||||
incremental = false
|
incremental = false
|
||||||
|
|
39
README.md
39
README.md
|
@ -1 +1,40 @@
|
||||||
# ENC424J600 Driver
|
# ENC424J600 Driver
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
### Endless Pinging - `tx_stm32f407`
|
||||||
|
|
||||||
|
This program demonstrates the Ethernet TX capability on an STM32F407 board connected to an ENC424J600 module via SPI. Once loaded and initialised, a specific ping packet is sent (broadcasted) every 100ms. Such a packet has the following properties:
|
||||||
|
|
||||||
|
* Destination MAC Address: ff-ff-ff-ff-ff-ff
|
||||||
|
* Source MAC Address: 08-60-6e-44-42-95
|
||||||
|
* Destination IP Address: 192.168.1.231
|
||||||
|
* Source IP Address: 192.168.1.100
|
||||||
|
* Frame Length in Bytes: 64
|
||||||
|
|
||||||
|
Note that this program uses ITM for logging output.
|
||||||
|
|
||||||
|
#### How-to
|
||||||
|
|
||||||
|
1. Prepare the Rust and Cargo environment for building and running the program on STM32F4xx Cortex-M platforms.
|
||||||
|
|
||||||
|
2. Install [`itm`](https://docs.rs/itm/) on Cargo:
|
||||||
|
```
|
||||||
|
cargo install itm
|
||||||
|
```
|
||||||
|
If necessary, add your installation location (`~/.cargo/bin` by default) to `$PATH`.
|
||||||
|
|
||||||
|
3. Connect your STM32F407 device to the computer. Without changing any code, you may use an STLink V2 debugger.
|
||||||
|
|
||||||
|
4. Run OpenOCD with the appropriate configuration files (e.g. `interface/stlink-v2.cfg`, `target/stm32f4x.cfg`).
|
||||||
|
|
||||||
|
5. With OpenOCD running, build and run this program:
|
||||||
|
```
|
||||||
|
cargo run --release --example=tx_stm32f407 --features=stm32f407
|
||||||
|
```
|
||||||
|
Use appropriate GDB commands such as `c` for continuing.
|
||||||
|
|
||||||
|
6. On a separate console window, monitor and observe the ITM output, which is located at the same directory as you started OpenOCD:
|
||||||
|
```
|
||||||
|
itmdump -f itm.log -F
|
||||||
|
```
|
||||||
|
|
|
@ -0,0 +1,129 @@
|
||||||
|
#![no_std]
|
||||||
|
#![no_main]
|
||||||
|
|
||||||
|
extern crate panic_itm;
|
||||||
|
use cortex_m::{iprint, iprintln};
|
||||||
|
|
||||||
|
use cortex_m_rt::entry;
|
||||||
|
use embedded_hal::watchdog::{WatchdogEnable, Watchdog};
|
||||||
|
use embedded_hal::digital::v2::OutputPin;
|
||||||
|
use embedded_hal::blocking::delay::DelayMs;
|
||||||
|
use stm32f4xx_hal::{
|
||||||
|
rcc::RccExt,
|
||||||
|
gpio::GpioExt,
|
||||||
|
watchdog::IndependentWatchdog,
|
||||||
|
time::U32Ext,
|
||||||
|
stm32::{CorePeripherals, Peripherals},
|
||||||
|
delay::Delay,
|
||||||
|
spi::Spi
|
||||||
|
};
|
||||||
|
use enc424j600;
|
||||||
|
use enc424j600::EthController;
|
||||||
|
|
||||||
|
#[entry]
|
||||||
|
fn main() -> ! {
|
||||||
|
let mut cp = CorePeripherals::take().unwrap();
|
||||||
|
cp.SCB.enable_icache();
|
||||||
|
cp.SCB.enable_dcache(&mut cp.CPUID);
|
||||||
|
|
||||||
|
let dp = Peripherals::take().unwrap();
|
||||||
|
let clocks = dp.RCC.constrain()
|
||||||
|
.cfgr
|
||||||
|
.sysclk(168.mhz())
|
||||||
|
.hclk(168.mhz())
|
||||||
|
.pclk1(32.mhz())
|
||||||
|
.pclk2(64.mhz())
|
||||||
|
.freeze();
|
||||||
|
let mut delay = Delay::new(cp.SYST, clocks);
|
||||||
|
|
||||||
|
let mut itm = cp.ITM;
|
||||||
|
let stim0 = &mut itm.stim[0];
|
||||||
|
|
||||||
|
iprintln!(stim0,
|
||||||
|
"Eth TX Pinging on STM32-H407 via NIC100/ENC424J600");
|
||||||
|
|
||||||
|
// NIC100 / ENC424J600 Set-up
|
||||||
|
let spi1 = dp.SPI1;
|
||||||
|
let gpioa = dp.GPIOA.split();
|
||||||
|
// Mapping: see Table 9, STM32F407ZG Manual
|
||||||
|
let spi1_sck = gpioa.pa5.into_alternate_af5();
|
||||||
|
let spi1_miso = gpioa.pa6.into_alternate_af5();
|
||||||
|
let spi1_mosi = gpioa.pa7.into_alternate_af5();
|
||||||
|
let spi1_nss = gpioa.pa4.into_push_pull_output();
|
||||||
|
// Map SPISEL: see Table 1, NIC100 Manual
|
||||||
|
let mut spisel = gpioa.pa1.into_push_pull_output();
|
||||||
|
spisel.set_high().unwrap();
|
||||||
|
delay.delay_ms(1_u32);
|
||||||
|
spisel.set_low().unwrap();
|
||||||
|
// Create SPI1 for HAL
|
||||||
|
let spi_eth_port = Spi::spi1(
|
||||||
|
spi1, (spi1_sck, spi1_miso, spi1_mosi),
|
||||||
|
enc424j600::spi::SPI_MODE, enc424j600::spi::SPI_CLOCK.into(),
|
||||||
|
clocks);
|
||||||
|
let mut spi_eth = enc424j600::SpiEth::new(spi_eth_port, spi1_nss);
|
||||||
|
// Init
|
||||||
|
match spi_eth.init_dev() {
|
||||||
|
Ok(_) => {
|
||||||
|
iprintln!(stim0, "Ethernet initialised.")
|
||||||
|
}
|
||||||
|
Err(_) => {
|
||||||
|
panic!("Ethernet initialisation Failed!")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delay.delay_ms(1_u32);
|
||||||
|
iprintln!(stim0,
|
||||||
|
"- Delayed 1000us (>=256us), PHY regs are now available");
|
||||||
|
|
||||||
|
// Read MAC
|
||||||
|
let mut eth_mac_addr: [u8; 6] = [0; 6];
|
||||||
|
spi_eth.read_from_mac(&mut eth_mac_addr);
|
||||||
|
iprintln!(stim0,
|
||||||
|
"MAC Address = {:02x}-{:02x}-{:02x}-{:02x}-{:02x}-{:02x}",
|
||||||
|
eth_mac_addr[5], eth_mac_addr[4],
|
||||||
|
eth_mac_addr[3], eth_mac_addr[2],
|
||||||
|
eth_mac_addr[1], eth_mac_addr[0]);
|
||||||
|
// Set to promiscuous mode
|
||||||
|
spi_eth.set_promiscuous();
|
||||||
|
iprintln!(stim0,
|
||||||
|
"Promiscuous Mode ON");
|
||||||
|
|
||||||
|
// Init Rx/Tx buffers
|
||||||
|
spi_eth.init_rxbuf();
|
||||||
|
spi_eth.init_txbuf();
|
||||||
|
// Testing Eth TX
|
||||||
|
let eth_tx_dat: [u8; 64] = [
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x08, 0x60,
|
||||||
|
0x6e, 0x44, 0x42, 0x95, 0x08, 0x06, 0x00, 0x01,
|
||||||
|
0x08, 0x00, 0x06, 0x04, 0x00, 0x01, 0x08, 0x60,
|
||||||
|
0x6e, 0x44, 0x42, 0x95, 0xc0, 0xa8, 0x01, 0x64,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xa8,
|
||||||
|
0x01, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x69, 0xd0, 0x85, 0x9f
|
||||||
|
];
|
||||||
|
loop {
|
||||||
|
let mut eth_tx_packet = enc424j600::tx::TxPacket::new();
|
||||||
|
eth_tx_packet.update_frame(ð_tx_dat, 64);
|
||||||
|
iprintln!(stim0,
|
||||||
|
"Sending packet (len={:}): \
|
||||||
|
dest={:02x}-{:02x}-{:02x}-{:02x}-{:02x}-{:02x} \
|
||||||
|
src={:02x}-{:02x}-{:02x}-{:02x}-{:02x}-{:02x} \
|
||||||
|
data={:02x}{:02x}{:02x}{:02x} {:02x}{:02x}{:02x}{:02x} ...",
|
||||||
|
eth_tx_packet.get_frame_length(),
|
||||||
|
eth_tx_packet.get_frame_byte(0), eth_tx_packet.get_frame_byte(1), eth_tx_packet.get_frame_byte(2),
|
||||||
|
eth_tx_packet.get_frame_byte(3), eth_tx_packet.get_frame_byte(4), eth_tx_packet.get_frame_byte(5),
|
||||||
|
eth_tx_packet.get_frame_byte(6), eth_tx_packet.get_frame_byte(7), eth_tx_packet.get_frame_byte(8),
|
||||||
|
eth_tx_packet.get_frame_byte(9), eth_tx_packet.get_frame_byte(10), eth_tx_packet.get_frame_byte(11),
|
||||||
|
eth_tx_packet.get_frame_byte(12), eth_tx_packet.get_frame_byte(13),
|
||||||
|
eth_tx_packet.get_frame_byte(14), eth_tx_packet.get_frame_byte(15),
|
||||||
|
eth_tx_packet.get_frame_byte(16), eth_tx_packet.get_frame_byte(17),
|
||||||
|
eth_tx_packet.get_frame_byte(18), eth_tx_packet.get_frame_byte(19)
|
||||||
|
);
|
||||||
|
spi_eth.send_raw_packet(eth_tx_packet);
|
||||||
|
iprintln!(stim0,
|
||||||
|
"Packet sent");
|
||||||
|
delay.delay_ms(100_u32);
|
||||||
|
}
|
||||||
|
|
||||||
|
unreachable!()
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 2048K
|
||||||
|
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 112K
|
||||||
|
RAM2 (xrw) : ORIGIN = 0x2001C000, LENGTH = 16K
|
||||||
|
RAM3 (xrw) : ORIGIN = 0x20020000, LENGTH = 64K
|
||||||
|
CCMRAM (rw) : ORIGIN = 0x10000000, LENGTH = 64K
|
||||||
|
}
|
||||||
|
|
||||||
|
_stack_start = ORIGIN(CCMRAM) + LENGTH(CCMRAM);
|
|
@ -0,0 +1,10 @@
|
||||||
|
target remote :3333
|
||||||
|
|
||||||
|
# print demangled symbols by default
|
||||||
|
set print asm-demangle on
|
||||||
|
|
||||||
|
monitor tpiu config internal itm.log uart off 168000000
|
||||||
|
monitor itm port 0 on
|
||||||
|
|
||||||
|
load
|
||||||
|
step
|
Loading…
Reference in New Issue