Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
initial commit
- Loading branch information
Marti Bolivar
committed
Sep 16, 2010
0 parents
commit f532e19
Showing
4 changed files
with
387 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
build/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,141 @@ | ||
.DEFAULT_GOAL := sketch | ||
|
||
# Valid BOARDs: maple, maple_native, ... | ||
BOARD ?= maple | ||
MEMORY_TARGET ?= flash | ||
|
||
# USB ID for DFU upload | ||
VENDOR_ID := 1EAF | ||
PRODUCT_ID := 0003 | ||
|
||
# Guess the MCU based on the BOARD (can be overridden ) | ||
ifeq ($(BOARD), maple) | ||
MCU := STM32F103RB | ||
PRODUCT_ID := 0003 | ||
endif | ||
ifeq ($(BOARD), maple_native) | ||
MCU := STM32F103ZE | ||
PRODUCT_ID := 0003 | ||
endif | ||
|
||
# Useful paths | ||
ifeq ($(LIB_MAPLE_HOME),) | ||
SRCROOT := . | ||
else | ||
SRCROOT := $(LIB_MAPLE_HOME) | ||
endif | ||
BUILD_PATH = build | ||
LIBMAPLE_PATH := $(SRCROOT)/libmaple | ||
SUPPORT_PATH := $(SRCROOT)/support | ||
|
||
# Useful variables | ||
GLOBAL_CFLAGS := -Os -g -mcpu=cortex-m3 -mthumb -march=armv7-m -nostdlib \ | ||
-ffunction-sections -fdata-sections -Wl,--gc-sections \ | ||
-DBOARD_$(BOARD) -DMCU_$(MCU) | ||
GLOBAL_CXXFLAGS := -fno-rtti -fno-exceptions -Wall -DBOARD_$(BOARD) -DMCU_$(MCU) | ||
|
||
|
||
LDDIR := $(SUPPORT_PATH)/ld | ||
LDFLAGS = -T$(LDDIR)/$(LDSCRIPT) -L$(LDDIR) \ | ||
-mcpu=cortex-m3 -mthumb -Xlinker \ | ||
--gc-sections --print-gc-sections --march=armv7-m -Wall | ||
|
||
# Set up build rules and some useful templates | ||
include $(SUPPORT_PATH)/make/build-rules.mk | ||
include $(SUPPORT_PATH)/make/build-templates.mk | ||
|
||
# Some target specific things | ||
ifeq ($(MEMORY_TARGET), ram) | ||
LDSCRIPT := $(BOARD)/ram.ld | ||
VECT_BASE_ADDR := VECT_TAB_RAM | ||
endif | ||
ifeq ($(MEMORY_TARGET), flash) | ||
LDSCRIPT := $(BOARD)/flash.ld | ||
VECT_BASE_ADDR := VECT_TAB_FLASH | ||
endif | ||
ifeq ($(MEMORY_TARGET), jtag) | ||
LDSCRIPT := $(BOARD)/jtag.ld | ||
VECT_BASE_ADDR := VECT_TAB_BASE | ||
endif | ||
|
||
# Set all submodules here | ||
LIBMAPLE_MODULES := $(SRCROOT)/libmaple | ||
LIBMAPLE_MODULES += $(SRCROOT)/wirish | ||
|
||
# call each module rules.mk | ||
$(foreach m,$(LIBMAPLE_MODULES),$(eval $(call LIBMAPLE_MODULE_template,$(m)))) | ||
|
||
# Main target | ||
include build-targets.mk | ||
|
||
.PHONY: install sketch clean help debug cscope tags ctags ram flash jtag | ||
|
||
# Target upload commands | ||
UPLOAD_ram := $(SUPPORT_PATH)/scripts/reset.py && \ | ||
sleep 1 && \ | ||
$(DFU) -a0 -d $(VENDOR_ID):$(PRODUCT_ID) -D $(BUILD_PATH)/$(BOARD).bin -R | ||
UPLOAD_flash := $(SUPPORT_PATH)/scripts/reset.py && \ | ||
sleep 1 && \ | ||
$(DFU) -a1 -d $(VENDOR_ID):$(PRODUCT_ID) -D $(BUILD_PATH)/$(BOARD).bin -R | ||
UPLOAD_jtag := $(OPENOCD) -f support/openocd/flash.cfg | ||
|
||
# conditionally upload to whatever the last build was | ||
install: INSTALL_TARGET = $(shell cat $(BUILD_PATH)/build-type 2>/dev/null) | ||
install: $(BUILD_PATH)/$(BOARD).bin | ||
@echo Install target: $(INSTALL_TARGET) | ||
$(UPLOAD_$(INSTALL_TARGET)) | ||
|
||
# Force a rebuild if the maple target changed | ||
PREV_BUILD_TYPE = $(shell cat $(BUILD_PATH)/build-type 2>/dev/null) | ||
build-check: | ||
ifneq ($(PREV_BUILD_TYPE), $(MEMORY_TARGET)) | ||
$(shell rm -rf $(BUILD_PATH)) | ||
endif | ||
|
||
sketch: build-check MSG_INFO $(BUILD_PATH)/$(BOARD).bin | ||
|
||
clean: | ||
rm -rf build | ||
|
||
help: | ||
@echo "" | ||
@echo " libmaple Makefile help" | ||
@echo " ----------------------" | ||
@echo " Compile targets (default MEMORY_TARGET=flash):" | ||
@echo " ram: Compile sketch code to ram" | ||
@echo " flash: Compile sketch code to flash" | ||
@echo " jtag: Compile sketch code to jtag" | ||
@echo " sketch: Compile sketch code to target MEMORY_TARGET" | ||
@echo " " | ||
@echo " Programming targets:" | ||
@echo " install: Upload code to target" | ||
@echo " " | ||
@echo " Other targets:" | ||
@echo " debug: Start an openocd gdb server, port 3333" | ||
@echo " clean: Remove all build and object files" | ||
@echo " help: Show this message" | ||
@echo " " | ||
|
||
debug: | ||
$(OPENOCD) -f support/openocd/run.cfg | ||
|
||
cscope: | ||
rm -rf *.cscope | ||
find . -name '*.[hcs]' -o -name '*.cpp' | xargs cscope -b | ||
|
||
tags: | ||
etags `find . -name "*.c" -o -name "*.cpp" -o -name "*.h"` | ||
@echo "Made TAGS file for EMACS code browsing" | ||
|
||
ctags: | ||
ctags-exuberant -R . | ||
@echo "Made tags file for VIM code browsing" | ||
|
||
ram: | ||
@$(MAKE) MEMORY_TARGET=ram --no-print-directory sketch | ||
|
||
flash: | ||
@$(MAKE) MEMORY_TARGET=flash --no-print-directory sketch | ||
|
||
jtag: | ||
@$(MAKE) MEMORY_TARGET=jtag --no-print-directory sketch |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
# main project target | ||
$(BUILD_PATH)/main.o: main.cpp | ||
$(SILENT_CXX) $(CXX) $(CFLAGS) $(CXXFLAGS) $(LIBMAPLE_INCLUDES) $(WIRISH_INCLUDES) -o $@ -c $< | ||
|
||
$(BUILD_PATH)/$(BOARD).elf: $(BUILDDIRS) $(TGT_BIN) $(BUILD_PATH)/main.o | ||
$(SILENT_LD) $(CXX) $(LDFLAGS) -o $@ $(TGT_BIN) $(BUILD_PATH)/main.o | ||
|
||
$(BUILD_PATH)/$(BOARD).bin: $(BUILD_PATH)/$(BOARD).elf | ||
$(SILENT_OBJCOPY) $(OBJCOPY) -v -Obinary $(BUILD_PATH)/$(BOARD).elf $@ 1>/dev/null | ||
$(SILENT_DISAS) $(DISAS) -d $(BUILD_PATH)/$(BOARD).elf > $(BUILD_PATH)/$(BOARD).disas | ||
@echo " " | ||
@echo "Object file sizes:" | ||
@find $(BUILD_PATH) -iname *.o | xargs $(SIZE) -t > $(BUILD_PATH)/$(BOARD).sizes | ||
@cat $(BUILD_PATH)/$(BOARD).sizes | ||
@echo " " | ||
@echo "Final Size:" | ||
@$(SIZE) $< | ||
@echo $(MEMORY_TARGET) > $(BUILD_PATH)/build-type | ||
|
||
$(BUILDDIRS): | ||
@mkdir -p $@ | ||
|
||
MSG_INFO: | ||
@echo "================================================================================" | ||
@echo "" | ||
@echo " Build info:" | ||
@echo " BOARD: " $(BOARD) | ||
@echo " MCU: " $(MCU) | ||
@echo " MEMORY_TARGET: " $(MEMORY_TARGET) | ||
@echo "" | ||
@echo " See 'make help' for all possible targets" | ||
@echo "" | ||
@echo "================================================================================" | ||
@echo | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,210 @@ | ||
/* | ||
Crude VGA Output | ||
Outputs a red and white leaf to VGA. This implementation is crude and noisy, | ||
but a fun demo. It should run most VGA monitors at 640x480, though it does | ||
not follow the timing spec very carefully. Real twisted or shielded wires, | ||
proper grounding, and not doing this on a breadboard are recommended (but | ||
it seems to work ok without). | ||
SerialUSB and SysTick are disabled (they mess with timing). This | ||
means that you have to use perpetual bootloader or the reset button | ||
to flash new programs. | ||
How to wire this to a VGA port: | ||
D5 via ~200ohms to VGA Red (1) | ||
D6 via ~200ohms to VGA Green (2) | ||
D7 via ~200ohms to VGA Blue (3) | ||
D11 to VGA VSync (14) (swapped?) | ||
D12 to VGA HSync (13) (swapped?) | ||
GND to VGA Ground (5) | ||
GND to VGA Sync Ground (10) | ||
See also: | ||
- http://pinouts.ru/Video/VGA15_pinout.shtml | ||
- http://www.epanorama.net/documents/pc/vga_timing.html | ||
Created 20 July 2010 | ||
By Bryan Newbold for LeafLabs | ||
This code is released with no strings attached. | ||
*/ | ||
|
||
#include "wirish.h" | ||
|
||
#define LED_PIN 13 | ||
|
||
// Pinouts | ||
#define VGA_R 5 // STM32: B6 | ||
#define VGA_G 6 // STM32: A8 | ||
#define VGA_B 7 // STM32: A9 | ||
#define VGA_V 11 // STM32: A6 | ||
#define VGA_H 12 // STM32: A7 | ||
|
||
// These low level macros make GPIO writes much faster | ||
#define VGA_R_HIGH (GPIOB_BASE)->BSRR = BIT(6) | ||
#define VGA_R_LOW (GPIOB_BASE)->BRR = BIT(6) | ||
#define VGA_G_HIGH (GPIOA_BASE)->BSRR = BIT(8) | ||
#define VGA_G_LOW (GPIOA_BASE)->BRR = BIT(8) | ||
#define VGA_B_HIGH (GPIOA_BASE)->BSRR = BIT(9) | ||
#define VGA_B_LOW (GPIOA_BASE)->BRR = BIT(9) | ||
#define VGA_V_HIGH (GPIOA_BASE)->BSRR = BIT(6) | ||
#define VGA_V_LOW (GPIOA_BASE)->BRR = BIT(6) | ||
#define VGA_H_HIGH (GPIOA_BASE)->BSRR = BIT(7) | ||
#define VGA_H_LOW (GPIOA_BASE)->BRR = BIT(7) | ||
|
||
void isr_porch(void); | ||
void isr_start(void); | ||
void isr_stop(void); | ||
void isr_update(void); | ||
|
||
uint8 toggle; | ||
uint16 x = 0; // X coordinate | ||
uint16 y = 0; // Y coordinate | ||
uint8 v_active = 1; // Are we in the image? | ||
|
||
// 1-bit! | ||
uint8 logo[18][16] = { | ||
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,}, | ||
{0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,}, | ||
{0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,}, | ||
{0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,}, | ||
{0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,0,}, | ||
{0,0,1,0,0,0,0,1,0,0,0,0,1,0,0,0,}, | ||
{0,0,1,0,0,1,0,1,0,1,0,0,1,0,0,0,}, | ||
{0,1,0,0,0,0,1,1,1,0,0,0,0,1,0,0,}, | ||
{0,1,0,1,0,0,0,1,0,0,0,1,0,1,0,0,}, | ||
{1,0,0,0,1,0,0,1,0,0,1,0,0,0,1,0,}, | ||
{1,0,0,0,0,1,0,1,0,1,0,0,0,0,1,0,}, | ||
{1,0,0,0,0,0,1,1,1,0,0,0,0,0,1,0,}, | ||
{0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,}, | ||
{0,0,1,1,0,0,0,1,0,0,0,1,1,0,0,0,}, | ||
{0,0,0,0,1,1,1,0,1,1,1,0,0,0,0,0,}, | ||
{0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,}, | ||
{0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,}, | ||
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,}, }; | ||
|
||
void setup() { | ||
// Setup our pins | ||
pinMode(LED_PIN, OUTPUT); | ||
pinMode(VGA_R, OUTPUT); | ||
pinMode(VGA_G, OUTPUT); | ||
pinMode(VGA_B, OUTPUT); | ||
pinMode(VGA_V, OUTPUT); | ||
pinMode(VGA_H, OUTPUT); | ||
digitalWrite(VGA_R, LOW); | ||
digitalWrite(VGA_G, LOW); | ||
digitalWrite(VGA_B, LOW); | ||
digitalWrite(VGA_H, HIGH); | ||
digitalWrite(VGA_V, HIGH); | ||
|
||
// This gets rid of the majority of the interrupt artifacts; | ||
SerialUSB.end(); | ||
systick_disable(); | ||
|
||
// Configure | ||
Timer4.pause(); // while we configure | ||
Timer4.setPrescaleFactor(1); // Full speed | ||
Timer4.setChannel1Mode(TIMER_OUTPUTCOMPARE); | ||
Timer4.setChannel2Mode(TIMER_OUTPUTCOMPARE); | ||
Timer4.setChannel3Mode(TIMER_OUTPUTCOMPARE); | ||
Timer4.setChannel4Mode(TIMER_OUTPUTCOMPARE); | ||
Timer4.setOverflow(2287); // Total line time | ||
|
||
Timer4.setCompare1(200); | ||
Timer4.attachCompare1Interrupt(isr_porch); | ||
Timer4.setCompare2(300); | ||
Timer4.attachCompare2Interrupt(isr_start); | ||
Timer4.setCompare3(2170); | ||
Timer4.attachCompare3Interrupt(isr_stop); | ||
Timer4.setCompare4(1); // Could be zero I guess | ||
Timer4.attachCompare4Interrupt(isr_update); | ||
|
||
Timer4.setCount(0); // Ready... | ||
Timer4.resume(); // Go! | ||
} | ||
|
||
void loop() { | ||
toggle ^= 1; | ||
digitalWrite(LED_PIN, toggle); | ||
delay(100); | ||
|
||
// Everything happens in the interrupts! | ||
} | ||
|
||
|
||
// This ISR will end horizontal sync for most of the image and | ||
// setup the vertical sync for higher line counts | ||
void isr_porch(void) { | ||
VGA_H_HIGH; | ||
y++; | ||
|
||
|
||
// Back to the top | ||
if(y>=523) { | ||
y=1; | ||
v_active = 1; | ||
return; | ||
} | ||
// Other vsync stuff below the image | ||
if(y>=492) { | ||
VGA_V_HIGH; | ||
return; | ||
} | ||
if(y>=490) { | ||
VGA_V_LOW; | ||
return; | ||
} | ||
if(y>=479) { | ||
v_active = 0; | ||
return; | ||
} | ||
} | ||
|
||
// This is the main horizontal sweep | ||
void isr_start(void) { | ||
// Skip if we're not in the image at all | ||
if(!v_active) { return; } | ||
|
||
// Start Red | ||
VGA_R_LOW; | ||
VGA_R_HIGH; | ||
|
||
// For each "pixel" (really 20 or so screen pixels?) go red or white | ||
for(x=0; x<32; x++) { | ||
if(logo[y/28][x/2]) { | ||
VGA_G_HIGH; | ||
VGA_B_HIGH; | ||
} else { | ||
VGA_G_LOW; | ||
VGA_B_LOW; | ||
} | ||
} | ||
// black out what's left | ||
VGA_R_LOW; | ||
VGA_G_LOW; | ||
VGA_B_LOW; | ||
} | ||
|
||
// End of the horizontal line | ||
void isr_stop(void) { | ||
if(!v_active) { return; } | ||
VGA_R_LOW; | ||
VGA_G_LOW; | ||
VGA_B_LOW; | ||
} | ||
|
||
// Setup horizonal sync | ||
void isr_update(void) { | ||
VGA_H_LOW; | ||
} | ||
|
||
int main(void) { | ||
init(); | ||
setup(); | ||
|
||
while (1) { | ||
loop(); | ||
} | ||
return 0; | ||
} |