Skip to content
This repository was archived by the owner on Jul 6, 2019. It is now read-only.

Commit 9646397

Browse files
committed
Merge pull request #193 from kvark/stm32l1
Added basic hal implementation for STM32L1
2 parents bbaa81d + 0cfc479 commit 9646397

File tree

14 files changed

+835
-2
lines changed

14 files changed

+835
-2
lines changed

.travis.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,5 @@ env:
1818
matrix:
1919
- PLATFORM=lpc17xx
2020
- PLATFORM=stm32f4
21+
- PLATFORM=stm32l1
2122
- PLATFORM=k20

Rakefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,8 @@ when 'k20'
179179
task :build_all => [:build_blink_k20, :build_blink_k20_isr]
180180
when 'stm32f4'
181181
task :build_all => [:build_blink_stm32f4]
182+
when 'stm32l1'
183+
task :build_all => [:build_blink_stm32l1]
182184
else
183185
task :build_all => [:build_empty, :build_blink]
184186
end

apps/app_blink_stm32l1.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#![feature(phase)]
2+
#![crate_type="staticlib"]
3+
#![no_std]
4+
5+
extern crate core;
6+
extern crate zinc;
7+
8+
#[no_mangle]
9+
pub unsafe fn main() {
10+
use core::default::Default;
11+
use zinc::hal::pin::GPIO;
12+
use zinc::hal::stm32l1::{init, pin, timer};
13+
use zinc::hal::timer::Timer;
14+
zinc::hal::mem_init::init_stack();
15+
zinc::hal::mem_init::init_data();
16+
17+
let sys_clock: init::SystemClockSource = Default::default();
18+
19+
let led1 = pin::Pin::new(pin::PortA, 5,
20+
pin::GpioOut(pin::OutPushPull, pin::VeryLow),
21+
pin::PullNone);
22+
23+
let timer = timer::Timer::new(timer::Timer2, sys_clock.to_speed_khz(), 0);
24+
25+
loop {
26+
led1.set_high();
27+
timer.wait_ms(1);
28+
led1.set_low();
29+
timer.wait_ms(1);
30+
}
31+
}

platforms.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,7 @@ lpc17xx:
44
- mcu_has_spi
55
stm32f4:
66
arch: cortex_m4
7+
stm32l1:
8+
arch: cortex_m3
79
k20:
810
arch: cortex_m4

src/zinc/hal/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ and each such struct has a `setup()` method that configures the hardware
2424

2525
pub mod lpc17xx;
2626
pub mod stm32f4;
27+
pub mod stm32l1;
2728
pub mod k20;
2829

2930
mod cortex_common;

src/zinc/hal/stm32f4/init.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
// See the License for the specific language governing permissions and
1414
// limitations under the License.
1515

16-
//! Routines for initialization of NXP LPC17xx.
16+
//! Routines for initialization of STM32F4.
1717
//!
1818
//! This module includes code for setting up the clock, flash, access time and
1919
//! performing initial peripheral configuration.

src/zinc/hal/stm32f4/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@
1515

1616
//! HAL for STM32F4.
1717
18-
pub mod pin;
1918
pub mod init;
2019
pub mod gpio;
2120
pub mod peripheral_clock;
21+
pub mod pin;
2222
pub mod timer;

src/zinc/hal/stm32l1/init.rs

Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
// Zinc, the bare metal stack for rust.
2+
// Copyright 2014 Dzmitry "kvark" Malyshau <[email protected]>
3+
//
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
//
8+
// http://www.apache.org/licenses/LICENSE-2.0
9+
//
10+
// Unless required by applicable law or agreed to in writing, software
11+
// distributed under the License is distributed on an "AS IS" BASIS,
12+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
// See the License for the specific language governing permissions and
14+
// limitations under the License.
15+
16+
//! Routines for initialization of STM32L1.
17+
//!
18+
//! This module includes code for setting up the clock, flash, access time and
19+
//! performing initial peripheral configuration.
20+
21+
//use hal::mem_init::init_data;
22+
use core::default::Default;
23+
use core::intrinsics::abort;
24+
25+
#[path="../../util/ioreg.rs"] mod ioreg;
26+
#[path="../../util/wait_for.rs"] mod wait_for;
27+
28+
/// Phase-locked loop configuration.
29+
pub struct PllConfig;
30+
31+
/// Multi-speed internal clock divisor.
32+
pub enum MsiSpeed {
33+
/// 65_536 kHz
34+
Msi65 = 0,
35+
/// 131_072 kHz
36+
Msi131 = 1,
37+
/// 262_144 kHz
38+
Msi262 = 2,
39+
/// 524_288 kHz
40+
Msi524 = 3,
41+
/// 1048 MHz
42+
Msi1048 = 4,
43+
/// 2097 MHz
44+
Msi2097 = 5,
45+
/// 4194 MHz
46+
Msi4194 = 6,
47+
}
48+
49+
/// System clock source.
50+
pub enum SystemClockSource {
51+
/// High-speed internal oscillator, 16MHz.
52+
SystemClockHSI,
53+
/// High-speed external oscillator with configurable frequency.
54+
SystemClockHSE(u32),
55+
/// PLL.
56+
SystemClockPLL(PllConfig),
57+
/// Multi-speed internal clock,
58+
SystemClockMSI(MsiSpeed),
59+
}
60+
61+
impl Default for SystemClockSource {
62+
fn default() -> SystemClockSource {
63+
SystemClockMSI(Msi2097)
64+
}
65+
}
66+
67+
impl SystemClockSource {
68+
/// Get the system clock speed in kHz
69+
pub fn to_speed_khz(&self) -> u32 {
70+
match *self {
71+
SystemClockHSI => 16<<10,
72+
SystemClockMSI(Msi2097) => 2097,
73+
_ => unsafe { abort() }, //TODO(kvark)
74+
}
75+
}
76+
}
77+
78+
// TODO(farcaller): this mod is pub as it's being used in peripheral_clock.rs.
79+
// This is not the best design solution and a good reason to
80+
// split RCC into distinct registers.
81+
#[allow(missing_doc)]
82+
pub mod reg {
83+
use util::volatile_cell::VolatileCell;
84+
use core::ops::Drop;
85+
86+
ioregs!(RCC = {
87+
0x00 => reg32 cr { // clock control
88+
31..0 => clock_control : rw,
89+
},
90+
0x04 => reg32 icscr { // internal clock sources calibration
91+
31..0 => clock_calibration : rw,
92+
},
93+
0x08 => reg32 cfgr { // clock configuration
94+
31..0 => clock_config : rw,
95+
},
96+
0x0C => reg32 cir { // clock interrupt
97+
31..0 => clock_interrupt : rw,
98+
},
99+
0x10 => reg32 ahbrstr { // AHB peripheral reset
100+
31..0 => reset : rw,
101+
},
102+
0x14 => reg32 apb2rstr { // APB2 peripheral reset
103+
31..0 => reset : rw,
104+
},
105+
0x18 => reg32 apb1rstr { // APB1 peripheral reset
106+
31..0 => reset : rw,
107+
},
108+
0x1C => reg32 ahbenr { // AHB peripheral clock enable
109+
31..0 => enable : rw,
110+
},
111+
0x20 => reg32 apb2enr { // APB2 peripheral clock enable
112+
31..0 => enable : rw,
113+
},
114+
0x24 => reg32 apb1enr { // ABB1 peripheral clock enable
115+
31..0 => enable : rw,
116+
},
117+
0x28 => reg32 ahblpenr { // AHB peripheral clock enable in low power mode
118+
31..0 => enable_low_power : rw,
119+
},
120+
0x2C => reg32 apb2lpenr { // APB2 peripheral clock enable in low power mode
121+
31..0 => enable_low_power : rw,
122+
},
123+
0x30 => reg32 apb1lpenr { // APB1 peripheral clock enable in low power mode
124+
31..0 => enable_low_power : rw,
125+
},
126+
0x34 => reg32 csr { // control/status
127+
31..0 => status : rw,
128+
},
129+
})
130+
131+
ioregs!(FLASH = {
132+
0x00 => reg32 acr { // access control
133+
31..0 => access_control : rw,
134+
},
135+
0x04 => reg32 pecr { // program/erase control
136+
31..0 => program_control : rw,
137+
},
138+
0x08 => reg32 pdkeyr { // power down key
139+
31..0 => power_down : rw,
140+
},
141+
0x0C => reg32 pekeyr { // program/erase key
142+
31..0 => program_key : rw,
143+
},
144+
0x10 => reg32 prtkeyr { // program memory key
145+
31..0 => program_memory : rw,
146+
},
147+
0x14 => reg32 optkeyr { // option byte key
148+
31..0 => option_byte : rw,
149+
},
150+
0x18 => reg32 sr { // status register
151+
31..0 => status : rw,
152+
},
153+
0x1C => reg32 obr { // option byte
154+
31..0 => option : rw,
155+
},
156+
0x20 => reg32 wrpr { // write protection
157+
31..0 => protect : rw,
158+
},
159+
0x28 => reg32 wrpr1 { // write protection register 1
160+
31..0 => protect : rw,
161+
},
162+
0x2C => reg32 wrpr2 { // write protection register 2
163+
31..0 => protect : rw,
164+
},
165+
})
166+
167+
ioregs!(PWR = {
168+
0x0 => reg32 cr { // power control
169+
31..0 => control : rw,
170+
},
171+
0x4 => reg32 csr { // power control/status
172+
31..0 => status : rw,
173+
},
174+
})
175+
176+
extern {
177+
#[link_name="stm32l1_iomem_RCC"] pub static RCC: RCC;
178+
#[link_name="stm32l1_iomem_FLASH"] pub static FLASH: FLASH;
179+
#[link_name="stm32l1_iomem_PWR"] pub static PWR: PWR;
180+
}
181+
}

src/zinc/hal/stm32l1/iomem.ld

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
INCLUDE ./src/zinc/hal/cortex_m3/armmem.ld
2+
3+
stm32l1_iomem_TIM2 = 0x40000000;
4+
5+
stm32l1_iomem_PWR = 0x40007000;
6+
7+
stm32l1_iomem_FLASH = 0x40023C00;
8+
stm32l1_iomem_RCC = 0x40023800;
9+
10+
stm32l1_iomem_GPIOA = 0x40020000;
11+
stm32l1_iomem_GPIOB = 0x40020400;
12+
stm32l1_iomem_GPIOC = 0x40020800;
13+
stm32l1_iomem_GPIOD = 0x40020c00;
14+
stm32l1_iomem_GPIOE = 0x40021000;
15+
stm32l1_iomem_GPIOF = 0x40021800;
16+
stm32l1_iomem_GPIOG = 0x40021C00;
17+
stm32l1_iomem_GPIOH = 0x40021400;

src/zinc/hal/stm32l1/layout.ld

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
__STACK_BASE = 0x20008000; /* end of ram */
2+
_boot_checksum = 0; /* TODO(farcaller): extract this to lpc code only */
3+
_data_load = LOADADDR(.data);
4+
5+
INCLUDE ./src/zinc/hal/stm32l1/iomem.ld
6+
7+
ENTRY(main)
8+
9+
MEMORY
10+
{
11+
rom(RX) : ORIGIN = 0x08000000, LENGTH = 6 * 64K
12+
ram(WAIL) : ORIGIN = 0x20000000, LENGTH = 32K
13+
}
14+
15+
REGION_ALIAS("vectors", rom);
16+
17+
INCLUDE ./src/zinc/hal/layout_common.ld

src/zinc/hal/stm32l1/mod.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Zinc, the bare metal stack for rust.
2+
// Copyright 2014 Dzmitry "kvark" Malyshau <[email protected]>
3+
//
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
//
8+
// http://www.apache.org/licenses/LICENSE-2.0
9+
//
10+
// Unless required by applicable law or agreed to in writing, software
11+
// distributed under the License is distributed on an "AS IS" BASIS,
12+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
// See the License for the specific language governing permissions and
14+
// limitations under the License.
15+
16+
//! HAL for STM32L1.
17+
18+
pub mod init;
19+
pub mod peripheral_clock;
20+
pub mod pin;
21+
pub mod timer;

0 commit comments

Comments
 (0)