LPC810 LED blink test using LPC812(LPC800-MAX) online compiler.

Dependencies:   mbed

lpc81isp_go

Table of Contents

  1. usage
  2. source code

usage

lpc81isp.exe -port=COM2 lpc810_helloworld_LPC812.bin

source code

lpc81isp.go

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!")
}

All wikipages