]> git.defcon.no Git - avrfbosd/blob - fbosd.c
Added support for drawing 8bpp images... Updated demo a bit...
[avrfbosd] / fbosd.c
1 #include <avr/io.h>
2 #include <avr/interrupt.h>
3 #include <util/delay.h>
4 #include <stdlib.h>
5 #include <avr/pgmspace.h>
6
7 #include "video_properties.h"
8 #include "render.h"
9 #include "draw.h"
10
11 //#include "font.h"
12 #include "testimage.h"
13
14 void (*line_handler)( void );
15
16 const int vres_scale = ( SCREEN_LINES / VRES -1 );
17 const int hres_bytes = HRES / 8;
18
19 volatile uint8_t* screen_buffer;
20
21 volatile int line;
22 volatile int buffer_position;
23
24 void Delay_ms(int cnt)
25 {
26 while(cnt-->0) _delay_ms(1);
27 }
28
29 void set_busy ( uint8_t busy)
30 {
31 if ( busy )
32 {
33 // Set busy signal
34 PORTB |= (1 << PB1);
35
36 // TODO: Disable SPI communication here...
37 }
38 else
39 {
40 // Clear Busy signal
41 PORTB &= ~(uint8_t)(1 << PB1);
42
43 // TODO: Enable SPI communication here...
44 }
45 }
46
47 void active_lines ( void )
48 {
49 static uint8_t rept;
50
51 _delay_us(4);
52
53 // Set Busy signal. Line rendering is time-critical.
54 set_busy(1);
55 asm_render_line();
56 set_busy(0);
57
58 if( !rept )
59 {
60 if ( buffer_position < ((VRES*hres_bytes)) )
61 buffer_position += hres_bytes;
62 rept = vres_scale;
63 }
64 else rept--;
65
66 }
67
68 void blank_lines ( void )
69 {
70 // Do nothing on the "lead-in" lines
71 if ( line < FIRST_LINE )
72 return;
73
74 // Clear Frame Ready signal
75 PORTD &= ~(uint8_t)(1 << PD5);
76
77 // Activate rendering
78 line_handler = active_lines;
79 }
80
81 ISR (INT1_vect)
82 {
83 line_handler();
84 line++;
85 if( line > LAST_LINE)
86 {
87 line = 0;
88 buffer_position = 0;
89 line_handler = &blank_lines;
90 EIMSK &= ~(uint8_t)(1<<INT1);
91
92 // Set Frame Ready signal
93 PORTD |= (1 << PD5);
94
95 }
96 }
97
98 ISR (INT0_vect)
99 {
100 // VSync is getting close to done.
101 // Set line-handler to blank-handler to count-up the undesired lines,
102 // and enable HSync interrupts.
103
104 line_handler = &blank_lines;
105
106 EIMSK |= (1<<INT1);
107
108 }
109
110 //Main Function
111 int main(void)
112 {
113 // Note: PB0 is used as CLKO outputting 20MHz clock to ATtiny
114
115 // Set PB2 as Output for BUSY signal
116 DDRB = (1 << PB1);
117
118 // Set PD5 as Output for FR signal
119 // Set PD6 as Output for Status LED
120 // Using pin 7 on PD to clock out pixels \o/
121 DDRD = (1<<PD5)|(1<<PD6)|(1<<PD7);
122
123 // Clear PORTB and PORTD
124 PORTB = 0x0;
125 PORTD = 0x0;
126
127 // Allocate the framebuffer :D
128 screen_buffer = (uint8_t*) malloc( hres_bytes * VRES * sizeof(uint8_t) );
129 // And make sure it's cleared
130 fill(c_BLACK);
131
132 /* LM1881 pins are connected to:
133 INT0 / PCINT18 / PD2 <- VSYNC
134 INT1 / PCINT19 / PD3 <- CSYNC
135 PCINT20 / PD4 <- ODD/EVEN
136 */
137 EICRA |= (1<<ISC01)|(1<<ISC00); // Select Rising-edge interrupt for VSync
138 EICRA |= (1<<ISC11)|(1<<ISC10); // Select Rising-edge interrupt for HSync
139 EIMSK |= (1<<INT0); // Enable VSync-interrupts
140
141 // Enable interrupts globally.
142 sei();
143
144 int counter;
145
146 // Do some static drawing :P
147 set_pixel(28, 8, 1);
148 set_pixel(92, 82, 1);
149
150 set_pixel(92, 8, 1);
151 set_pixel(28, 82, 1);
152
153 draw_line(0, 0, 128, 92, c_WHITE);
154 draw_line(128, 0, 0, 92, c_WHITE);
155
156 draw_rect( 0, 1, 127, 91, c_WHITE);
157
158 draw_rect( 34, 21, 60, 50, c_WHITE);
159 _draw_rect( 24, 11, 80, 70, 1, c_NONE);
160 draw_rect( 34, 21, 60, 50, c_WHITE);
161
162 fill_circle( 64,46, 45, c_WHITE );
163 fill_circle( 64,46, 40, c_BLACK );
164
165 _draw_circle( 64,46, 35, 1, c_NONE );
166 draw_circle( 64,46, 30, c_WHITE );
167 fill_rect( 38, 25, 52, 42, c_WHITE);
168 fill_rect( 41, 28, 46, 36, c_BLACK);
169
170 for (counter = 0; counter < 3; counter++)
171 {
172 // Toggle status LED
173 PORTD ^= (uint8_t)(1 << PD6);
174
175 for ( int j = 0; j < 92; j++ )
176 {
177 draw_line(0,0,128,j, c_INVERT);
178 draw_line(128,0,0,j, c_INVERT);
179 draw_line(0,92,128,92-j, c_INVERT);
180 draw_line(128,92,0,92-j, c_INVERT);
181
182 Delay_ms(2);
183
184 }
185 for ( int j = 0; j < 92; j++ )
186 {
187 draw_line(0,0,128,j, c_INVERT);
188 draw_line(128,0,0,j, c_INVERT);
189 draw_line(0,92,128,92-j, c_INVERT);
190 draw_line(128,92,0,92-j, c_INVERT);
191
192 Delay_ms(2);
193
194 }
195 Delay_ms(250);
196 }
197 fill(c_BLACK);
198
199 int8_t hp = 10;
200 int8_t vp = 10;
201
202 for (counter = 0; counter < 100; counter++)
203 {
204 hp += 2;
205 vp += 1;
206
207 if ( hp > 125 ) hp = 10;
208 if ( vp > VRES ) vp = 10;
209
210 pgm_draw_8bpp_bitmap(hp, vp, testimage_width, testimage_height, testimage);
211 Delay_ms(10);
212 fill_rect(hp, vp, testimage_width, testimage_height, 0);
213 }
214 for (;;)
215 {
216 }
217
218 }
219