diff --git a/back.txt b/back.txt new file mode 100644 index 0000000..6e85fc1 --- /dev/null +++ b/back.txt @@ -0,0 +1,136 @@ +#![no_std] +#![feature(asm, used, const_fn, naked_functions, alloc, box_syntax)] +#![no_main] +#![feature(extern_prelude)] + +#[macro_use] +extern crate hcl; + +#[macro_use] +extern crate alloc; + +use core::mem; +use hcl::platform::gpio; +use hcl::platform::irq; +use hcl::platform::rcc; +use hcl::platform::scs; +use hcl::platform::timer; +use hcl::platform::usart; +use hcl::platform::dma; +use hcl::dma::*; + +mod printer; + +use printer::UsartPrinter; + +fn configure_clocks(rcc: &mut rcc::RCC) { + rcc.clock_control.set_hse_on(true); + while !rcc.clock_control.hse_ready() { + } + + rcc.clock_config.configure(|c| c + .set_pll_multiplier(10) + .set_pll_source(rcc::PllSource::HsiDiv2)); + + rcc.clock_control.set_pll_on(true); + while !rcc.clock_control.pll_ready() { + } + + rcc.clock_config.switch_clock_source(rcc::SystemClockSource::Pll); +} + +fn configure_peripherals(rcc: &mut hcl::platform::rcc::RCC, + gpio: &mut gpio::GPIO, + usart: &mut usart::USART) { + rcc.apb2_enable.configure(|a| a + .set_gpio_a(true) + .set_spi1(true)); + rcc.apb1_enable.configure(|a| a + .set_usart2(true)); + + gpio.configure(|g| g + .set_mode(2, gpio::PinMode::Output50MHz) + .set_output_config(2, gpio::OutputConfig::AfPushPull) + .set_mode(3, gpio::PinMode::Output50MHz) + .set_output_config(3, gpio::OutputConfig::AfPushPull) + // SCK1 + .set_mode(5, gpio::PinMode::Output50MHz) + .set_output_config(5, gpio::OutputConfig::AfPushPull) + // MOSI1 + .set_mode(7, gpio::PinMode::Output50MHz) + .set_output_config(7, gpio::OutputConfig::AfPushPull) + // MISO1 + .set_mode(6, gpio::PinMode::Input) + .set_input_config(6, gpio::InputConfig::PullUpDown) + // NSS1 + .set_mode(4, gpio::PinMode::Output50MHz) + .set_output_config(4, gpio::OutputConfig::PushPull)); + + usart.configure(|u| u + .set_enabled(true) + .set_tx_enabled(true) + .set_baudgen((21, 11))); // 115.2 kbaud +} + + + +// allowing inlining into main() breaks the stack, since main() must be naked to set up a process stack. +#[inline(never)] +fn run(mut scs: scs::Instance, mut p: hcl::platform::Instance) { + configure_clocks(&mut p.rcc); + configure_peripherals(&mut p.rcc, &mut p.gpio_a, &mut p.usart2); + + let mut printer = UsartPrinter::init(p.usart2); + + let mut spi = p.spi1; + spi.configure(|s| s + .set_enabled(true) + .set_master_mode(true) + .set_slave_select_output_enabled(true) + .set_bidi_tx(false) + .set_clock_divider(128) + .set_data_16bit(true) + .set_clock_idles_high(false) + .set_lsb_first(false) + .set_clock_skip_first(true)); + + loop { + + p.gpio_a.reset_bit(4); + spi.set_data(0xFFFF); + + while !spi.rx_buffer_not_empty() { + } + + let i = spi.data() >> 3; + let temp = (i as f32) * 0.25; + + while spi.busy() { + } + p.gpio_a.set_bit(4); + + + + let x = format!("> {}\r\n", temp).into_bytes(); + + printer.print(x); + + for y in 0u32..0xFFFFFF { + unsafe { asm!("nop" :::: "volatile") }; + } + + } +} + + +entry_point!(main); +fn main(scs: scs::Instance, p: hcl::platform::Instance) { + declare_thread_stack!(stack, 4096); + + unsafe { + hcl::set_process_stack(&stack); + hcl::use_process_stack(true); + } + + run(scs, p); +} diff --git a/hcl b/hcl index 9dc33a9..001d44d 160000 --- a/hcl +++ b/hcl @@ -1 +1 @@ -Subproject commit 9dc33a9abadbde8e0c2ffc853a35feaf6990c143 +Subproject commit 001d44d6b9693a9ad3fd6fc8bc44e8dc22ad7149 diff --git a/openocd.sh b/openocd.sh new file mode 100755 index 0000000..7d889ae --- /dev/null +++ b/openocd.sh @@ -0,0 +1,2 @@ +#!/bin/bash +openocd -f interface/stlink-v2.cfg -f target/stm32f1x.cfg diff --git a/run.sh b/run.sh new file mode 100755 index 0000000..8c7da25 --- /dev/null +++ b/run.sh @@ -0,0 +1,3 @@ +#!/bin/bash +cargo build --target=thumbv7m-none-eabi || exit -1 +arm-none-eabi-gdb target/thumbv7m-none-eabi/debug/reflow-firmware diff --git a/src/main.rs b/src/main.rs index f697c6c..fb0dec4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -50,9 +50,6 @@ hcl_ivt!{ systick => systick::isr; } - - - fn configure_peripherals(rcc: &mut hcl::platform::rcc::RCC, gpio_a: &mut gpio::GPIO, gpio_c: &mut gpio::GPIO, @@ -75,12 +72,21 @@ fn configure_peripherals(rcc: &mut hcl::platform::rcc::RCC, // MISO1 .set_mode(6, gpio::PinMode::Input) .set_input_config(6, gpio::InputConfig::PullUpDown) - // ??? - .set_mode(4, gpio::PinMode::Output50MHz) - .set_output_config(4, gpio::OutputConfig::PushPull) // SS MAX6675 .set_mode(9, gpio::PinMode::Output50MHz) .set_output_config(9, gpio::OutputConfig::PushPull) + // ST7735 cs pin + .set_mode(0, gpio::PinMode::Output50MHz) + .set_output_config(0, gpio::OutputConfig::PushPull) + // ST7735 rst pin + .set_mode(1, gpio::PinMode::Output50MHz) + .set_output_config(1, gpio::OutputConfig::PushPull) + // ST7735 rs pin + .set_mode(4, gpio::PinMode::Output50MHz) + .set_output_config(4, gpio::OutputConfig::PushPull) + // ST7735 led pin + .set_mode(8, gpio::PinMode::Output50MHz) + .set_output_config(8, gpio::OutputConfig::PushPull) }); gpio_c.configure(|g| { @@ -104,7 +110,7 @@ fn run(mut scs: scs::Instance, mut p: hcl::platform::Instance) { systick::configure(&mut scs.systick); configure_peripherals(&mut p.rcc, &mut p.gpio_a, &mut p.gpio_c, &mut p.usart2); - let mut printer = UsartPrinter::init(p.usart2); + //let mut printer = UsartPrinter::init(p.usart2); let mut spi = p.spi1; @@ -113,12 +119,22 @@ fn run(mut scs: scs::Instance, mut p: hcl::platform::Instance) { let mut st7735 = st7735::St7735::new(st7735::DisplayType::RED_18_BLACKTAB, 0, 1, 4, 8); let mut st7735io = st7735.start(spi, gpio); - st7735io.init(); + loop { + st7735io.init(); + st7735io.fill_rect(0, 0, 128, 160, 0x00, 0x00); + st7735io.fill_rect(4, 4, 60, 76, 0x00, 0x1F); + st7735io.fill_rect(4, 80, 60, 76, 0xF8, 0x00); + st7735io.fill_rect(64, 4, 60, 76, 0x07, 0xE0); + st7735io.fill_rect(64, 80, 60, 76, 0xFF, 0xE0); + systick::delay_ms(2000); + } let (st7735, mut spi, mut gpio) = st7735io.done(); - + /* loop { + + let res = max6675::read(&mut spi, &mut gpio, 9); let msg = match res { @@ -133,6 +149,7 @@ fn run(mut scs: scs::Instance, mut p: hcl::platform::Instance) { systick::delay_ms(1000); } + */ } diff --git a/src/st7735.rs b/src/st7735.rs index f6242e6..b5a70d2 100644 --- a/src/st7735.rs +++ b/src/st7735.rs @@ -68,7 +68,7 @@ enum Command { GMCTRN1([u8; 16]), } -fn command_to_byte(cmd : Command) -> u8 { +fn command_to_byte(cmd : &Command) -> u8 { match cmd { Command::NOP => 0x00, Command::SWRESET => 0x01, @@ -169,7 +169,7 @@ const ST7735_BLUE_INIT : [(Command, u32); 18] = [ // Init for 7735R, part 1 (red or green tab) -const ST7735_RED_INIT : [(Command, u32); 15] = [ +const ST7735_RED_INIT1 : [(Command, u32); 15] = [ (Command::SWRESET, 150), // 1: Software reset, 150ms delay (Command::SLPOUT, 500), // 2: Out of sleep mode (Command::FRMCTR1([0x01, 0x2C, 0x2D]), 0), // 3: Frame rate ctrl - normal mode @@ -347,10 +347,9 @@ impl St7735IO GPIOAddr: Location { spi.configure(|s| { - s.set_enabled(true) - .set_master_mode(true) + s.set_master_mode(true) .set_software_slave_select(true) - .set_clock_divider(128) + .set_clock_divider(8) // required for master mode, even if ss is done manually .set_slave_select_output_enabled(true) }); @@ -409,11 +408,14 @@ impl St7735IO } fn write_byte(&mut self, byte : u8) { + self.spi.set_enabled(true); self.spi.set_data(byte as u32); + while !self.spi.rx_buffer_not_empty() {} while self.spi.busy() {} + self.spi.set_enabled(false); } - fn write_data_byte(&mut self, data : u8) { + pub fn write_data_byte(&mut self, data : u8) { self.set_rs(); self.reset_cs(); @@ -421,28 +423,156 @@ impl St7735IO self.set_cs(); } - fn write_command_byte(&mut self, cmd : u8) { + pub fn write_color_bytes(&mut self, data0 : u8, data1 : u8) { self.set_rs(); + self.reset_cs(); + self.write_byte(data0); + self.write_byte(data1); + self.set_cs(); + } + + fn write_command_byte(&mut self, cmd : u8) { + self.reset_rs(); + self.reset_cs(); self.write_byte(cmd); self.set_cs(); } - pub fn write_command(&mut self, cmd : Command) { + pub fn write_command(&mut self, cmd : &Command) { let cmd_byte = command_to_byte(cmd); self.write_command_byte(cmd_byte); - + match cmd { + Command::COLMOD(arg) | + Command::MADCTL(arg) | + Command::INVCTR(arg) | + Command::PWCTR2(arg) => self.write_data_byte(*arg), + + Command::DISSET5(args) | + Command::PWCTR3(args) | + Command::PWCTR4(args) | + Command::PWCTR5(args) | + Command::PWCTR6(args) | + Command::VMCTR1(args) | + Command::PWCTR1(args) => { + for &arg in args.iter() { + self.write_data_byte(arg); + } + }, + + Command::CASET(args) | + Command::RASET(args) => { + for &arg in args.iter() { + self.write_data_byte(arg); + } + }, + + Command::FRMCTR1(args) | + Command::FRMCTR2(args) => { + for &arg in args.iter() { + self.write_data_byte(arg); + } + }, + + Command::FRMCTR3(args) => { + for &arg in args.iter() { + self.write_data_byte(arg); + } + }, + + Command::GMCTRP1(args) | + Command::GMCTRN1(args) => { + for &arg in args.iter() { + self.write_data_byte(arg); + } + }, + + _ => () + } } + fn run_commands(&mut self, cmds: &[(Command, u32)]) { + for &(ref cmd, ref delay) in cmds.iter() { + self.write_command(cmd); + delay_ms(*delay); + } + } + + pub fn init(&mut self) { + self.enable_led(); + self.reset(); + + match self.st7735.display_type { + DisplayType::BLUE => { + self.run_commands(&ST7735_BLUE_INIT); + }, + DisplayType::RED_18_GREENTAB => { + self.run_commands(&ST7735_RED_INIT1); + self.run_commands(&ST7735_RED_INIT_GREEN2); + self.run_commands(&ST7735_RED_INIT3); + }, + DisplayType::RED_18_REDTAB => { + self.run_commands(&ST7735_RED_INIT1); + self.run_commands(&ST7735_RED_INIT_RED2); + self.run_commands(&ST7735_RED_INIT3); + }, + DisplayType::RED_18_BLACKTAB => { + self.run_commands(&ST7735_RED_INIT1); + self.run_commands(&ST7735_RED_INIT_RED2); + self.run_commands(&ST7735_RED_INIT3); + // Change MADCTL color filter for black + self.write_command(&Command::MADCTL(0xC0)); + }, + DisplayType::RED144_GREENTAB => { + self.run_commands(&ST7735_RED_INIT1); + self.run_commands(&ST7735_RED_INIT_GREEN1442); + self.run_commands(&ST7735_RED_INIT3); + } + } } + pub fn set_addr_win(&mut self, x0 : u8, y0 : u8, x1 : u8, y1 : u8) { + let xstart = x0 + self.st7735.column_start; + let xend = x1 + self.st7735.column_start; + self.write_command(&Command::CASET([0x00, + xstart, + 0x00, + xend])); // Column addr set + + let ystart = y0 + self.st7735.row_start; + let yend = y1 + self.st7735.row_start; + self.write_command(&Command::RASET([0x00, + ystart, + 0x00, + yend])); // Column addr set + + self.write_command(&Command::RAMWR); // write to RAM + } + + pub fn fill_rect(&mut self, x : u8, y : u8, w : u8, h : u8, c1 : u8, c2 : u8) { + + self.set_addr_win(x, y, x + w - 1, y + h - 1); + + self.set_rs(); + self.reset_cs(); + + for i in 0..h { + for j in 0..w { + self.write_byte(c1); + self.write_byte(c2); + } + } + + self.set_cs(); + } + + pub fn done(mut self) -> (St7735, PeripheralRef, PeripheralRef) { self.set_cs(); - self.spi.set_enabled(false); (self.st7735, self.spi, self.gpio) } }