Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
lpc81isp_go
usage¶
lpc81isp.exe -port=COM2 lpc810_helloworld_LPC812.bin
source code¶
lpc81isp.go
// lpc81isp.go 2016/3/21
package main
import (
"flag"
"fmt"
"github.com/tarm/serial"
"io/ioutil"
"log"
"regexp"
)
const (
RAM = 0x10000300
ChunkSize = 64
SectorSize = 1024
)
type target struct {
p *serial.Port
}
func newTarget(port string, baud int) *target {
c := &serial.Config{Name: port, Baud: baud}
s, err := serial.OpenPort(c)
if err != nil {
log.Fatal(err)
}
return &target{p: s}
}
func (t *target) send(str string) {
t.p.Write([]byte(str))
}
func (t *target) recv(n int) []byte {
buf := make([]byte, n)
i := 0
for i < n {
r, err := t.p.Read(buf[i:n])
if err != nil {
log.Fatal(err)
}
i += r
}
return buf
}
func (t *target) sendln(line string) {
log.Printf("send: %s<CR><LF>\n", line)
t.send(line + "\r\n")
}
func (t *target) recvln() string {
s := ""
raw := ""
for {
buf := t.recv(1)
switch c := buf[0]; c {
case '\r':
raw += "<CR>"
case '\n':
raw += "<LF>"
log.Printf("recv: %s[%s]", raw, s)
return s
default:
s += string(c)
raw += string(c)
}
}
}
func (t *target) waitln(match string) {
for {
matched, _ := regexp.MatchString(match, t.recvln())
if matched {
break
}
}
}
func (t *target) cmd(format string, v ...interface{}) {
t.sendln(fmt.Sprintf(format, v...))
t.waitln("^0$") // CMD_SUCCESS
}
func (t *target) sync() {
log.Println("send: ?")
t.send("?")
t.waitln("Synchronized$")
t.sendln("Synchronized")
t.waitln("OK$")
t.sendln("12284")
t.waitln("OK$")
t.cmd("A 0") // echo off
}
func (t *target) toRam(data []byte) {
t.cmd("W %d %d", RAM, ChunkSize) // write to ram
buf := make([]byte, ChunkSize)
copy(buf, data)
t.send(string(buf))
}
func (t *target) flashWrite(data []byte) {
t.sync()
t.cmd("U 23130") // unlock
sector := 0
for addr := 0; addr < len(data); addr += ChunkSize {
t.toRam(data[addr : addr+ChunkSize])
if (addr % SectorSize) == 0 {
sector = addr / SectorSize
t.cmd("P %d %d", sector, sector) // prepare sector
t.cmd("E %d %d", sector, sector) // erase sector
}
t.cmd("P %d %d", sector, sector)
t.cmd("C %d %d %d", addr, RAM, ChunkSize) // copy ram to flash
}
}
func (t *target) flashVerify(data []byte) {
for addr := 0; addr < len(data); addr += ChunkSize {
t.cmd("R %d %d", addr, ChunkSize) // read memory
r := t.recv(ChunkSize)
for i := 0; i < ChunkSize && (addr+i) < len(data); i++ {
if data[addr+i] != r[i] {
log.Fatal("verify error")
}
}
}
}
func main() {
pPort := flag.String("port", "COM1", "serial port")
pBaud := flag.Int("baud", 9600, "serial baud")
pVerifyFlag := flag.Bool("verify", false, "verify after write")
flag.Parse()
filename := flag.Args()[0]
data, err := ioutil.ReadFile(filename)
if err != nil {
log.Fatal(err)
}
log.Printf("binfile: %s, size: %d bytes\n", filename, len(data))
lpc810 := newTarget(*pPort, *pBaud)
lpc810.flashWrite(data)
if *pVerifyFlag {
lpc810.flashVerify(data)
}
log.Println("done!")
}