Bluepill Page
Introduction
This page is for the STM32F103C8T6 or Bluepill
Counterfeit Pills
Most of the boards bought of Aliexpress are fake and as such have issues. The ST-Link v2 appears to have issues.
Arduino IDE
To get these to work in Arduino I needed to follow the guides which refer to using
https://dan.drown.org/stm32duino/package_STM32duino_index.json
This is added to the Additional Board Manager URL and allows you to use Generic STM32F103C6/fake STM32F103C8
Using pcf8574 on a Bluepill
Good not get this to work on the Bluepill. It is a dodgey one. I did get it to work on an ESP32 with no issue so I guess it is board related. One thing that I did notice was I needed to turn the pot to make it work on the ESP32.
Rust Blink
Took a while to get this going. It is quite easy once you know.
Code
//! Blinks an LED
//!
//! This assumes that a LED is connected to pc13 as is the case on the blue pill board.
//!
//! Note: Without additional hardware, PC13 should not be used to drive an LED, see page 5.1.2 of
//! the reference manual for an explanation. This is not an issue on the blue pill.
#![deny(unsafe_code)]
#![no_std]
#![no_main]
use panic_halt as _;
use nb::block;
use cortex_m_rt::entry;
use stm32f1xx_hal::{pac, prelude::*, timer::Timer};
#[entry]
fn main() -> ! {
// Get access to the core peripherals from the cortex-m crate
let cp = cortex_m::Peripherals::take().unwrap();
// Get access to the device specific peripherals from the peripheral access crate
let dp = pac::Peripherals::take().unwrap();
// Take ownership over the raw flash and rcc devices and convert them into the corresponding
// HAL structs
let mut flash = dp.FLASH.constrain();
let rcc = dp.RCC.constrain();
// Freeze the configuration of all the clocks in the system and store the frozen frequencies in
// `clocks`
let clocks = rcc.cfgr.freeze(&mut flash.acr);
// Acquire the GPIOC peripheral
let mut gpioc = dp.GPIOC.split();
// Configure gpio C pin 13 as a push-pull output. The `crh` register is passed to the function
// in order to configure the port. For pins 0-7, crl should be passed instead.
let mut led = gpioc.pc13.into_push_pull_output(&mut gpioc.crh);
// Configure the syst timer to trigger an update every second
let mut timer = Timer::syst(cp.SYST, &clocks).counter_hz();
timer.start(1.Hz()).unwrap();
// Wait for the timer to trigger an update and change the state of the LED
loop {
block!(timer.wait()).unwrap();
block!(timer.wait()).unwrap();
block!(timer.wait()).unwrap();
led.set_high();
block!(timer.wait()).unwrap();
led.set_low();
}
}
Cargo
Here is the toml on the 20-Jan-2024, thanks Mikhail
[package]
name = "rustpill"
version = "0.1.0"
authors = ["Mikhail Perov <bthkn@icloud.com>"]
edition = "2021"
description = "Rust STM32 hello world"
[dependencies]
cortex-m = "0.7.2"
cortex-m-rt = "0.7.3"
cortex-m-semihosting = "0.5.0"
embedded-hal = "1.0.0"
nb = "1.0.0"
panic-halt = "0.2.0"
[dependencies.stm32f1xx-hal]
version = "0.10.0"
features = ["rt", "stm32f103", "medium"]
Memory.x
Possibly the reason it did not work previously but either way the FLASH and RAM have been change to cater for the fact this is a conterfeit
/* STM32F103C8T6 */
MEMORY
{
FLASH : ORIGIN = 0x08000000, LENGTH = 32K
RAM : ORIGIN = 0x20000000, LENGTH = 10K
}
/* This is where the call stack will be allocated. */
/* The stack is of the full descending type. */
/* NOTE Do NOT modify `_stack_start` unless you know what you are doing */
/* _stack_start = ORIGIN(RAM) + LENGTH(RAM); */
Cargo Config
[target.thumbv7m-none-eabi]
runner = "arm-none-eabi-gdb -x openocd.gdb"
rustflags = [
# LLD (shipped with the Rust toolchain) is used as the default linker
"-C", "link-arg=-Tlink.x",
]
[build]
target = "thumbv7m-none-eabi" # Cortex-M3
Running
Here is my openocd config for starting openocd
# This is an genericBoard board with a single STM32F103C6Tx chip
#
# Generated by STM32CubeIDE
# Take care that such file, as generated, may be overridden without any early notice. Please have a look to debug launch configuration setup(s)
source [find interface/stlink-dap.cfg]
set WORKAREASIZE 0x2800
transport select "dapdirect_swd"
set CHIPNAME STM32F103C6Tx
set BOARDNAME genericBoard
# Enable debug when in low power modes
set ENABLE_LOW_POWER 1
# Stop Watchdog counters when halt
set STOP_WATCHDOG 1
# STlink Debug clock frequency
set CLOCK_FREQ 4000
# Reset configuration;shutdown"
# use software system reset if reset done
reset_config none
set CONNECT_UNDER_RESET 0
set CORE_RESET 0
# ACCESS PORT NUMBER
set AP_NUM 0
# GDB PORT
set GDB_PORT 3333
# BCTM CPU variables
source [find target/stm32f1x.cfg]
Plug in the ST-Link v2 and to run the example (remember not much flash)
cargo build --release cargo run --release
On the debugger you run
openocd -f start.cfg