tinygo.org/x/drivers@v0.27.1-0.20240509133757-7dbca2a54349/ssd1289/ssd1289.go (about) 1 // Package ssd1289 implements a driver for the SSD1289 led matrix controller as packaged on the TFT_320QVT board 2 // 3 // Datasheet: http://aitendo3.sakura.ne.jp/aitendo_data/product_img/lcd/tft2/M032C1289TP/3.2-SSD1289.pdf 4 package ssd1289 5 6 import ( 7 "image/color" 8 "machine" 9 "time" 10 ) 11 12 type Bus interface { 13 Set(data uint16) 14 } 15 16 type Device struct { 17 rs machine.Pin 18 wr machine.Pin 19 cs machine.Pin 20 rst machine.Pin 21 bus Bus 22 } 23 24 const width = int16(240) 25 const height = int16(320) 26 27 func New(rs machine.Pin, wr machine.Pin, cs machine.Pin, rst machine.Pin, bus Bus) Device { 28 d := Device{ 29 rs: rs, 30 wr: wr, 31 cs: cs, 32 rst: rst, 33 bus: bus, 34 } 35 36 rs.Configure(machine.PinConfig{Mode: machine.PinOutput}) 37 wr.Configure(machine.PinConfig{Mode: machine.PinOutput}) 38 cs.Configure(machine.PinConfig{Mode: machine.PinOutput}) 39 rst.Configure(machine.PinConfig{Mode: machine.PinOutput}) 40 41 cs.High() 42 rst.High() 43 wr.High() 44 45 return d 46 } 47 48 func (d *Device) lcdWriteCom(cmd Command) { 49 d.rs.Low() 50 d.lcdWriteBusInt(uint16(cmd)) 51 } 52 53 func (d *Device) lcdWriteDataInt(data uint16) { 54 d.rs.High() 55 d.lcdWriteBusInt(data) 56 } 57 58 func (d *Device) lcdWriteComData(cmd Command, data uint16) { 59 d.lcdWriteCom(cmd) 60 d.lcdWriteDataInt(data) 61 } 62 63 func (d *Device) tx() { 64 d.wr.Low() 65 d.wr.High() 66 } 67 68 func (d *Device) lcdWriteBusInt(data uint16) { 69 d.bus.Set(data) 70 d.tx() 71 } 72 73 func (d *Device) Configure() { 74 d.rst.High() 75 time.Sleep(time.Millisecond * 5) 76 d.rst.Low() 77 time.Sleep(time.Millisecond * 15) 78 d.rst.High() 79 time.Sleep(time.Millisecond * 15) 80 d.cs.Low() 81 82 //Power supply setting 83 d.lcdWriteComData(POWERCONTROL1, 0xA8A4) 84 d.lcdWriteComData(POWERCONTROL2, 0x0000) 85 d.lcdWriteComData(POWERCONTROL3, 0x080C) 86 d.lcdWriteComData(POWERCONTROL4, 0x2B00) 87 d.lcdWriteComData(POWERCONTROL5, 0x00B7) 88 89 //Set R07h at 0021h 90 d.lcdWriteComData(DISPLAYCONTROL, 0x021) 91 92 //Set R00h at 0001h 93 d.lcdWriteComData(OSCILLATIONSTART, 0x0001) 94 95 //Set R07h at 0021h 96 d.lcdWriteComData(DISPLAYCONTROL, 0x023) 97 98 //Set R10h at 0000h, Exit sleep mode 99 d.lcdWriteComData(SLEEPMODE, 0x0000) 100 101 //Wait 30ms 102 time.Sleep(time.Millisecond * 30) 103 104 //Set R07h at 0033h 105 d.lcdWriteComData(DISPLAYCONTROL, 0x033) 106 107 //Entry Mode setting (R11h) 108 //DFM 11 --> 65k 109 //TRANS 0 110 //OEDEF 0 111 //WMODE 0 --> Normal data bus 112 //DMODE 00 --> Ram 113 //TY 01 --> 262k Type A not used as we are in 65k mode. 114 //ID 11 --> Horizontal & Vertical increment 115 //AM 0 --> Horizontal 116 //LG 000 --> No compare register usage 117 d.lcdWriteComData(ENTRYMODE, 0x6030) 118 119 //LCD Driver AC Setting 120 //I couldn't make sense of the documentation fortunately 0 seems to 121 //FLD 0 --> Normal driving 122 //ENWS 0 --> POR mode 123 //BC 1 --> Less flicker 124 //EOR 1 --> Less stripey 125 //WSMD 0 --> not used in POR mode 126 //NW 0 --> Least flicker 127 d.lcdWriteComData(LCDDRIVEACCONTROL, 0x0600) 128 129 //End of documented init 130 131 //RL 0 --> Output shift direction 132 //REV 1 --> Reverse colors 133 //CAD 0 --> Cs on common 134 //BGR 0 --> use RGB color assignment 135 //SM 0 --> standard gate scan sequence 136 //TB 1 --> Display is mirrored with 0 137 //MUX 319 --> Number of lines in display 138 d.lcdWriteComData(DRIVEROUTPUTCONTROL, 0x233F) 139 140 d.cs.High() 141 142 } 143 144 func (d *Device) setXY(x1 uint16, y1 uint16, x2 uint16, y2 uint16) { 145 d.lcdWriteComData(HORIZONTALRAMADDRESSPOSITION, (x2<<8)+x1) 146 d.lcdWriteComData(VERTICALRAMADDRESSSTARTPOSITION, y1) 147 d.lcdWriteComData(VERTICALRAMADDRESSENDPOSITION, y2) 148 d.lcdWriteComData(SETGDDRAMXADDRESSCOUNTER, x1) 149 d.lcdWriteComData(SETGDDRAMYADDRESSCOUNTER, y1) 150 d.lcdWriteCom(RAMDATAREADWRITE) 151 } 152 153 func (d *Device) ClearDisplay() { 154 d.FillDisplay(color.RGBA{0, 0, 0, 255}) 155 } 156 157 func (d *Device) FillDisplay(c color.RGBA) { 158 d.FillRect(0, 0, width, height, c) 159 } 160 161 func encodeColor(c color.RGBA) uint16 { 162 encoded := (uint16(c.B)&248)<<8 | (uint16(c.G)&252)<<3 | (uint16(c.R)&248)>>3 163 return encoded 164 } 165 166 func (d *Device) SetPixel(x, y int16, c color.RGBA) { 167 168 encoded := encodeColor(c) 169 170 d.cs.Low() 171 d.setXY(uint16(x), uint16(y), uint16(x), uint16(y)) 172 d.rs.High() 173 d.lcdWriteBusInt(encoded) 174 d.cs.High() 175 } 176 177 func (d *Device) FillRect(x, y, w, h int16, c color.RGBA) { 178 encoded := encodeColor(c) 179 180 d.cs.Low() 181 d.setXY(uint16(x), uint16(y), uint16(x+(w-1)), uint16(y+(h-1))) 182 d.rs.High() 183 d.bus.Set(encoded) 184 for i := int64(0); i < int64(w)*int64(h); i++ { 185 d.tx() 186 } 187 d.cs.High() 188 d.rs.Low() 189 190 } 191 192 func (d *Device) Display() error { 193 //Not enough memory to store an entire screen on most microcontrollers 194 return nil 195 } 196 197 func (d *Device) Size() (x, y int16) { 198 return width, height 199 }