mirror of
https://github.com/tinygo-org/drivers.git
synced 2026-08-04 06:57:48 +00:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4c59a3ff90 | |||
| 915ca320de |
File diff suppressed because it is too large
Load Diff
@@ -10,6 +10,25 @@ import (
|
|||||||
"tinygo.org/x/drivers/ili9341"
|
"tinygo.org/x/drivers/ili9341"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
BALLWIDTH = 136
|
||||||
|
BALLHEIGHT = 100
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
SCREENHEIGHT = 240
|
||||||
|
SCREENWIDTH = 320
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
invBGCOLOR = 0x75AD
|
||||||
|
invGRIDCOLOR = 0x15A8
|
||||||
|
invBGSHADOW = 0x8552
|
||||||
|
invGRIDSHADOW = 0x0C60
|
||||||
|
invRED = 0x00F8
|
||||||
|
invWHITE = 0xFFFF
|
||||||
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
BGCOLOR = 0xAD75
|
BGCOLOR = 0xAD75
|
||||||
GRIDCOLOR = 0xA815
|
GRIDCOLOR = 0xA815
|
||||||
@@ -25,7 +44,12 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
frameBuffer = [(graphics.BALLHEIGHT + 8) * (graphics.BALLWIDTH + 8)]uint16{}
|
dbg5 = machine.D5
|
||||||
|
dbg6 = machine.D6
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
frameBuffer = [2][(BALLHEIGHT + 8) * (BALLWIDTH + 8)]uint16{}
|
||||||
|
|
||||||
startTime int64
|
startTime int64
|
||||||
frame int64
|
frame int64
|
||||||
@@ -71,14 +95,18 @@ func main() {
|
|||||||
balloldx = ballx
|
balloldx = ballx
|
||||||
balloldy = bally // Prior ball position
|
balloldy = bally // Prior ball position
|
||||||
|
|
||||||
|
var bufIdx int8 = 0
|
||||||
|
|
||||||
for {
|
for {
|
||||||
|
dbg5.High()
|
||||||
|
bufIdx = 1 - bufIdx
|
||||||
|
|
||||||
balloldx = ballx // Save prior position
|
balloldx = ballx // Save prior position
|
||||||
balloldy = bally
|
balloldy = bally
|
||||||
ballx += ballvx // Update position
|
ballx += ballvx // Update position
|
||||||
bally += ballvy
|
bally += ballvy
|
||||||
ballvy += 0.06 // Update Y velocity
|
ballvy += 0.06 // Update Y velocity
|
||||||
if (ballx <= 15) || (ballx >= graphics.SCREENWIDTH-graphics.BALLWIDTH) {
|
if (ballx <= 15) || (ballx >= SCREENWIDTH-BALLWIDTH) {
|
||||||
ballvx *= -1 // Left/right bounce
|
ballvx *= -1 // Left/right bounce
|
||||||
}
|
}
|
||||||
if bally >= YBOTTOM { // Hit ground?
|
if bally >= YBOTTOM { // Hit ground?
|
||||||
@@ -100,13 +128,13 @@ func main() {
|
|||||||
if int16(balloldy) < miny {
|
if int16(balloldy) < miny {
|
||||||
miny = int16(balloldy)
|
miny = int16(balloldy)
|
||||||
}
|
}
|
||||||
maxx = int16(ballx + graphics.BALLWIDTH - 1)
|
maxx = int16(ballx + BALLWIDTH - 1)
|
||||||
if int16(balloldx+graphics.BALLWIDTH-1) > maxx {
|
if int16(balloldx+BALLWIDTH-1) > maxx {
|
||||||
maxx = int16(balloldx + graphics.BALLWIDTH - 1)
|
maxx = int16(balloldx + BALLWIDTH - 1)
|
||||||
}
|
}
|
||||||
maxy = int16(bally + graphics.BALLHEIGHT - 1)
|
maxy = int16(bally + BALLHEIGHT - 1)
|
||||||
if int16(balloldy+graphics.BALLHEIGHT-1) > maxy {
|
if int16(balloldy+BALLHEIGHT-1) > maxy {
|
||||||
maxy = int16(balloldy + graphics.BALLHEIGHT - 1)
|
maxy = int16(balloldy + BALLHEIGHT - 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
width = maxx - minx + 1
|
width = maxx - minx + 1
|
||||||
@@ -120,13 +148,13 @@ func main() {
|
|||||||
ballframe -= 14
|
ballframe -= 14
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set 7 palette entries to white, 7 to red, based on frame number.
|
//// Set 7 palette entries to white, 7 to red, based on frame number.
|
||||||
// This makes the ball spin
|
//// This makes the ball spin
|
||||||
for i := 0; i < 14; i++ {
|
for i := 0; i < 14; i++ {
|
||||||
if (int(ballframe)+i)%14 < 7 {
|
if (int(ballframe)+i)%14 < 7 {
|
||||||
palette[i+2] = WHITE
|
palette[i+2] = invWHITE
|
||||||
} else {
|
} else {
|
||||||
palette[i+2] = RED
|
palette[i+2] = invRED
|
||||||
} // Palette entries 0 and 1 aren't used (clear and shadow, respectively)
|
} // Palette entries 0 and 1 aren't used (clear and shadow, respectively)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -136,61 +164,100 @@ func main() {
|
|||||||
by := miny - int16(bally) // Y relative to ball bitmap (can be negative)
|
by := miny - int16(bally) // Y relative to ball bitmap (can be negative)
|
||||||
bgx := minx // X relative to background bitmap (>= 0)
|
bgx := minx // X relative to background bitmap (>= 0)
|
||||||
bgy := miny // Y relative to background bitmap (>= 0)
|
bgy := miny // Y relative to background bitmap (>= 0)
|
||||||
var bx1, bgx1 int16 // Loop counters and working vars
|
//var bufIdx int8 = 0
|
||||||
var p uint8 // 'packed' value of 2 ball pixels
|
|
||||||
var bufIdx int8 = 0
|
|
||||||
|
|
||||||
//tft.setAddrWindow(minx, miny, width, height)
|
//tft.setAddrWindow(minx, miny, width, height)
|
||||||
|
//dbg5.Low()
|
||||||
|
dbg6.High()
|
||||||
|
//fmt.Printf("%d < %d < %d < %d\r\n", by, 0, BALLHEIGHT, height)
|
||||||
|
|
||||||
for y := 0; y < int(height); y++ { // For each row...
|
y := 0
|
||||||
//destPtr = &renderbuf[bufIdx][0];
|
if by < 0 {
|
||||||
bx1 = bx // Need to keep the original bx and bgx values,
|
max := -1 * int(by)
|
||||||
bgx1 = bgx // so copies of them are made here (and changed in loop below)
|
for y = 0; y < max; y++ { // For each row...
|
||||||
for x := 0; x < int(width); x++ {
|
var bgidxBase = int(bgy)*(SCREENWIDTH) + int(bgx)
|
||||||
var bgidx = int(bgy)*(graphics.SCREENWIDTH/8) + int(bgx1/8)
|
var yBase = y * int(width)
|
||||||
if (bx1 >= 0) && (bx1 < graphics.BALLWIDTH) && // Is current pixel row/column
|
for x := 0; x < int(width); x++ {
|
||||||
(by >= 0) && (by < graphics.BALLHEIGHT) { // inside the ball bitmap area?
|
frameBuffer[bufIdx][yBase+x] = graphics.Background[bgidxBase+x]
|
||||||
|
}
|
||||||
|
bgy++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
y2 := y
|
||||||
|
max := 0
|
||||||
|
if bx < 0 {
|
||||||
|
max = -1 * int(bx)
|
||||||
|
bgy2 := bgy
|
||||||
|
for y = y2; y < y2+int(BALLHEIGHT); y++ { // For each row...
|
||||||
|
var bgidxBase = int(bgy2)*(SCREENWIDTH) + int(bgx)
|
||||||
|
var yBase = y * int(width)
|
||||||
|
//fmt.Printf("- %d %d %d %d %d %d\r\n", bgy, y, bgx, max, yBase, bgidxBase)
|
||||||
|
for x := 0; x < int(max); x++ {
|
||||||
|
//fmt.Printf(" %d %d\r\n", yBase+x, bgidxBase+x)
|
||||||
|
frameBuffer[bufIdx][yBase+x] = graphics.Background[bgidxBase+x]
|
||||||
|
}
|
||||||
|
bgy2++
|
||||||
|
}
|
||||||
|
//fmt.Printf("(%d, %d) - (%d, %d)\r\n", bx, 0, -1, BALLHEIGHT-1)
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
bgy2 := bgy
|
||||||
|
//fmt.Printf("(%d, %d) - (%d, %d)\r\n", 0, 0, BALLWIDTH-1, BALLHEIGHT-1)
|
||||||
|
for y = y2; y < y2+int(BALLHEIGHT); y++ { // For each row...
|
||||||
|
var bgidxBase = int(bgy2)*(SCREENWIDTH) + int(bgx)
|
||||||
|
var byBase = (y - y2) * BALLWIDTH
|
||||||
|
var yBase = y * int(width)
|
||||||
|
for x := max; x < int(BALLWIDTH)+max; x++ {
|
||||||
|
//fmt.Printf("%d %d %d %d\r\n", byBase, x, bgidxBase, yBase)
|
||||||
|
//time.Sleep(1 * time.Millisecond)
|
||||||
// Yes, do ball compositing math...
|
// Yes, do ball compositing math...
|
||||||
p = graphics.Ball[int(by*(graphics.BALLWIDTH/2))+int(bx1/2)] // Get packed value (2 pixels)
|
c = uint16(graphics.Ball[int(byBase)+x-max]) // Get packed value (2 pixels)
|
||||||
if (bx1 & 1) != 0 {
|
|
||||||
c = uint16(p & 0xF)
|
|
||||||
} else {
|
|
||||||
c = uint16(p >> 4)
|
|
||||||
} // Unpack high or low nybble
|
|
||||||
if c == 0 { // Outside ball - just draw grid
|
if c == 0 { // Outside ball - just draw grid
|
||||||
if graphics.Background[bgidx]&(0x80>>(bgx1&7)) != 0 {
|
c = graphics.Background[bgidxBase+x]
|
||||||
c = GRIDCOLOR
|
|
||||||
} else {
|
|
||||||
c = BGCOLOR
|
|
||||||
}
|
|
||||||
} else if c > 1 { // In ball area...
|
} else if c > 1 { // In ball area...
|
||||||
c = palette[c]
|
c = palette[c]
|
||||||
} else { // In shadow area...
|
} else { // In shadow area...
|
||||||
if graphics.Background[bgidx]&(0x80>>(bgx1&7)) != 0 {
|
c = graphics.BackgroundShadow[bgidxBase+x]
|
||||||
c = GRIDSHADOW
|
|
||||||
} else {
|
|
||||||
c = BGSHADOW
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else { // Outside ball bitmap, just draw background bitmap...
|
|
||||||
if graphics.Background[bgidx]&(0x80>>(bgx1&7)) != 0 {
|
|
||||||
c = GRIDCOLOR
|
|
||||||
} else {
|
|
||||||
c = BGCOLOR
|
|
||||||
}
|
}
|
||||||
|
frameBuffer[bufIdx][yBase+x] = c
|
||||||
}
|
}
|
||||||
frameBuffer[y*int(width)+x] = c
|
bgy2++
|
||||||
bx1++ // Increment bitmap position counters (X axis)
|
|
||||||
bgx1++
|
|
||||||
}
|
}
|
||||||
//tft.dmaWait(); // Wait for prior line to complete
|
|
||||||
//tft.writePixels(&renderbuf[bufIdx][0], width, false); // Non-blocking write
|
|
||||||
bufIdx = 1 - bufIdx
|
|
||||||
by++ // Increment bitmap position counters (Y axis)
|
|
||||||
bgy++
|
|
||||||
}
|
}
|
||||||
|
|
||||||
display.DrawRGBBitmap(minx, miny, frameBuffer[:width*height], width, height)
|
{
|
||||||
|
bgy2 := bgy
|
||||||
|
for y = y2; y < y2+int(BALLHEIGHT); y++ { // For each row...
|
||||||
|
var bgidxBase = int(bgy2)*(SCREENWIDTH) + int(bgx)
|
||||||
|
var yBase = y * int(width)
|
||||||
|
//fmt.Printf("+ %d %d %d %d %d\r\n", bgy, y, bgx, yBase, bgidxBase)
|
||||||
|
for x := int(BALLWIDTH) + max; x < int(width); x++ {
|
||||||
|
frameBuffer[bufIdx][yBase+x] = graphics.Background[bgidxBase+x]
|
||||||
|
}
|
||||||
|
bgy2++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
y = y2 + int(BALLHEIGHT)
|
||||||
|
bgy += BALLHEIGHT
|
||||||
|
{
|
||||||
|
for ; y < int(height); y++ { // For each row...
|
||||||
|
//destPtr = &renderbuf[bufIdx][0];
|
||||||
|
var bgidxBase = int(bgy)*(SCREENWIDTH) + int(bgx)
|
||||||
|
var yBase = y * int(width)
|
||||||
|
for x := 0; x < int(width); x++ {
|
||||||
|
frameBuffer[bufIdx][yBase+x] = graphics.Background[bgidxBase+x]
|
||||||
|
}
|
||||||
|
bgy++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dbg6.Low()
|
||||||
|
|
||||||
|
display.DrawRGBBitmap(minx, miny, frameBuffer[bufIdx][:width*height], width, height)
|
||||||
|
//time.Sleep(10 * time.Millisecond)
|
||||||
|
|
||||||
// Show approximate frame rate
|
// Show approximate frame rate
|
||||||
frame++
|
frame++
|
||||||
@@ -205,21 +272,13 @@ func main() {
|
|||||||
|
|
||||||
func DrawBackground() {
|
func DrawBackground() {
|
||||||
w, h := display.Size()
|
w, h := display.Size()
|
||||||
byteWidth := (w + 7) / 8 // Bitmap scanline pad = whole byte
|
var bufIdx int8 = 0
|
||||||
var b uint8
|
for j := 0; j < int(h); j++ {
|
||||||
for j := int16(0); j < h; j++ {
|
bufIdx = 1 - bufIdx
|
||||||
for k := int16(0); k < w; k++ {
|
for k := 0; k < int(w); k++ {
|
||||||
if k&7 > 0 {
|
frameBuffer[bufIdx][k] = graphics.Background[j*int(w)+k]
|
||||||
b <<= 1
|
|
||||||
} else {
|
|
||||||
b = graphics.Background[j*byteWidth+k/8]
|
|
||||||
}
|
|
||||||
if b&0x80 == 0 {
|
|
||||||
frameBuffer[k] = BGCOLOR
|
|
||||||
} else {
|
|
||||||
frameBuffer[k] = GRIDCOLOR
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
display.DrawRGBBitmap(0, j, frameBuffer[0:w], w, 1)
|
display.DrawRGBBitmap(0, int16(j), frameBuffer[bufIdx][0:w], w, 1)
|
||||||
|
time.Sleep(1 * time.Millisecond)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,5 +5,10 @@ go 1.15
|
|||||||
require (
|
require (
|
||||||
github.com/eclipse/paho.mqtt.golang v1.2.0
|
github.com/eclipse/paho.mqtt.golang v1.2.0
|
||||||
github.com/frankban/quicktest v1.10.2
|
github.com/frankban/quicktest v1.10.2
|
||||||
|
github.com/sago35/tinygo-dma v0.0.0-20210610020721-297675ab9b23 // indirect
|
||||||
github.com/tinygo-org/tinyfs v0.0.0-20210514090915-924e60a7bcf8
|
github.com/tinygo-org/tinyfs v0.0.0-20210514090915-924e60a7bcf8
|
||||||
)
|
)
|
||||||
|
|
||||||
|
replace (
|
||||||
|
github.com/sago35/tinygo-dma => ../../sago35/tinygo-dma
|
||||||
|
)
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfn
|
|||||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
|
github.com/sago35/tinygo-dma v0.0.0-20210610020721-297675ab9b23 h1:ESMYhe6RQJ2RbBCH2OK1SNyYq3gKoBpI7g07aLjQgJI=
|
||||||
|
github.com/sago35/tinygo-dma v0.0.0-20210610020721-297675ab9b23/go.mod h1:gXCCsg4cKOJ6NJl7teGN597XgN0hzQJz0Wekayj4k+M=
|
||||||
github.com/tinygo-org/tinyfs v0.0.0-20210514004344-b02c062d12c9 h1:66or7MohOph3xr3gMGCXceLkd+MBoUbV/rPPjl8iQOU=
|
github.com/tinygo-org/tinyfs v0.0.0-20210514004344-b02c062d12c9 h1:66or7MohOph3xr3gMGCXceLkd+MBoUbV/rPPjl8iQOU=
|
||||||
github.com/tinygo-org/tinyfs v0.0.0-20210514004344-b02c062d12c9/go.mod h1:HGuyo42bGd1zWSuS1gwgyyjN36ZZMlEpwM0vSrglmXc=
|
github.com/tinygo-org/tinyfs v0.0.0-20210514004344-b02c062d12c9/go.mod h1:HGuyo42bGd1zWSuS1gwgyyjN36ZZMlEpwM0vSrglmXc=
|
||||||
github.com/tinygo-org/tinyfs v0.0.0-20210514090915-924e60a7bcf8 h1:pYwuKe1XuNeJnGV1UjeZ0FhuZ5+lapIq1NUmGacbBwo=
|
github.com/tinygo-org/tinyfs v0.0.0-20210514090915-924e60a7bcf8 h1:pYwuKe1XuNeJnGV1UjeZ0FhuZ5+lapIq1NUmGacbBwo=
|
||||||
|
|||||||
+55
-36
@@ -28,6 +28,35 @@ type Device struct {
|
|||||||
rd machine.Pin
|
rd machine.Pin
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var cmdBuf [4]byte
|
||||||
|
var initCmd = []byte{
|
||||||
|
0xEF, 3, 0x03, 0x80, 0x02,
|
||||||
|
0xCF, 3, 0x00, 0xC1, 0x30,
|
||||||
|
0xED, 4, 0x64, 0x03, 0x12, 0x81,
|
||||||
|
0xE8, 3, 0x85, 0x00, 0x78,
|
||||||
|
0xCB, 5, 0x39, 0x2C, 0x00, 0x34, 0x02,
|
||||||
|
0xF7, 1, 0x20,
|
||||||
|
0xEA, 2, 0x00, 0x00,
|
||||||
|
PWCTR1, 1, 0x23, // Power control VRH[5:0]
|
||||||
|
PWCTR2, 1, 0x10, // Power control SAP[2:0];BT[3:0]
|
||||||
|
VMCTR1, 2, 0x3e, 0x28, // VCM control
|
||||||
|
VMCTR2, 1, 0x86, // VCM control2
|
||||||
|
MADCTL, 1, 0x48, // Memory Access Control
|
||||||
|
VSCRSADD, 1, 0x00, // Vertical scroll zero
|
||||||
|
PIXFMT, 1, 0x55,
|
||||||
|
FRMCTR1, 2, 0x00, 0x18,
|
||||||
|
DFUNCTR, 3, 0x08, 0x82, 0x27, // Display Function Control
|
||||||
|
0xF2, 1, 0x00, // 3Gamma Function Disable
|
||||||
|
GAMMASET, 1, 0x01, // Gamma curve selected
|
||||||
|
GMCTRP1, 15, 0x0F, 0x31, 0x2B, 0x0C, 0x0E, 0x08, // Set Gamma
|
||||||
|
0x4E, 0xF1, 0x37, 0x07, 0x10, 0x03, 0x0E, 0x09, 0x00,
|
||||||
|
GMCTRN1, 15, 0x00, 0x0E, 0x14, 0x03, 0x11, 0x07, // Set Gamma
|
||||||
|
0x31, 0xC1, 0x48, 0x08, 0x0F, 0x0C, 0x31, 0x36, 0x0F,
|
||||||
|
SLPOUT, 0x80, // Exit Sleep
|
||||||
|
DISPON, 0x80, // Display on
|
||||||
|
0x00, // End of list
|
||||||
|
}
|
||||||
|
|
||||||
// Configure prepares display for use
|
// Configure prepares display for use
|
||||||
func (d *Device) Configure(config Config) {
|
func (d *Device) Configure(config Config) {
|
||||||
|
|
||||||
@@ -80,33 +109,6 @@ func (d *Device) Configure(config Config) {
|
|||||||
delay(150)
|
delay(150)
|
||||||
}
|
}
|
||||||
|
|
||||||
initCmd := []byte{
|
|
||||||
0xEF, 3, 0x03, 0x80, 0x02,
|
|
||||||
0xCF, 3, 0x00, 0xC1, 0x30,
|
|
||||||
0xED, 4, 0x64, 0x03, 0x12, 0x81,
|
|
||||||
0xE8, 3, 0x85, 0x00, 0x78,
|
|
||||||
0xCB, 5, 0x39, 0x2C, 0x00, 0x34, 0x02,
|
|
||||||
0xF7, 1, 0x20,
|
|
||||||
0xEA, 2, 0x00, 0x00,
|
|
||||||
PWCTR1, 1, 0x23, // Power control VRH[5:0]
|
|
||||||
PWCTR2, 1, 0x10, // Power control SAP[2:0];BT[3:0]
|
|
||||||
VMCTR1, 2, 0x3e, 0x28, // VCM control
|
|
||||||
VMCTR2, 1, 0x86, // VCM control2
|
|
||||||
MADCTL, 1, 0x48, // Memory Access Control
|
|
||||||
VSCRSADD, 1, 0x00, // Vertical scroll zero
|
|
||||||
PIXFMT, 1, 0x55,
|
|
||||||
FRMCTR1, 2, 0x00, 0x18,
|
|
||||||
DFUNCTR, 3, 0x08, 0x82, 0x27, // Display Function Control
|
|
||||||
0xF2, 1, 0x00, // 3Gamma Function Disable
|
|
||||||
GAMMASET, 1, 0x01, // Gamma curve selected
|
|
||||||
GMCTRP1, 15, 0x0F, 0x31, 0x2B, 0x0C, 0x0E, 0x08, // Set Gamma
|
|
||||||
0x4E, 0xF1, 0x37, 0x07, 0x10, 0x03, 0x0E, 0x09, 0x00,
|
|
||||||
GMCTRN1, 15, 0x00, 0x0E, 0x14, 0x03, 0x11, 0x07, // Set Gamma
|
|
||||||
0x31, 0xC1, 0x48, 0x08, 0x0F, 0x0C, 0x31, 0x36, 0x0F,
|
|
||||||
SLPOUT, 0x80, // Exit Sleep
|
|
||||||
DISPON, 0x80, // Display on
|
|
||||||
0x00, // End of list
|
|
||||||
}
|
|
||||||
for i, c := 0, len(initCmd); i < c; {
|
for i, c := 0, len(initCmd); i < c; {
|
||||||
cmd := initCmd[i]
|
cmd := initCmd[i]
|
||||||
if cmd == 0x00 {
|
if cmd == 0x00 {
|
||||||
@@ -146,8 +148,24 @@ func (d *Device) Display() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var err1 = errors.New("rectangle coordinates outside display area")
|
||||||
|
|
||||||
// DrawRGBBitmap copies an RGB bitmap to the internal buffer at given coordinates
|
// DrawRGBBitmap copies an RGB bitmap to the internal buffer at given coordinates
|
||||||
func (d *Device) DrawRGBBitmap(x, y int16, data []uint16, w, h int16) error {
|
func (d *Device) DrawRGBBitmap(x, y int16, data []uint16, w, h int16) error {
|
||||||
|
k, i := d.Size()
|
||||||
|
if x < 0 || y < 0 || w <= 0 || h <= 0 ||
|
||||||
|
x >= k || (x+w) > k || y >= i || (y+h) > i {
|
||||||
|
return err1
|
||||||
|
}
|
||||||
|
d.setWindow(x, y, w, h)
|
||||||
|
d.startWrite()
|
||||||
|
d.driver.write16sl(data)
|
||||||
|
d.endWrite()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DrawRGBBitmap8 copies an RGB bitmap to the internal buffer at given coordinates
|
||||||
|
func (d *Device) DrawRGBBitmap8(x, y int16, data []uint8, w, h int16) error {
|
||||||
k, i := d.Size()
|
k, i := d.Size()
|
||||||
if x < 0 || y < 0 || w <= 0 || h <= 0 ||
|
if x < 0 || y < 0 || w <= 0 || h <= 0 ||
|
||||||
x >= k || (x+w) > k || y >= i || (y+h) > i {
|
x >= k || (x+w) > k || y >= i || (y+h) > i {
|
||||||
@@ -155,7 +173,7 @@ func (d *Device) DrawRGBBitmap(x, y int16, data []uint16, w, h int16) error {
|
|||||||
}
|
}
|
||||||
d.setWindow(x, y, w, h)
|
d.setWindow(x, y, w, h)
|
||||||
d.startWrite()
|
d.startWrite()
|
||||||
d.driver.write16sl(data)
|
d.driver.write8sl(data)
|
||||||
d.endWrite()
|
d.endWrite()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -235,7 +253,8 @@ func (d *Device) SetRotation(rotation Rotation) {
|
|||||||
case 3:
|
case 3:
|
||||||
madctl = MADCTL_MX | MADCTL_MY | MADCTL_MV | MADCTL_BGR
|
madctl = MADCTL_MX | MADCTL_MY | MADCTL_MV | MADCTL_BGR
|
||||||
}
|
}
|
||||||
d.sendCommand(MADCTL, []uint8{madctl})
|
cmdBuf[0] = madctl
|
||||||
|
d.sendCommand(MADCTL, cmdBuf[:1])
|
||||||
d.rotation = rotation
|
d.rotation = rotation
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -266,16 +285,14 @@ func (d *Device) setWindow(x, y, w, h int16) {
|
|||||||
//y += d.rowOffset
|
//y += d.rowOffset
|
||||||
x1 := x + w - 1
|
x1 := x + w - 1
|
||||||
if x != d.x0 || x1 != d.x1 {
|
if x != d.x0 || x1 != d.x1 {
|
||||||
d.sendCommand(CASET, []uint8{
|
cmdBuf[0], cmdBuf[1], cmdBuf[2], cmdBuf[3] = uint8(x>>8), uint8(x), uint8(x1>>8), uint8(x1)
|
||||||
uint8(x >> 8), uint8(x), uint8(x1 >> 8), uint8(x1),
|
d.sendCommand(CASET, cmdBuf[:4])
|
||||||
})
|
|
||||||
d.x0, d.x1 = x, x1
|
d.x0, d.x1 = x, x1
|
||||||
}
|
}
|
||||||
y1 := y + h - 1
|
y1 := y + h - 1
|
||||||
if y != d.y0 || y1 != d.y1 {
|
if y != d.y0 || y1 != d.y1 {
|
||||||
d.sendCommand(PASET, []uint8{
|
cmdBuf[0], cmdBuf[1], cmdBuf[2], cmdBuf[3] = uint8(y>>8), uint8(y), uint8(y1>>8), uint8(y1)
|
||||||
uint8(y >> 8), uint8(y), uint8(y1 >> 8), uint8(y1),
|
d.sendCommand(PASET, cmdBuf[:4])
|
||||||
})
|
|
||||||
d.y0, d.y1 = y, y1
|
d.y0, d.y1 = y, y1
|
||||||
}
|
}
|
||||||
d.sendCommand(RAMWR, nil)
|
d.sendCommand(RAMWR, nil)
|
||||||
@@ -300,7 +317,9 @@ func (d *Device) sendCommand(cmd byte, data []byte) {
|
|||||||
d.dc.Low()
|
d.dc.Low()
|
||||||
d.driver.write8(cmd)
|
d.driver.write8(cmd)
|
||||||
d.dc.High()
|
d.dc.High()
|
||||||
d.driver.write8sl(data)
|
if data != nil {
|
||||||
|
d.driver.write8sl(data)
|
||||||
|
}
|
||||||
d.endWrite()
|
d.endWrite()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+128
@@ -0,0 +1,128 @@
|
|||||||
|
// +build !atsamd51,!atsamd21
|
||||||
|
|
||||||
|
package ili9341
|
||||||
|
|
||||||
|
import (
|
||||||
|
"device/sam"
|
||||||
|
"machine"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
dma "github.com/sago35/tinygo-dma"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
dbg5 = machine.D5
|
||||||
|
dbg6 = machine.D6
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
dbg5.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
||||||
|
dbg6.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
||||||
|
}
|
||||||
|
|
||||||
|
var buf [64]byte
|
||||||
|
|
||||||
|
type spiDriver struct {
|
||||||
|
bus machine.SPI
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
dmatx *dma.DMA
|
||||||
|
desc *dma.DMADescriptor
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewSPI(bus machine.SPI, dc, cs, rst machine.Pin) *Device {
|
||||||
|
from := make([]byte, 256)
|
||||||
|
for i := range from {
|
||||||
|
from[i] = byte(i)
|
||||||
|
}
|
||||||
|
|
||||||
|
dmatx = dma.NewDMA(func(d *dma.DMA) {
|
||||||
|
d.Wait()
|
||||||
|
return
|
||||||
|
})
|
||||||
|
dmatx.SetTrigger(dma.DMAC_CHANNEL_CHCTRLA_TRIGSRC_SERCOM1_TX)
|
||||||
|
dmatx.SetTriggerAction(sam.DMAC_CHANNEL_CHCTRLA_TRIGACT_BURST)
|
||||||
|
desc = dmatx.GetDescriptor()
|
||||||
|
|
||||||
|
return &Device{
|
||||||
|
dc: dc,
|
||||||
|
cs: cs,
|
||||||
|
rst: rst,
|
||||||
|
rd: machine.NoPin,
|
||||||
|
driver: &spiDriver{
|
||||||
|
bus: bus,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pd *spiDriver) configure(config *Config) {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pd *spiDriver) write8(b byte) {
|
||||||
|
buf[0] = b
|
||||||
|
pd.bus.Tx(buf[:1], nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pd *spiDriver) write8n(b byte, n int) {
|
||||||
|
buf[0] = b
|
||||||
|
for i := 0; i < n; i++ {
|
||||||
|
pd.bus.Tx(buf[:1], nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pd *spiDriver) write8sl(b []byte) {
|
||||||
|
if len(b) > 64 {
|
||||||
|
desc.UpdateDescriptor(dma.DescriptorConfig{
|
||||||
|
SRC: unsafe.Pointer(&b[0]),
|
||||||
|
DST: unsafe.Pointer(&pd.bus.Bus.DATA.Reg),
|
||||||
|
SRCINC: dma.DMAC_SRAM_BTCTRL_SRCINC_ENABLE,
|
||||||
|
DSTINC: dma.DMAC_SRAM_BTCTRL_DSTINC_DISABLE,
|
||||||
|
SIZE: uint32(len(b)), // Total size of DMA transfer
|
||||||
|
BLOCKACT: 1,
|
||||||
|
})
|
||||||
|
dmatx.Start()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
pd.bus.Tx(b, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pd *spiDriver) write16(data uint16) {
|
||||||
|
buf[0] = uint8(data >> 8)
|
||||||
|
buf[1] = uint8(data)
|
||||||
|
pd.bus.Tx(buf[:2], nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pd *spiDriver) write16n(data uint16, n int) {
|
||||||
|
for i := 0; i < len(buf); i += 2 {
|
||||||
|
buf[i] = uint8(data >> 8)
|
||||||
|
buf[i+1] = uint8(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < (n >> 5); i++ {
|
||||||
|
pd.bus.Tx(buf[:], nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
pd.bus.Tx(buf[:n%64], nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pd *spiDriver) write16sl(data []uint16) {
|
||||||
|
if len(data) > 64 {
|
||||||
|
desc.UpdateDescriptor(dma.DescriptorConfig{
|
||||||
|
SRC: unsafe.Pointer(&data[0]),
|
||||||
|
DST: unsafe.Pointer(&pd.bus.Bus.DATA.Reg),
|
||||||
|
SRCINC: dma.DMAC_SRAM_BTCTRL_SRCINC_ENABLE,
|
||||||
|
DSTINC: dma.DMAC_SRAM_BTCTRL_DSTINC_DISABLE,
|
||||||
|
SIZE: uint32(len(data) * 2), // Total size of DMA transfer
|
||||||
|
BLOCKACT: 1,
|
||||||
|
})
|
||||||
|
dmatx.Start()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for i, c := 0, len(data); i < c; i++ {
|
||||||
|
buf[0] = uint8(data[i] >> 8)
|
||||||
|
buf[1] = uint8(data[i])
|
||||||
|
pd.bus.Tx(buf[:2], nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user