-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Initial commit; successfully blinks an LED.
- Loading branch information
Showing
6 changed files
with
257 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,19 @@ | ||
#MCU=msp430f5510 | ||
# MCU is now defined in msp403.nim | ||
|
||
NIMFLAGS=-d:release --os:standalone --opt:size --gc:none --deadCodeElim:on | ||
# avr is the closest cpu for the moment | ||
NIMFLAGS+=--cpu:avr | ||
# running one C compiler lets its errors show | ||
NIMFLAGS+=--parallelBuild:1 --verbosity:1 | ||
|
||
%: %.nim panicoverride.nim | ||
nim c $(NIMFLAGS) $< | ||
|
||
blink: blink.nim msp430usb.nim msp430.nim | ||
|
||
all: blink | ||
|
||
# Uses python-msp430-tools | ||
program: blink | ||
python -m msp430.bsl5.hid -e $^ |
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,40 @@ | ||
import msp430 | ||
#import msp430usb | ||
|
||
# Trivial blink demo for now. | ||
|
||
template toggleLED() = | ||
PJ.OUT = PJ.OUT xor 8 | ||
|
||
proc main = | ||
PJ.DIR = PJ.DIR or 8 | ||
while true: | ||
toggleLED() | ||
var i {.volatile.} = 0x7350 # volatile to keep delay loop | ||
while i!=0: | ||
i = i - 1 | ||
|
||
main() | ||
|
||
|
||
# My first project is a PC joystick to USB adapter based on an | ||
# Olimexino-5510 board (a MSP430 board resembling an Arduino Pro). | ||
# Judging by the SW/HW I2C solder jumpers on the board, the | ||
# designer was unaware that this chip can remap those functions. | ||
# I intend to measure the analog resistances by timing a capacitor | ||
# charge, similar to the original card. Luckily the f5510 has | ||
# more than four timer capture pins for this. | ||
# I also intend to add a Gravis Grip decoder, for which the | ||
# pin change interrupts will come in handy. | ||
# Pins connected on adapter board so far: | ||
# 1,8,9,15 5v | ||
# 4,5,12 gnd | ||
# 7 b2 d3 ta0_0 | ||
# 6 y1 d4 ta0_1 needs capacitor | ||
# 14 b3 d2 p1_0 | ||
# 13 y2 d5 ta0_2 needs capacitor | ||
# 11 x2 d6 ta0_3 needs capacitor | ||
# 3 x1 d7 ta0_4 needs capacitor | ||
# pins yet to connect | ||
# 2 b1 d8 p1_6 | ||
# 10 b4 d9 p1_7 |
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,71 @@ | ||
import macros | ||
|
||
const mcu="msp430f5510" | ||
|
||
{.passC: "-mmcu="&mcu.} | ||
{.passL: "-mmcu="&mcu.} | ||
|
||
type | ||
GPIO = tuple | ||
IN: int16 | ||
OUT: int16 | ||
DIR: int16 | ||
REN: int16 | ||
DS: int16 | ||
SEL: int16 | ||
# Only port A (aka port 1 and 2) has interrupts | ||
IES: int16 | ||
IE: int16 | ||
IFG: int16 | ||
|
||
macro declGPIO(n: expr): stmt {.immediate.} = | ||
result = newNimNode(nnkStmtList) | ||
n.expectKind(nnkIdent) | ||
let name = $n.ident | ||
# Doing it this way sadly leaves parsing modules (parseutils, strutils, | ||
# macros) which have initializers in the runtime (empty, but each wastes | ||
# six words). But building the expression directly is awfully clumsy. | ||
# This makes me see more appeal to lisp. | ||
result.add(parseStmt("var "&name&"IN {.header: \"<msp430.h>\", importc.} : int16"), | ||
parseStmt("template "&name&"*: expr = cast[ptr GPIO](addr "&name&"IN)")) | ||
|
||
var | ||
WDTCTL* {.header: "<msp430.h>", importc.} : int16 | ||
|
||
declGPIO(PA) | ||
declGPIO(PJ) | ||
|
||
template setPragma(node: stmt, name: string, value: string) = | ||
if node.pragma.kind==nnkEmpty: | ||
node.pragma=newNimNode(nnkPragma) | ||
node.pragma.add(newNimNode(nnkExprColonExpr) | ||
.add(newIdentNode(name)) | ||
.add(newStrLitNode(value))) | ||
template setPragma(node: stmt, name: string) = | ||
if node.pragma.kind==nnkEmpty: | ||
node.pragma=newNimNode(nnkPragma) | ||
node.pragma.add(newIdentNode(name)) | ||
|
||
macro ISR*(procs: stmt): stmt {.immediate.} = | ||
# Statement macro that modifies a proc to work as interrupt handler | ||
# The vectors are only resolved at C level, so this routine does not | ||
# need to know which exist. | ||
let keeps = newNimNode(nnkStmtList) | ||
# TODO: parse the C header file to extract numbers like these | ||
for node in procs.children: | ||
node.expectKind(nnkProcDef) | ||
let name : string = $node.name.ident | ||
node.setPragma("codegenDecl", "$# __attribute__((__interrupt__("&name&"_VECTOR))) $# $#") | ||
node.setPragma("exportc", "ISR_" & name) | ||
keeps.add(newNimNode(nnkDiscardstmt).add(node.name)) | ||
# discard statements are generated to keep the proc referenced | ||
# dead code elimination doesn't know of the ISR vector table | ||
result = procs.add(keeps) | ||
|
||
# Example usage | ||
#ISR: | ||
# proc SYSNMI() = | ||
# return | ||
|
||
# Disable watchdog timer | ||
WDTCTL = 0x5a80 |
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,103 @@ | ||
import msp430 | ||
|
||
|
||
type | ||
USBVECINT_value = enum | ||
NONE = 0x00 | ||
PWR_DROP = 0x02 | ||
PLL_LOCK = 0x04 | ||
PLL_SIGNAL = 0x06 | ||
PLL_RANGE = 0x08 | ||
PWR_VBUSOn = 0x0A | ||
PWR_VBUSOff = 0x0C | ||
USB_TIMESTAMP = 0x10 | ||
INPUT_ENDPOINT0 = 0x12 | ||
OUTPUT_ENDPOINT0 = 0x14 | ||
RSTR = 0x16 | ||
SUSR = 0x18 | ||
RESR = 0x1A | ||
SETUP_PACKET_RECEIVED = 0x20 | ||
STPOW_PACKET_RECEIVED = 0x22 | ||
INPUT_ENDPOINT1 = 0x24 | ||
INPUT_ENDPOINT2 = 0x26 | ||
INPUT_ENDPOINT3 = 0x28 | ||
INPUT_ENDPOINT4 = 0x2A | ||
INPUT_ENDPOINT5 = 0x2C | ||
INPUT_ENDPOINT6 = 0x2E | ||
INPUT_ENDPOINT7 = 0x30 | ||
OUTPUT_ENDPOINT1 = 0x32 | ||
OUTPUT_ENDPOINT2 = 0x34 | ||
OUTPUT_ENDPOINT3 = 0x36 | ||
OUTPUT_ENDPOINT4 = 0x38 | ||
OUTPUT_ENDPOINT5 = 0x3A | ||
OUTPUT_ENDPOINT6 = 0x3C | ||
OUTPUT_ENDPOINT7 = 0x3E | ||
|
||
var | ||
USBVECINT* {.header: "<msp430.h>", importc.} : USBVECINT_value | ||
|
||
ISR: | ||
proc USB_UBM() = | ||
while true: | ||
# computedGoto does not seem to understand the values are all even | ||
# {.computedGoto.} | ||
case USBVECINT | ||
of NONE: | ||
return | ||
of PWR_DROP: | ||
PA.OUT = 4 | ||
of PLL_LOCK: | ||
PA.OUT = 5 | ||
of PLL_SIGNAL: | ||
PA.OUT = 6 | ||
of PLL_RANGE: | ||
PA.OUT = 7 | ||
of PWR_VBUSOn: | ||
PA.OUT = 1 | ||
of PWR_VBUSOff: | ||
PA.OUT = 2 | ||
of USB_TIMESTAMP: | ||
PA.OUT = 8 | ||
of INPUT_ENDPOINT0: | ||
PA.OUT = 9 | ||
of OUTPUT_ENDPOINT0: | ||
PA.OUT = 9 | ||
of RSTR: | ||
PA.OUT = 9 | ||
of SUSR: | ||
PA.OUT = 9 | ||
of RESR: | ||
PA.OUT = 9 | ||
of SETUP_PACKET_RECEIVED: | ||
PA.OUT = 9 | ||
of STPOW_PACKET_RECEIVED: | ||
PA.OUT = 9 | ||
of INPUT_ENDPOINT1: | ||
PA.OUT = 9 | ||
of INPUT_ENDPOINT2: | ||
PA.OUT = 9 | ||
of INPUT_ENDPOINT3: | ||
PA.OUT = 9 | ||
of INPUT_ENDPOINT4: | ||
PA.OUT = 9 | ||
of INPUT_ENDPOINT5: | ||
PA.OUT = 9 | ||
of INPUT_ENDPOINT6: | ||
PA.OUT = 9 | ||
of INPUT_ENDPOINT7: | ||
PA.OUT = 9 | ||
of OUTPUT_ENDPOINT1: | ||
PA.OUT = 9 | ||
of OUTPUT_ENDPOINT2: | ||
PA.OUT = 9 | ||
of OUTPUT_ENDPOINT3: | ||
PA.OUT = 9 | ||
of OUTPUT_ENDPOINT4: | ||
PA.OUT = 9 | ||
of OUTPUT_ENDPOINT5: | ||
PA.OUT = 9 | ||
of OUTPUT_ENDPOINT6: | ||
PA.OUT = 9 | ||
of OUTPUT_ENDPOINT7: | ||
PA.OUT = 9 | ||
|
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,4 @@ | ||
# We use the AVR target for msp430, since Nim sees it as a 16-bit | ||
# little endian target (which is more true of msp430 than avr). | ||
avr.standalone.gcc.exe = "msp430-gcc" | ||
avr.standalone.gcc.linkerexe = "msp430-gcc" |
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,20 @@ | ||
|
||
#proc printf(frmt: cstring) {.varargs, importc, header: "<stdio.h>", cdecl.} | ||
proc exit(code: int) {.importc, header: "<stdlib.h>", cdecl.} | ||
|
||
{.push stack_trace: off, profiler:off.} | ||
|
||
proc rawoutput(s: string) = | ||
#printf("%s\n", s) | ||
return | ||
|
||
proc panic(s: string) = | ||
#rawoutput(s) | ||
exit(1) | ||
|
||
# Alternatively we also could implement these 2 here: | ||
# | ||
# template sysFatal(exceptn: typeDesc, message: string) | ||
# template sysFatal(exceptn: typeDesc, message, arg: string) | ||
|
||
{.pop.} |