#include <avr/interrupt.h>
#include <util/delay.h>
#include <stdlib.h>
+#include <avr/pgmspace.h>
#include "video_properties.h"
#include "render.h"
#include "draw.h"
+#include "testimage.h"
+
void (*line_handler)( void );
const int vres_scale = ( SCREEN_LINES / VRES -1 );
while(cnt-->0) _delay_ms(1);
}
+void set_busy ( uint8_t busy)
+{
+ if ( busy )
+ {
+ // Set busy signal
+ PORTB |= (1 << PB1);
+
+ // TODO: Disable SPI communication here...
+ }
+ else
+ {
+ // Clear Busy signal
+ PORTB &= ~(uint8_t)(1 << PB1);
+
+ // TODO: Enable SPI communication here...
+ }
+}
+
void active_lines ( void )
{
static uint8_t rept;
_delay_us(4);
+ // Set Busy signal. Line rendering is time-critical.
+ set_busy(1);
asm_render_line();
+ set_busy(0);
if( !rept )
{
buffer_position += hres_bytes;
rept = vres_scale;
}
- else
- rept--;
+ else rept--;
}
void blank_lines ( void )
{
+ // Do nothing on the "lead-in" lines
if ( line < FIRST_LINE )
- {
- PORTB ^= 0x001;
return;
- }
+
+ // Clear Frame Ready signal
+ PORTD &= ~(uint8_t)(1 << PD5);
+
+ // Activate rendering
line_handler = active_lines;
}
buffer_position = 0;
line_handler = &blank_lines;
EIMSK &= ~(uint8_t)(1<<INT1);
+
+ // Set Frame Ready signal
+ PORTD |= (1 << PD5);
+
}
}
//Main Function
int main(void)
{
+ // Note: PB0 is used as CLKO outputting 20MHz clock to ATtiny
- // Using some pins on PORTB for debug-indicator-LEDs
- DDRB = (1<< PB0)|(1 << PB1)|(1 << PB2);
- PORTB = 0x0;
-
+ // Set PB2 as Output for BUSY signal
+ DDRB = (1 << PB1);
+
+ // Set PD5 as Output for FR signal
+ // Set PD6 as Output for Status LED
// Using pin 7 on PD to clock out pixels \o/
- DDRD = (1<<PD7);
+ DDRD = (1<<PD5)|(1<<PD6)|(1<<PD7);
+
+ // Clear PORTB and PORTD
+ PORTB = 0x0;
PORTD = 0x0;
+ // Allocate the framebuffer :D
+ screen_buffer = (uint8_t*) malloc( hres_bytes * VRES * sizeof(uint8_t) );
+ // And make sure it's cleared
+ fill(c_BLACK);
+
/* LM1881 pins are connected to:
INT0 / PCINT18 / PD2 <- VSYNC
INT1 / PCINT19 / PD3 <- CSYNC
*/
EICRA |= (1<<ISC01)|(1<<ISC00); // Select Rising-edge interrupt for VSync
EICRA |= (1<<ISC11)|(1<<ISC10); // Select Rising-edge interrupt for HSync
- EIMSK |= (1<<INT0); // Enable VSync-interrupts
+ EIMSK |= (1<<INT0); // Enable VSync-interrupts
- // And enable interrupts globally.
+ // Enable interrupts globally.
sei();
- // Allocate the framebuffer :D
- screen_buffer = (uint8_t*) malloc( hres_bytes * VRES * sizeof(uint8_t) );
- // And make sure it's cleared
- fill(c_BLACK);
-
- // Do some static drawing :P
- set_pixel(28, 8, 1);
- set_pixel(92, 82, 1);
-
- set_pixel(92, 8, 1);
- set_pixel(28, 82, 1);
-
-
- draw_line(0, 0, 128, 92, 1);
- draw_line(128, 0, 0, 92, 1);
+ // Switch ON status LED
+ PORTD |= (uint8_t)(1 << PD6);
- draw_rect( 0, 1, 127, 91, 1);
-
- draw_rect( 34, 21, 60, 50, 1);
- _draw_rect( 24, 11, 80, 70, 1, -1);
- draw_rect( 34, 21, 60, 50, 1);
+ for (;;)
+ {
+ Delay_ms(100);
+ draw_string( 2, 2, "!\"#$%&'()*+-./");
+ draw_string( 2, 10, "01234567890");
+ draw_string( 2, 18, ":;<=>?@");
+ draw_string( 2, 26, "ABCDEFGHIJKLM");
+ draw_string( 2, 34, "NOPQRSTUVWXYZ");
+ draw_string( 2, 42, "[\\]^_`");
+ draw_string( 2, 50, "ABCDEFGHIJKLM");
+ draw_string( 2, 58, "NOPQRSTUVWXYZ");
+ draw_string( 2, 66, "{|}~");
+
+ draw_char( 10, 80, 127);
+ draw_char( 20, 80, 128);
+ draw_char( 30, 80, 129);
+ draw_char( 40, 80, 130);
+
+ Delay_ms(500);
+ clear_screen();
+
+ // Do some static drawing :P
+ set_pixel(28, 8, 1);
+ set_pixel(92, 82, 1);
+
+ set_pixel(92, 8, 1);
+ set_pixel(28, 82, 1);
+
+ draw_line(0, 0, 128, 92, c_WHITE);
+ draw_line(128, 0, 0, 92, c_WHITE);
+
+ draw_rect( 0, 1, 127, 91, c_WHITE);
+
+ draw_rect( 34, 21, 60, 50, c_WHITE);
+ _draw_rect( 24, 11, 80, 70, 1, c_NONE);
+ draw_rect( 34, 21, 60, 50, c_WHITE);
+
+ fill_circle( 64,46, 45, c_WHITE );
+ fill_circle( 64,46, 40, c_BLACK );
+
+ _draw_circle( 64,46, 35, 1, c_NONE );
+ draw_circle( 64,46, 30, c_WHITE );
+ fill_rect( 38, 25, 52, 42, c_WHITE);
+ fill_rect( 41, 28, 46, 36, c_BLACK);
+
+ for ( int j = 0; j < 92; j++ )
+ {
+ draw_line(0,0,128,j, c_INVERT);
+ draw_line(128,0,0,j, c_INVERT);
+ draw_line(0,92,128,92-j, c_INVERT);
+ draw_line(128,92,0,92-j, c_INVERT);
+ Delay_ms(2);
- _draw_circle( 64,46, 35, 1, -1 );
- draw_circle( 64,46, 30, 1 );
- fill_circle( 64,46, 25, 1 );
- fill_circle( 64,46, 20, 0 );
- fill_rect( 44, 31, 40, 30, 1);
- fill_rect( 54, 41, 20, 10, 0);
+ }
+ for ( int j = 0; j < 92; j++ )
+ {
+ draw_line(0,0,128,j, c_INVERT);
+ draw_line(128,0,0,j, c_INVERT);
+ draw_line(0,92,128,92-j, c_INVERT);
+ draw_line(128,92,0,92-j, c_INVERT);
- for (;;)
- PORTB ^= 0x002;
+ Delay_ms(2);
- for ( int j = 8; j < 89; j++ )
+ }
+ Delay_ms(250);
+ clear_screen();
+
+ int8_t hp = 10;
+ int8_t vp = 10;
+
+ int counter = 0;
+ for (counter = 0; counter < 60; counter++)
{
- draw_line(8,88-j,120,j, 2);
- draw_line(120,j,8,88-j, 2);
- Delay_ms(5);
- draw_line(8,88-j,120,j, 2);
- Delay_ms(5);
+ hp += 2;
+ vp += 1;
+
+ if ( hp > 125 ) hp = 10;
+ if ( vp > VRES ) vp = 10;
+
+ pgm_draw_8bpp_bitmap(hp, vp, testimage_width, testimage_height, testimage);
+ Delay_ms(10);
+ //fill_rect(hp, vp, testimage_width, testimage_height, 0);
+ clear_screen();
}
- Delay_ms(150);
+ clear_screen();
+
}
}
-
-