Skip to content

Commit

Permalink
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
Show file tree
Hide file tree
Showing 4 changed files with 387 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
@@ -0,0 +1 @@
build/
141 changes: 141 additions & 0 deletions vga/Makefile
@@ -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
35 changes: 35 additions & 0 deletions vga/build-targets.mk
@@ -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

210 changes: 210 additions & 0 deletions vga/main.cpp
@@ -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;
}

0 comments on commit f532e19

Please sign in to comment.