Just dumping all the current work
This commit is contained in:
8
blink/Cargo.lock
generated
8
blink/Cargo.lock
generated
@@ -4,6 +4,7 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"arduino 0.1.0",
|
||||
"core 0.1.0",
|
||||
"rustc_builtins 0.1.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -17,3 +18,10 @@ dependencies = [
|
||||
name = "core"
|
||||
version = "0.1.0"
|
||||
|
||||
[[package]]
|
||||
name = "rustc_builtins"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"core 0.1.0",
|
||||
]
|
||||
|
||||
|
||||
@@ -3,8 +3,21 @@ name = "blink"
|
||||
version = "0.1.0"
|
||||
authors = ["Jake Goulding <jake.goulding@gmail.com>"]
|
||||
|
||||
[profile.release]
|
||||
lto = true
|
||||
|
||||
# [dependencies]
|
||||
# rlibc = "*"
|
||||
|
||||
[dependencies.core]
|
||||
path = "../libcore"
|
||||
path = "../rust-avr-libcore-mini"
|
||||
|
||||
[dependencies.arduino]
|
||||
path = "../arduino"
|
||||
|
||||
# [dependencies.compiler-rt]
|
||||
# git = "https://github.com/japaric/compiler-rt.rs"
|
||||
|
||||
|
||||
[dependencies.rustc_builtins]
|
||||
path = "/Users/shep/Projects/rustc-builtins"
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
COMPILED:=target/arduino/release/blink.elf
|
||||
HEX:=blink.hex
|
||||
SERIAL_PORT:=/dev/cu.usbmodem1411
|
||||
|
||||
all: ${HEX}
|
||||
|
||||
@@ -14,4 +15,8 @@ ${HEX}: ${COMPILED}
|
||||
# Download the HEX to the board
|
||||
.PHONY: program
|
||||
program: ${HEX}
|
||||
avrdude -p atmega328p -c arduino -P /dev/cu.usbmodem1411 -U flash:w:$<:i
|
||||
avrdude -p atmega328p -c arduino -P ${SERIAL_PORT} -U flash:w:$<:i
|
||||
|
||||
.PHONY: connect-terminal
|
||||
connect-terminal:
|
||||
picocom ${SERIAL_PORT}
|
||||
|
||||
@@ -1,50 +1,58 @@
|
||||
{
|
||||
"llvm-target": "avr-atmel-none",
|
||||
"cpu": "atmega328p",
|
||||
|
||||
"target-endian": "little",
|
||||
"target-pointer-width": "16",
|
||||
"os": "none",
|
||||
"target-env": "gnu",
|
||||
"target-vendor": "unknown",
|
||||
"arch": "avr",
|
||||
"data-layout": "e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8-i64:8:8-f32:8:8-f64:8:8-n8",
|
||||
"data-layout": "e-p:16:16:16-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-n8",
|
||||
|
||||
"executables": true,
|
||||
|
||||
"linker": "avr-gcc",
|
||||
"pre-link-args": [
|
||||
"-mmcu=atmega328p",
|
||||
"-nostartfiles",
|
||||
"../interrupt_vector.S"
|
||||
],
|
||||
"linker-flavor": "gcc",
|
||||
"pre-link-args": {
|
||||
"gcc": [
|
||||
"-mmcu=atmega328p",
|
||||
"-nostartfiles",
|
||||
"../interrupt_vector.S",
|
||||
"../initialize_memory.S"
|
||||
]
|
||||
},
|
||||
"exe-suffix": ".elf",
|
||||
"post-link-args": [
|
||||
"-Wl,--entry=main",
|
||||
"-Wl,--entry=_ivr_irq0",
|
||||
"-Wl,--entry=_ivr_irq1",
|
||||
"-Wl,--entry=_ivr_pin_change_0",
|
||||
"-Wl,--entry=_ivr_pin_change_1",
|
||||
"-Wl,--entry=_ivr_pin_change_2",
|
||||
"-Wl,--entry=_ivr_watchdog_timer",
|
||||
"-Wl,--entry=_ivr_timer2_compare_a",
|
||||
"-Wl,--entry=_ivr_timer2_compare_b",
|
||||
"-Wl,--entry=_ivr_timer2_overflow",
|
||||
"-Wl,--entry=_ivr_timer1_capture",
|
||||
"-Wl,--entry=_ivr_timer1_compare_a",
|
||||
"-Wl,--entry=_ivr_timer1_compare_b",
|
||||
"-Wl,--entry=_ivr_timer1_overflow",
|
||||
"-Wl,--entry=_ivr_timer0_compare_a",
|
||||
"-Wl,--entry=_ivr_timer0_compare_b",
|
||||
"-Wl,--entry=_ivr_timer0_overflow",
|
||||
"-Wl,--entry=_ivr_spi_transfer_complete",
|
||||
"-Wl,--entry=_ivr_usart_rx_complete",
|
||||
"-Wl,--entry=_ivr_usart_udr_empty",
|
||||
"-Wl,--entry=_ivr_usart_tx_complete",
|
||||
"-Wl,--entry=_ivr_adc_conversion_complete",
|
||||
"-Wl,--entry=_ivr_eeprom_ready",
|
||||
"-Wl,--entry=_ivr_analog_comparator",
|
||||
"-Wl,--entry=_ivr_two_wire_serial_interface",
|
||||
"-Wl,--entry=_ivr_store_program_memory_ready"
|
||||
],
|
||||
"post-link-args": {
|
||||
"gcc": [
|
||||
"-Wl,--entry=main",
|
||||
"-Wl,--entry=_ivr_irq0",
|
||||
"-Wl,--entry=_ivr_irq1",
|
||||
"-Wl,--entry=_ivr_pin_change_0",
|
||||
"-Wl,--entry=_ivr_pin_change_1",
|
||||
"-Wl,--entry=_ivr_pin_change_2",
|
||||
"-Wl,--entry=_ivr_watchdog_timer",
|
||||
"-Wl,--entry=_ivr_timer2_compare_a",
|
||||
"-Wl,--entry=_ivr_timer2_compare_b",
|
||||
"-Wl,--entry=_ivr_timer2_overflow",
|
||||
"-Wl,--entry=_ivr_timer1_capture",
|
||||
"-Wl,--entry=_ivr_timer1_compare_a",
|
||||
"-Wl,--entry=_ivr_timer1_compare_b",
|
||||
"-Wl,--entry=_ivr_timer1_overflow",
|
||||
"-Wl,--entry=_ivr_timer0_compare_a",
|
||||
"-Wl,--entry=_ivr_timer0_compare_b",
|
||||
"-Wl,--entry=_ivr_timer0_overflow",
|
||||
"-Wl,--entry=_ivr_spi_transfer_complete",
|
||||
"-Wl,--entry=_ivr_usart_rx_complete",
|
||||
"-Wl,--entry=_ivr_usart_udr_empty",
|
||||
"-Wl,--entry=_ivr_usart_tx_complete",
|
||||
"-Wl,--entry=_ivr_adc_conversion_complete",
|
||||
"-Wl,--entry=_ivr_eeprom_ready",
|
||||
"-Wl,--entry=_ivr_analog_comparator",
|
||||
"-Wl,--entry=_ivr_two_wire_serial_interface",
|
||||
"-Wl,--entry=_ivr_store_program_memory_ready"
|
||||
]
|
||||
},
|
||||
|
||||
"no-compiler-rt": true
|
||||
}
|
||||
|
||||
@@ -1,17 +1,22 @@
|
||||
#![feature(lang_items)]
|
||||
#![feature(no_core)]
|
||||
#![feature(asm)]
|
||||
#![feature(naked_functions)]
|
||||
#![feature(abi_avr_interrupt)]
|
||||
|
||||
#![no_core]
|
||||
#![no_main]
|
||||
|
||||
#[macro_use]
|
||||
extern crate core;
|
||||
extern crate arduino;
|
||||
extern crate rustc_builtins;
|
||||
|
||||
use core::prelude::v1::*;
|
||||
use core::ptr::{read_volatile, write_volatile};
|
||||
// Let's pretend to have a standard library
|
||||
pub use core::{option, iter};
|
||||
pub use core::{option, iter, fmt, ops};
|
||||
use core::fmt::Write;
|
||||
|
||||
use arduino::*;
|
||||
use arduino::prelude::*;
|
||||
@@ -29,52 +34,214 @@ pub unsafe extern "avr-interrupt" fn _ivr_timer1_compare_a() {
|
||||
}
|
||||
|
||||
const CPU_FREQUENCY_HZ: u64 = 16_000_000;
|
||||
const DESIRED_HZ_TIM1: f64 = 1.0;
|
||||
const TIM1_PRESCALER: u64 = 1024;
|
||||
const INTERRUPT_EVERY_1_HZ_1024_PRESCALER: u16 = ((CPU_FREQUENCY_HZ as f64 / (DESIRED_HZ_TIM1 * TIM1_PRESCALER as f64)) as u64 - 1) as u16;
|
||||
const CPU_RAM_BYTES: u16 = 2048;
|
||||
|
||||
const DESIRED_HZ_TIM0: f64 = 30.0;
|
||||
const TIM0_PRESCALER: u64 = 1024;
|
||||
const INTERRUPT_EVERY_30_HZ_1024_PRESCALER: u8 = ((CPU_FREQUENCY_HZ as f64 / (DESIRED_HZ_TIM0 * TIM0_PRESCALER as f64)) as u64 - 1) as u8;
|
||||
const DESIRED_HZ_TIM1: f64 = 2.0;
|
||||
const TIM1_PRESCALER: u64 = 1024;
|
||||
const INTERRUPT_EVERY_1_HZ_1024_PRESCALER: u16 =
|
||||
((CPU_FREQUENCY_HZ as f64 / (DESIRED_HZ_TIM1 * TIM1_PRESCALER as f64)) as u64 - 1) as u16;
|
||||
|
||||
// const DESIRED_HZ_TIM0: f64 = 30.0;
|
||||
// const TIM0_PRESCALER: u64 = 1024;
|
||||
// const INTERRUPT_EVERY_30_HZ_1024_PRESCALER: u8 = ((CPU_FREQUENCY_HZ as f64 / (DESIRED_HZ_TIM0 * TIM0_PRESCALER as f64)) as u64 - 1) as u8;
|
||||
|
||||
const BAUD: u64 = 9600;
|
||||
const MYUBRR: u16 = (CPU_FREQUENCY_HZ / 16 / BAUD - 1) as u16;
|
||||
|
||||
#[no_mangle]
|
||||
pub extern fn main() {
|
||||
// const MEMORY_MAP_START: u16 = MEMORY_MAP_REGISTERS_START;
|
||||
// const MEMORY_MAP_REGISTERS_START: u16 = 0x0000; // - 0x001F
|
||||
// const MEMORY_MAP_IO_REGISTERS_START: u16 = 0x0020; // - 0x005F
|
||||
// const MEMORY_MAP_EXTENDED_IO_REGISTERS_START: u16 = 0x0060; // - 0x00FF
|
||||
// const MEMORY_MAP_SRAM_START: u16 = 0x0100;
|
||||
// const MEMORY_MAP_SRAM_END: u16 = 0x0900; // EXCLUSIVE! DEPENDS ON PART!
|
||||
// 0x02FF/0x04FF/0x4FF/0x08FF
|
||||
|
||||
|
||||
|
||||
// extern {
|
||||
// static __data_start: u16;
|
||||
// static __data_end: u16;
|
||||
// static __data_load_start: u16;
|
||||
// static __data_load_end: u16;
|
||||
// }
|
||||
|
||||
extern {
|
||||
#[naked]
|
||||
fn __initialize_memory();
|
||||
}
|
||||
|
||||
fn initialize_memory() {
|
||||
unsafe {
|
||||
without_interrupts(|| {
|
||||
__initialize_memory();
|
||||
}
|
||||
|
||||
// let len = __data_load_end - __data_load_start;
|
||||
// if len == 0 { return }
|
||||
|
||||
// fn hi_lo(v: u16) -> (u8, u8) {
|
||||
// (((v >> 8) & 0xFF) as u8, ((v >> 0) & 0xFF) as u8)
|
||||
// }
|
||||
|
||||
// let (len_hi, len_lo) = hi_lo(len);
|
||||
// let (z_hi, z_lo) = hi_lo(__data_load_start);
|
||||
// let (x_hi, x_lo) = hi_lo(__data_start);
|
||||
|
||||
// unsafe {
|
||||
// asm!("
|
||||
// sub r28, r30
|
||||
// sbc r29, r31 ; Y now contains the length of bytes
|
||||
// entrypoint:
|
||||
// lpm r0, Z+ ; Load from program memory, increment pointer
|
||||
// st X+, r0 ; Store to RAM, increment pointer
|
||||
|
||||
// subi r28, 1 ; Decrement the count
|
||||
// sbci r29, 0
|
||||
// check:
|
||||
// brne entrypoint ; Exit when all bytes copied"
|
||||
// : // output operands
|
||||
// : // input operands
|
||||
// "{r31r30}"(__data_load_start) // Z
|
||||
// "{r27r26}"(__data_start) // X
|
||||
// "{r29r28}"(__data_load_end) // Y
|
||||
// : // clobbers
|
||||
// "cc r0"
|
||||
// : // options
|
||||
// );
|
||||
|
||||
// let src = __data_start as *mut u8;
|
||||
// let dest = __data_load_start as *mut u8;
|
||||
// let len = __data_load_end - __data_load_start;
|
||||
|
||||
// let src = 00800100 as *mut u8;
|
||||
// let dest = 00000126 as *mut u8;
|
||||
// let len = 00000136 - 00000124;
|
||||
|
||||
// let dest = __data_start as *mut u8;
|
||||
// let src = __data_load_start as *mut u8;
|
||||
// let end = __data_load_end as *mut u8;
|
||||
|
||||
// 0x0118
|
||||
// 0x0128
|
||||
|
||||
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern fn main() -> ! {
|
||||
without_interrupts(|| { // TODO: we know interrupts are off, don't we?
|
||||
// r1 is assumed to be always zero
|
||||
unsafe { asm!("eor r1, r1"); }
|
||||
|
||||
unsafe {
|
||||
write_volatile(SP, CPU_RAM_BYTES);
|
||||
}
|
||||
|
||||
initialize_memory();
|
||||
|
||||
unsafe {
|
||||
// Configure all Port B pins as outputs
|
||||
write_volatile(DDRB, 0xFF);
|
||||
// Turn on all Port B pins
|
||||
write_volatile(PORTB, 0xFF);
|
||||
}
|
||||
|
||||
timer0::Timer::new()
|
||||
.waveform_generation_mode(timer0::WaveformGenerationMode::ClearOnTimerMatchOutputCompare)
|
||||
.clock_source(timer0::ClockSource::Prescale1024)
|
||||
.output_compare_1(Some(INTERRUPT_EVERY_30_HZ_1024_PRESCALER))
|
||||
.configure();
|
||||
timer1::Timer::new()
|
||||
.waveform_generation_mode(timer1::WaveformGenerationMode::ClearOnTimerMatchOutputCompare)
|
||||
.clock_source(timer1::ClockSource::Prescale1024)
|
||||
.output_compare_1(Some(INTERRUPT_EVERY_1_HZ_1024_PRESCALER))
|
||||
.configure();
|
||||
|
||||
timer1::Timer::new()
|
||||
.waveform_generation_mode(timer1::WaveformGenerationMode::ClearOnTimerMatchOutputCompare)
|
||||
.clock_source(timer1::ClockSource::Prescale1024)
|
||||
.output_compare_1(Some(INTERRUPT_EVERY_1_HZ_1024_PRESCALER))
|
||||
.configure();
|
||||
serial::Serial::new(MYUBRR)
|
||||
.character_size(serial::CharacterSize::EightBits)
|
||||
.mode(serial::Mode::Asynchronous)
|
||||
.parity(serial::Parity::Disabled)
|
||||
.stop_bits(serial::StopBits::OneBit)
|
||||
.configure();
|
||||
});
|
||||
|
||||
serial::Serial::new(MYUBRR)
|
||||
.character_size(serial::CharacterSize::EightBits)
|
||||
.mode(serial::Mode::Asynchronous)
|
||||
.parity(serial::Parity::Disabled)
|
||||
.stop_bits(serial::StopBits::OneBit)
|
||||
.configure();
|
||||
});
|
||||
serial::transmit(b'A');
|
||||
|
||||
for &b in b"hello, world!" {
|
||||
write_newline();
|
||||
for i in 0..4 {
|
||||
let b = unsafe { *TO_HEX.get_unchecked(i) };
|
||||
serial::transmit(b);
|
||||
}
|
||||
write_newline();
|
||||
|
||||
write_u8_hex(0x00);
|
||||
write_newline();
|
||||
write_u8_hex(0x05);
|
||||
write_newline();
|
||||
write_u8_hex(0x50);
|
||||
write_newline();
|
||||
write_u8_hex(0xFF);
|
||||
write_newline();
|
||||
|
||||
write_slice_hex(&[0x00, 0x05, 0x50, 0xFF]);
|
||||
write_newline();
|
||||
|
||||
write_raw("write_raw");
|
||||
|
||||
SuperSerial.write_str("write_str\r\n").unwrap();
|
||||
|
||||
// Formatting code disabled in libcore
|
||||
writeln!(SuperSerial, "writeln!").unwrap();
|
||||
write_newline();
|
||||
|
||||
serial::transmit(b'Z');
|
||||
write_newline();
|
||||
|
||||
loop {
|
||||
if let Some(b) = serial::try_receive() {
|
||||
serial::transmit(b);
|
||||
serial::transmit(b'<');
|
||||
}
|
||||
|
||||
loop {
|
||||
// forever!
|
||||
}
|
||||
// forever!
|
||||
}
|
||||
}
|
||||
|
||||
pub static TO_HEX: &'static [u8; 16] = b"0123456789ABCDEF";
|
||||
|
||||
#[inline(never)]
|
||||
pub fn write_slice_hex(v: &[u8]) {
|
||||
for &b in v {
|
||||
write_u8_hex(b);
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
pub fn write_u8_hex(v: u8) {
|
||||
let top_idx = (v >> 4) & 0b1111;
|
||||
let bot_idx = (v >> 0) & 0b1111;
|
||||
|
||||
let top = unsafe { *TO_HEX.get_unchecked(top_idx as usize) };
|
||||
let bot = unsafe { *TO_HEX.get_unchecked(bot_idx as usize) };
|
||||
|
||||
serial::transmit(top);
|
||||
serial::transmit(bot);
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
fn write_newline() {
|
||||
serial::transmit(b'\r');
|
||||
serial::transmit(b'\n');
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
fn write_raw(s: &str) {
|
||||
for b in s.bytes() {
|
||||
serial::transmit(b);
|
||||
}
|
||||
write_newline();
|
||||
}
|
||||
|
||||
struct SuperSerial;
|
||||
|
||||
impl fmt::Write for SuperSerial {
|
||||
fn write_str(&mut self, s: &str) -> Result<(), fmt::Error> {
|
||||
for b in s.bytes() {
|
||||
serial::transmit(b);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
29
initialize_memory.S
Normal file
29
initialize_memory.S
Normal file
@@ -0,0 +1,29 @@
|
||||
.section .text
|
||||
.globl __initialize_memory
|
||||
.type __initialize_memory, @function
|
||||
|
||||
;;; Does not handle the region pointer!
|
||||
__initialize_memory:
|
||||
ldi r31, hi8(__data_load_start)
|
||||
ldi r30, lo8(__data_load_start) ; Z
|
||||
|
||||
ldi r29, hi8(__data_load_end)
|
||||
ldi r28, lo8(__data_load_end) ; Y
|
||||
|
||||
ldi r27, hi8(__data_start)
|
||||
ldi r26, lo8(__data_start) ; X
|
||||
|
||||
sub r28, r30
|
||||
sbc r29, r31 ; Y now contains the length of bytes
|
||||
rjmp check
|
||||
|
||||
entrypoint:
|
||||
lpm r0, Z+ ; Load from program memory, increment pointer
|
||||
st X+, r0 ; Store to RAM, increment pointer
|
||||
|
||||
subi r28, 1 ; Decrement the count
|
||||
sbci r29, 0
|
||||
|
||||
check:
|
||||
brne entrypoint ; Exit when all bytes copied
|
||||
ret
|
||||
@@ -4,5 +4,5 @@ version = "0.1.0"
|
||||
authors = ["Jake Goulding <jake.goulding@gmail.com>"]
|
||||
|
||||
[lib]
|
||||
#path = "/Users/shep/Projects/avr-rust/src/libcore/lib.rs"
|
||||
path = "/tmp/libcore/lib.rs"
|
||||
path = "/Users/shep/Projects/avr-rust/src/libcore/lib.rs"
|
||||
# path = "/tmp/libcore/lib.rs"
|
||||
|
||||
Reference in New Issue
Block a user