avr-something

Something something AVR side…
git clone git://henryandlizzy.uk/avr-something
Log | Files | Refs | README

lcd.cpp (4582B)


      1 #include "lcd.h"
      2 #include "hidModule.h"
      3 
      4 #include <util/delay.h>
      5 #include "font.h"
      6 
      7 /*
      8 	A0~ chip select
      9 	A1  Backlight
     10 	A2~ Reset
     11 	A3~ Write
     12 	A4~ Command
     13 	A5~ Read
     14 	A6~ Vsync
     15 	A7~ Hsync
     16 
     17 	C[0-7] DATA BUS
     18 */
     19 namespace lcd {
     20 
     21 void send(const uint8_t d)
     22 {
     23 	control() = defaultControl & n_write;
     24 	data() = d;
     25 	control() = defaultControl;
     26 }
     27 
     28 void send(const uint16_t d)
     29 {
     30 	send(uint8_t(d >> 8));
     31 	send(uint8_t(d));
     32 }
     33 
     34 template <typename...Ts>
     35 void cmd(const uint8_t c, Ts... params)
     36 {
     37 	control() = defaultControl & n_command & n_write;
     38 	data() = c;
     39 	control() = defaultControl;
     40 	
     41 	// https://stackoverflow.com/questions/25680461/variadic-template-pack-expansion#25683817
     42 	// TODO:(C++17)      (send(params), ...);
     43 	char dummy[] __attribute__((unused)) {0, (send(uint8_t(params)), '\0')...};
     44 }
     45 
     46 void fillScreen(uint16_t colour)
     47 {
     48 	cmd(0x2C);
     49 	uint8_t j = (320ul * 240) / (256 * 2);
     50 	uint8_t i = 0; // uses wraparound
     51 	do
     52 	{
     53 		do {
     54 			lcd::send(colour);
     55 			lcd::send(colour);
     56 		} while (--i);
     57 	} while (--j);
     58 }
     59 
     60 void init()
     61 {
     62 	controlDir() = 0xFF;
     63 	dataDir() = 0xFF;
     64 	
     65 	control() = defaultControl & n_reset;
     66 	_delay_us(16);
     67 	control() = defaultControl;
     68 	_delay_ms(128);
     69 	
     70 	
     71 	cmd(0x11); // awake
     72 	_delay_ms(6);
     73 	
     74 	cmd(0x3A, 0x55); // 16 bits per pixel
     75 	
     76 	fillScreen(0);
     77 	
     78 	cmd(0x36, 0x20); // x/y -> y/x
     79 	
     80 	cmd(0x29); // display ON
     81 }
     82 
     83 union colour
     84 {
     85 	struct __attribute__((packed)) {
     86 		uint8_t r:5;
     87 		uint8_t g:6;
     88 		uint8_t b:5;
     89 	};
     90 	uint16_t word;
     91 	
     92 	constexpr colour(uint16_t const val = 0)
     93 	:	word(val)
     94 	{}
     95 	
     96 	constexpr colour(uint8_t const red, uint8_t const green, uint8_t const blue)
     97 	:	r(red)
     98 	,	g(green)
     99 	,	b(blue)
    100 	{}
    101 	constexpr operator uint16_t() const
    102 	{
    103 		return word;
    104 	}
    105 	static constexpr auto grey(uint8_t val)
    106 	{
    107 		return colour(val >> 1, val, val >> 1);
    108 	}
    109 } p;
    110 
    111 static_assert(sizeof(colour) == sizeof(uint16_t), "not correct size");
    112 
    113 [[noreturn]]
    114 void test()
    115 {
    116 
    117 	
    118 	init();
    119 	
    120 	cmd(0x2C);
    121 	
    122 	for (;;)
    123 	{
    124 		//if (0 == ++p.r) if (0 == ++p.b) --p.g;
    125 		
    126 		//send(p.word);
    127 		//send(uint16_t(0xF800));
    128 		auto x = hid::sampleInput();
    129 		send(x);
    130 		send(x);
    131 	}
    132 }
    133 
    134 void setColumns(const uint16_t start, const uint16_t end)
    135 {
    136 	cmd(0x2A);
    137 	send(start);
    138 	send(end);
    139 }
    140 
    141 void setRows(const uint16_t start, const uint16_t end)
    142 {
    143 	cmd(0x2B);
    144 	send(start);
    145 	send(end);
    146 }
    147 
    148 struct drawSequence
    149 {
    150 	drawSequence()
    151 	{
    152 		cmd(0x2C);
    153 	}
    154 	~drawSequence()
    155 	{
    156 		cmd(0);
    157 	}
    158 };
    159 
    160 struct
    161 {
    162 	void putc(const char c)
    163 	{
    164 		switch (c)
    165 		{
    166 			case '\n':
    167 				newline();
    168 				return;
    169 			case '\f':
    170 				y = 0;
    171 				// fallthrough
    172 			case '\r':
    173 				cr();
    174 				return;
    175 			case 0x7F:
    176 				x -= 8;
    177 				putc(' ');
    178 				x -= 8;
    179 				return;
    180 		}
    181 		
    182 		setColumns(x, x + 7);
    183 		setRows(y, y + 7);
    184 		advance();
    185 		
    186 		auto g = drawSequence();
    187 		
    188 		auto bytePtr = flashPtr<uint8_t>(fonts::mash[c - ' ']);
    189 		
    190 		uint8_t x = 8;
    191 		do
    192 		{
    193 			auto byte = bytePtr.load_post_inc();
    194 			send(byte & bit(7) ? foreground : background);
    195 			send(byte & bit(6) ? foreground : background);
    196 			send(byte & bit(5) ? foreground : background);
    197 			send(byte & bit(4) ? foreground : background);
    198 			send(byte & bit(3) ? foreground : background);
    199 			send(byte & bit(2) ? foreground : background);
    200 			send(byte & bit(1) ? foreground : background);
    201 			send(byte & bit(0) ? foreground : background);
    202 		}
    203 		while (--x);
    204 	}
    205 	void newline()
    206 	{
    207 		y += 8;
    208 		cr();
    209 	}
    210 	void cr()
    211 	{
    212 		x = 0;
    213 	}
    214 	void advance(uint8_t count = 1)
    215 	{
    216 		if (x >= 320 - 8) newline();
    217 		else x += count * 8;
    218 	}
    219 	void puts_ram(char const* str)
    220 	{
    221 		while (auto c = *str++) putc(c);
    222 	}
    223 	void puts(flashPtr<char> str)
    224 	{
    225 		while (auto c = str.load_post_inc()) putc(c);
    226 	}
    227 	void putu(uint16_t val)
    228 	{
    229 		if (val >= 10)
    230 		{
    231 			putu(val / 10);
    232 			putc(val % 10 + '0');
    233 		}
    234 		else
    235 		{
    236 			putc(val + '0');
    237 		}
    238 	}
    239 	void puti(int16_t val)
    240 	{
    241 		if (val < 0)
    242 		{
    243 			putc('-');
    244 			putu(-val); // does not handle min(int16_t)
    245 			return;
    246 		}
    247 		putu(val);
    248 	}
    249 
    250 	uint16_t x = 0, y = 0;
    251 	uint16_t foreground = white;
    252 	uint16_t background = dgrey;
    253 	fonts::glyph const* glyphs = fonts::mash;
    254 } lout;
    255 
    256 char const testStr[] [[gnu::__progmem__]] = "\n\nHello, World!\nIt is a very nice day today, what are you up to this afternoon?\n";
    257 
    258 char const clearNum[] [[gnu::__progmem__]] = "\r      \r";
    259 
    260 void testFont()
    261 {
    262 	lout.foreground = green;
    263 	for (char c = ' '; c < 0x7F;)
    264 	{
    265 		lout.putc(c);
    266 		if (not (++c % 0x10)) lout.newline();
    267 	}
    268 	lout.background = black;
    269 	lout.foreground = colour(0xF,0x0,0xF);
    270 	
    271 	lout.puts(testStr);
    272 	lout.putu(5);
    273 	lout.newline();
    274 	lout.newline();
    275 	return;
    276 	lout.foreground = white;
    277 	int16_t x = -32000;
    278 	for (;;)
    279 	{
    280 		lout.puti(x);
    281 		x += 10;
    282 		_delay_ms(50);
    283 		lout.puts(clearNum);
    284 	}
    285 }
    286 
    287 }