summaryrefslogtreecommitdiff
path: root/main.cpp
blob: eab4e69b8b9cc55b509763b79670949b0f531505 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#include <rcc/rcc.h>
#include <gpio/pin.h>
#include <spi/spi.h>
#include <os/time.h>

Pin& noe   = PA3;
Pin& vsync = PA4;
Pin& clk   = PA5; // SCK
Pin& hsync = PA6; 
Pin& data  = PA7; // MOSI

inline void nopdelay(uint32_t iterations) {
	while(iterations--) {
		asm volatile("nop");
	}
}

uint32_t buf[] = {
	0b1001010100000000,
	0b1001010100000000,
	0b1111010100000000,
	0b1001010000000000,
	0b1001010100000000,
	0b0000000000000000,
	0b0000000000000000,
	0b0000000000000000,
	0b0000000000000000,
	0b0000000000000000,
	0b0000000000000000,
	0b0000000000000000,
	0b0000000000000000,
	0b0000000000000000,
	0b0000000000000000,
	0b0000000000000000,
};

int main() {
	// Initialize system timer.
	STK.LOAD = 168000000 / 8 / 1000; // 1000 Hz.
	STK.CTRL = 0x03;
	
	RCC.enable(RCC.GPIOA);
	RCC.enable(RCC.SPI1);
	
	noe.set_mode(Pin::Output);
	noe.off();
	
	hsync.set_mode(Pin::Output);
	hsync.off();
	
	vsync.set_mode(Pin::Output);
	vsync.on();
	
	clk.set_mode(Pin::AF);
	clk.set_af(5);
	
	data.set_mode(Pin::AF);
	data.set_af(5);
	
	SPI1.reg.CR1 = 0xbfc;
	
	uint32_t row = 0;
	
	while(1) {
		// Shift out a row.
		SPI1.reg.DR = buf[row];
		while(!(SPI1.reg.SR & 0x01));
		(void)SPI1.reg.DR;
		
		// Assert vsync if this is first row.
		if(row == 0) {
			vsync.off();
		}
		
		// Strobe hsync.
		hsync.on();
		nopdelay(10);
		hsync.off();
		
		// Deassert vsync.
		if(row == 0) {
			vsync.on();
		}
		
		Time::sleep(1);
		
		row = (row + 1) & 0xf;
	}
}