Skip to content
Snippets Groups Projects
Commit e6ed6ab2 authored by Johannes Sjölund's avatar Johannes Sjölund
Browse files

Clocking works with serial and systick

parent eff15834
No related branches found
No related tags found
No related merge requests found
...@@ -17,6 +17,7 @@ use f4::Timer; ...@@ -17,6 +17,7 @@ use f4::Timer;
use f4::led::{self, LED}; use f4::led::{self, LED};
use f4::prelude::*; use f4::prelude::*;
use f4::time::Hertz; use f4::time::Hertz;
use f4::clock;
use rtfm::{app, Threshold}; use rtfm::{app, Threshold};
const FREQUENCY: Hertz = Hertz(1); const FREQUENCY: Hertz = Hertz(1);
...@@ -30,8 +31,10 @@ app! { ...@@ -30,8 +31,10 @@ app! {
} }
fn init(p: init::Peripherals) { fn init(p: init::Peripherals) {
led::init(p.GPIOA, p.RCC); // Set system clock in order to test that it works
clock::set_84_mhz(&p.RCC, &p.FLASH);
led::init(p.GPIOA, p.RCC);
let timer = Timer(&*p.TIM11); let timer = Timer(&*p.TIM11);
timer.init(FREQUENCY.invert(), p.RCC); timer.init(FREQUENCY.invert(), p.RCC);
......
...@@ -3,20 +3,35 @@ ...@@ -3,20 +3,35 @@
#![feature(proc_macro)] #![feature(proc_macro)]
#![no_std] #![no_std]
extern crate cortex_m;
extern crate cortex_m_rtfm as rtfm; extern crate cortex_m_rtfm as rtfm;
extern crate f4; extern crate f4;
use rtfm::app; use rtfm::{app, Threshold};
use f4::led::{self, LED}; use f4::led::{self, LED};
use f4::clock; use f4::clock;
use cortex_m::peripheral::SystClkSource;
const FREQUENCY: u32 = 10; // Hz
// TASKS & RESOURCES // TASKS & RESOURCES
app! { app! {
device: f4::stm32f40x, device: f4::stm32f40x,
resources: {
static ON: bool = false;
},
tasks: {
SYS_TICK: {
path: toggle,
resources: [ON],
},
},
} }
// INITIALIZATION PHASE // INITIALIZATION PHASE
fn init(p: init::Peripherals) { fn init(p: init::Peripherals, _r: init::Resources) {
// See RM0368 6.2.10 Clock-out capability // See RM0368 6.2.10 Clock-out capability
// PC9 outputs SYSCLK/4 MHz and PA8 the frequency of the HSI RC // PC9 outputs SYSCLK/4 MHz and PA8 the frequency of the HSI RC
...@@ -41,22 +56,38 @@ fn init(p: init::Peripherals) { ...@@ -41,22 +56,38 @@ fn init(p: init::Peripherals) {
p.RCC.cfgr.modify(|_, w| unsafe { w.mco2pre().bits(0b110) }); //Divide SYSCLK by 4 p.RCC.cfgr.modify(|_, w| unsafe { w.mco2pre().bits(0b110) }); //Divide SYSCLK by 4
// Set the clock to 84 MHz for compatibility with stm32f401 // Set the clock to 84 MHz for compatibility with stm32f401
clock::set_84_mhz(&p.RCC, &p.FLASH); // let clk = clock::set_84_mhz(&p.RCC, &p.FLASH);
// The stm32f411 supports 100 MHz. // The stm32f411 supports 100 MHz.
// clock::set_100_mhz(&p.RCC, &p.FLASH); let clk = clock::set_100_mhz(&p.RCC, &p.FLASH);
// We can also use a lower frequency by providing valid PLL constants. // We can also use a lower frequency by providing valid PLL constants.
// Since the HSI RC is 16 MHz, we get 16/8*50/4 = 25 MHz // Since the HSI RC is 16 MHz, we get 16/8*50/4 = 25 MHz
// clock::set(&p.RCC, &p.FLASH, 8, 50, 4); // let clk = clock::set(&p.RCC, &p.FLASH, 8, 50, 4);
// Light the green LED when we start idling. // Light the green LED when we start idling.
led::init(&p.GPIOA, &p.RCC); led::init(&p.GPIOA, &p.RCC);
p.SYST.set_clock_source(SystClkSource::Core);
p.SYST.set_reload(clk / FREQUENCY);
p.SYST.enable_interrupt();
p.SYST.enable_counter();
}
// TASKS
// Toggle the state of the LED
fn toggle(_t: &mut Threshold, r: SYS_TICK::Resources) {
**r.ON = !**r.ON;
if **r.ON {
LED.on();
} else {
LED.off();
}
} }
// IDLE LOOP // IDLE LOOP
fn idle() -> ! { fn idle() -> ! {
LED.on();
// Sleep // Sleep
loop { loop {
rtfm::wfi(); rtfm::wfi();
......
...@@ -17,6 +17,7 @@ use f4::Writer as w; ...@@ -17,6 +17,7 @@ use f4::Writer as w;
use f4::prelude::*; use f4::prelude::*;
use f4::dma::{Buffer, Dma1Channel5, Dma1Channel6}; use f4::dma::{Buffer, Dma1Channel5, Dma1Channel6};
use f4::time::Hertz; use f4::time::Hertz;
use f4::clock;
use heapless::Vec; use heapless::Vec;
use rtfm::{app, Threshold}; use rtfm::{app, Threshold};
...@@ -52,7 +53,11 @@ app! { ...@@ -52,7 +53,11 @@ app! {
}, },
}, },
} }
fn init(p: init::Peripherals, r: init::Resources) { fn init(p: init::Peripherals, r: init::Resources) {
// Set clock to higher than default in order to test it works
clock::set_84_mhz(&p.RCC, &p.FLASH);
// There is no need to claim() resources in the init. // There is no need to claim() resources in the init.
// Start the serial port // Start the serial port
let serial = Serial(p.USART2); let serial = Serial(p.USART2);
...@@ -98,8 +103,9 @@ fn rx_done(t: &mut Threshold, mut r: DMA1_STREAM5::Resources) { ...@@ -98,8 +103,9 @@ fn rx_done(t: &mut Threshold, mut r: DMA1_STREAM5::Resources) {
} }
if byte == b'\r' { if byte == b'\r' {
// If we got carrige return, send new line as well // If we got carrige return, send new line as well
if serial.write(b'\n').is_err() { while serial.write(b'\n').is_err() {
rtfm::bkpt(); // Since we just transmitted carrige return,
// we need to wait until tx line is free
} }
} }
// Get ready to receive again // Get ready to receive again
......
...@@ -21,7 +21,7 @@ fn calculate_pll(m: u8, n: u16, p: u8) -> (u32, u32) { ...@@ -21,7 +21,7 @@ fn calculate_pll(m: u8, n: u16, p: u8) -> (u32, u32) {
}, },
_ => panic!("Invalid PLLN multiplier"), _ => panic!("Invalid PLLN multiplier"),
}; };
let log2p = match p { let pval = match p {
2 => 0b00, 2 => 0b00,
4 => 0b01, 4 => 0b01,
6 => 0b10, 6 => 0b10,
...@@ -32,7 +32,7 @@ fn calculate_pll(m: u8, n: u16, p: u8) -> (u32, u32) { ...@@ -32,7 +32,7 @@ fn calculate_pll(m: u8, n: u16, p: u8) -> (u32, u32) {
24_000_000...100_000_000 => vco_clock / p as u32, 24_000_000...100_000_000 => vco_clock / p as u32,
_ => panic!("Invalid PLLP output frequency"), _ => panic!("Invalid PLLP output frequency"),
}; };
let pll_bitmask = ((log2p as u32) << 16) | ((n as u32) << 6) | (m as u32); let pll_bitmask = ((pval as u32) << 16) | ((n as u32) << 6) | (m as u32);
(pll_bitmask, pll_output) (pll_bitmask, pll_output)
} }
...@@ -45,9 +45,12 @@ pub fn set(rcc: &RCC, flash: &FLASH, m: u8, n: u16, p: u8) -> u32 { ...@@ -45,9 +45,12 @@ pub fn set(rcc: &RCC, flash: &FLASH, m: u8, n: u16, p: u8) -> u32 {
// setting up the flash memory latency // setting up the flash memory latency
// RM0368 8.4.1 (register), 3.4 Table 6 // RM0368 8.4.1 (register), 3.4 Table 6
// apb1 will be at 42 MHz // apb1 will be at half system clock
rcc.cfgr.modify(|_, w| unsafe { w.ppre1().bits(4) }); //Configure apb1 prescaler = 2, rcc.cfgr.modify(|_, w| unsafe { w.ppre1().bits(4) }); //Configure apb1 prescaler = 2,
::apb1::set_frequency(hclk / 2); ::apb1::set_frequency(hclk / 2);
::ahb1::set_frequency(hclk);
::ahb2::set_frequency(hclk);
::apb2::set_frequency(hclk);
// we assume 3.3 volt operation, thus 2 cycles for 84MHz // we assume 3.3 volt operation, thus 2 cycles for 84MHz
flash.acr.modify(|_, w| unsafe { flash.acr.modify(|_, w| unsafe {
......
...@@ -22,7 +22,6 @@ use stm32f40x::{gpioa, DMA1, USART2, usart6, GPIOA, RCC}; ...@@ -22,7 +22,6 @@ use stm32f40x::{gpioa, DMA1, USART2, usart6, GPIOA, RCC};
use dma::{self, Buffer, Dma1Channel5, Dma1Channel6}; use dma::{self, Buffer, Dma1Channel5, Dma1Channel6};
use core::fmt; use core::fmt;
use core::iter;
/// ///
pub struct Writer<'a> { pub struct Writer<'a> {
...@@ -237,7 +236,15 @@ where ...@@ -237,7 +236,15 @@ where
usart.cr2.write(|w| unsafe { w.stop().bits(0b00) }); usart.cr2.write(|w| unsafe { w.stop().bits(0b00) });
// baud rate // baud rate
let brr = baud_rate.into(); // Check if peripheral does not use default clock
let apb1psc = match rcc.cfgr.read().ppre1().bits() {
0b100 => 2,
0b101 => 4,
0b110 => 8,
0b111 => 16,
_ => 1,
};
let brr = baud_rate.into() / apb1psc;
assert!(brr >= 16, "impossible baud rate"); assert!(brr >= 16, "impossible baud rate");
usart.brr.write(|w| unsafe { w.bits(brr) }); usart.brr.write(|w| unsafe { w.bits(brr) });
...@@ -394,6 +401,7 @@ impl<'a> Serial<'a, USART2> { ...@@ -394,6 +401,7 @@ impl<'a> Serial<'a, USART2> {
where where
B: Unsize<[u8]>, B: Unsize<[u8]>,
{ {
// write!(dma1, "hi {}", 1);
let usart2 = self.0; let usart2 = self.0;
if dma1.s6cr.read().en().bit_is_set() { if dma1.s6cr.read().en().bit_is_set() {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment