Skip to content

Commit

Permalink
Merge branch 'bugskiller-new-tvout-lib'
Browse files Browse the repository at this point in the history
  • Loading branch information
MikyM0use authored and MikyM0use committed Jul 8, 2016
2 parents acef482 + 5c73a88 commit 1c6586f
Show file tree
Hide file tree
Showing 9 changed files with 224 additions and 263 deletions.
171 changes: 27 additions & 144 deletions libs/TVout/TVout.cpp
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
*/
char TVout::begin(uint8_t mode) {

return begin(mode,128,96);
return begin(mode, 128, 96);
} // end of begin


Expand All @@ -74,19 +74,23 @@ char TVout::begin(uint8_t mode) {
char TVout::begin(uint8_t mode, uint8_t x, uint8_t y) {

// check if x is divisable by 8
if ( !(x & 0xF8))
if ( !(x & 0xF8)) {
return 1;
x = x/8;
}

x = x / 8;

screen = (unsigned char*)malloc(x * y * sizeof(unsigned char));
if (screen == NULL)
if (screen == NULL) {
return 4;
}

cursor_x = 0;
cursor_y = 0;

render_setup(mode,x,y,screen);
render_setup(mode, x, y, screen);
clear_screen();

return 0;
} // end of begin

Expand Down Expand Up @@ -134,7 +138,7 @@ void TVout::fill(uint8_t color) {
* The horizonal resolution.
*/
unsigned char TVout::hres() {
return display.hres*8;
return display.hres * 8;
} // end of hres


Expand All @@ -155,7 +159,7 @@ unsigned char TVout::vres() {
* Will return -1 for dynamic width fonts as this cannot be determined.
*/
char TVout::char_line() {
return ((display.hres*8)/pgm_read_byte(font));
return ((display.hres * 8) / pgm_read_byte(font));
} // end of char_line


Expand All @@ -172,6 +176,17 @@ void TVout::delay(unsigned int x) {
} // end of delay


/* Get the time in ms since begin was called.
* The resolution is 16ms for NTSC and 20ms for PAL
*
* Returns:
* The time in ms since video generation has started.
*/
unsigned long TVout::millis() {
return display.frames * _PAL_TIME_SCANLINE * _PAL_LINE_FRAME / 1000;
} // end of millis


/* Delay for x frames, exits at the end of the last display line.
* delay_frame(1) is useful prior to drawing so there is little/no flicker.
*
Expand All @@ -180,7 +195,7 @@ void TVout::delay(unsigned int x) {
* The number of frames to delay for.
*/
void TVout::delay_frame(unsigned int x) {
int stop_line = (int)(display.start_render + (display.vres*(display.vscale_const+1)))+1;
int stop_line = (int)(display.first_half_frame_start_render + (display.vres * (display.vscale_const + 1))) + 1;
while (x) {
while (display.scanLine != stop_line);
while (display.scanLine == stop_line);
Expand All @@ -189,22 +204,6 @@ void TVout::delay_frame(unsigned int x) {
} // end of delay_frame


/* Get the time in ms since begin was called.
* The resolution is 16ms for NTSC and 20ms for PAL
*
* Returns:
* The time in ms since video generation has started.
*/
unsigned long TVout::millis() {
if (display.lines_frame == _NTSC_LINE_FRAME) {
return display.frames * _NTSC_TIME_SCANLINE * _NTSC_LINE_FRAME / 1000;
}
else {
return display.frames * _PAL_TIME_SCANLINE * _PAL_LINE_FRAME / 1000;
}
} // end of millis


/* force the number of times to display each line.
*
* Arguments:
Expand Down Expand Up @@ -238,7 +237,10 @@ void TVout::force_outstart(uint8_t time) {
*/
void TVout::force_linestart(uint8_t line) {
delay_frame(1);
display.start_render = line;
display.first_half_frame_start_render = line;
display.first_half_frame_end_render = display.first_half_frame_start_render + (display.vres * (display.vscale_const + 1));
display.second_half_frame_start_render = display.lines_frame + display.first_half_frame_start_render;
display.second_half_frame_end_render = display.lines_frame + display.first_half_frame_end_render;
}


Expand Down Expand Up @@ -756,122 +758,3 @@ static void inline sp(uint8_t x, uint8_t y, char c) {
else
display.screen[(x/8) + (y*display.hres)] ^= 0x80 >> (x&7);
} // end of sp


/* set the vertical blank function call
* The function passed to this function will be called one per frame. The function should be quickish.
*
* Arguments:
* func:
* The function to call.
*/
void TVout::set_vbi_hook(void (*func)()) {
vbi_hook = func;
} // end of set_vbi_hook


/* set the horizonal blank function call
* This function passed to this function will be called one per scan line.
* The function MUST be VERY FAST(~2us max).
*
* Arguments:
* funct:
* The function to call.
*/
void TVout::set_hbi_hook(void (*func)()) {
hbi_hook = func;
} // end of set_bhi_hook


/* Simple tone generation
*
* Arguments:
* frequency:
* the frequency of the tone
* courtesy of adamwwolf
*/
void TVout::tone(unsigned int frequency) {
tone(frequency, 0);
} // end of tone


/* Simple tone generation
*
* Arguments:
* frequency:
* the frequency of the tone
* duration_ms:
* The duration to play the tone in ms
* courtesy of adamwwolf
*/
void TVout::tone(unsigned int frequency, unsigned long duration_ms) {

if (frequency == 0)
return;

#define TIMER 2
//this is init code
TCCR2A = 0;
TCCR2B = 0;
TCCR2A |= _BV(WGM21);
TCCR2B |= _BV(CS20);
//end init code

//most of this is taken from Tone.cpp from Arduino
uint8_t prescalarbits = 0b001;
uint32_t ocr = 0;


DDR_SND |= _BV(SND_PIN); //set pb3 (digital pin 11) to output

//we are using an 8 bit timer, scan through prescalars to find the best fit
ocr = F_CPU / frequency / 2 - 1;
prescalarbits = 0b001; // ck/1: same for both timers
if (ocr > 255) {
ocr = F_CPU / frequency / 2 / 8 - 1;
prescalarbits = 0b010; // ck/8: same for both timers

if (ocr > 255) {
ocr = F_CPU / frequency / 2 / 32 - 1;
prescalarbits = 0b011;
}

if (ocr > 255) {
ocr = F_CPU / frequency / 2 / 64 - 1;
prescalarbits = TIMER == 0 ? 0b011 : 0b100;
if (ocr > 255) {
ocr = F_CPU / frequency / 2 / 128 - 1;
prescalarbits = 0b101;
}

if (ocr > 255) {
ocr = F_CPU / frequency / 2 / 256 - 1;
prescalarbits = TIMER == 0 ? 0b100 : 0b110;
if (ocr > 255) {
// can't do any better than /1024
ocr = F_CPU / frequency / 2 / 1024 - 1;
prescalarbits = TIMER == 0 ? 0b101 : 0b111;
}
}
}
}
TCCR2B = prescalarbits;

if (duration_ms > 0)
remainingToneVsyncs = duration_ms*60/1000; //60 here represents the framerate
else
remainingToneVsyncs = -1;

// Set the OCR for the given timer,
OCR2A = ocr;
//set it to toggle the pin by itself
TCCR2A &= ~(_BV(COM2A1)); //set COM2A1 to 0
TCCR2A |= _BV(COM2A0);
} // end of tone

/* Stops tone generation
*/
void TVout::noTone() {
TCCR2B = 0;
PORT_SND &= ~(_BV(SND_PIN)); //set pin 11 to 0
} // end of noTone
9 changes: 0 additions & 9 deletions libs/TVout/TVout.h
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -104,15 +104,6 @@ class TVout {
void draw_circle(uint8_t x0, uint8_t y0, uint8_t radius, char c, char fc = -1);
void bitmap(uint8_t x, uint8_t y, const unsigned char * bmp, uint16_t i = 0, uint8_t width = 0, uint8_t lines = 0);

//hook setup functions
void set_vbi_hook(void (*func)());
void set_hbi_hook(void (*func)());

//tone functions
void tone(unsigned int frequency, unsigned long duration_ms);
void tone(unsigned int frequency);
void noTone();

//The following function definitions can be found in TVoutPrint.cpp
//printing functions
void print_char(uint8_t x, uint8_t y, unsigned char c);
Expand Down
Empty file modified libs/TVout/TVoutPrint.cpp
100755 → 100644
Empty file.
Empty file modified libs/TVout/spec/asm_macros.h
100755 → 100644
Empty file.
Empty file modified libs/TVout/spec/hardware_setup.h
100755 → 100644
Empty file.
87 changes: 59 additions & 28 deletions libs/TVout/spec/video_properties.h
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -32,36 +32,67 @@

#define _CYCLES_PER_US (F_CPU / 1000000)

#define _TIME_HORZ_SYNC 4.7
#define _TIME_VIRT_SYNC 58.85
#define _TIME_ACTIVE 46
#define _CYCLES_VIRT_SYNC ((_TIME_VIRT_SYNC * _CYCLES_PER_US) - 1)
#define _CYCLES_HORZ_SYNC ((_TIME_HORZ_SYNC * _CYCLES_PER_US) - 1)

//Timing settings for NTSC
#define _NTSC_TIME_SCANLINE 63.55
#define _NTSC_TIME_OUTPUT_START 12

#define _NTSC_LINE_FRAME 262
#define _NTSC_LINE_START_VSYNC 0
#define _NTSC_LINE_STOP_VSYNC 3
#define _NTSC_LINE_DISPLAY 216
#define _NTSC_LINE_MID ((_NTSC_LINE_FRAME - _NTSC_LINE_DISPLAY)/2 + _NTSC_LINE_DISPLAY/2)

#define _NTSC_CYCLES_SCANLINE ((_NTSC_TIME_SCANLINE * _CYCLES_PER_US) - 1)
#define _NTSC_CYCLES_OUTPUT_START ((_NTSC_TIME_OUTPUT_START * _CYCLES_PER_US) - 1)

//Timing settings for PAL
#define _PAL_TIME_SCANLINE 64
#define _PAL_TIME_OUTPUT_START 12.5

#define _PAL_LINE_FRAME 312
#define _PAL_LINE_START_VSYNC 0
#define _PAL_LINE_STOP_VSYNC 7
#define _PAL_LINE_DISPLAY 260
#define _PAL_LINE_MID ((_PAL_LINE_FRAME - _PAL_LINE_DISPLAY)/2 + _PAL_LINE_DISPLAY/2)
// Timing settings for PAL
// Front porch (A): 1.65 µs +0.4/-0.1
// Sync pulse length (B): 4.7 µs +0.2/-0.2
// Back porch (C): 5.7 µs +0.2/-0.2
// Active video (D): 51.95 µs +0.4/-0.1
// Total horizontal sync time: 12.05 µs / 12.00 µs + 0.15 µs
// Total time for each line: 64.00 µs
//
// 312.5 - 287.5 = 25 lines (Vertical Blanking Width: Blank lines/field)
// Vertical lines: 312.5 / 312-313 (625 total) ??? 288 + 25 = 313
// Vertical lines visible: 287.5 / 288 (575 / 576 total)
// Vertical Frequency: 50 Hz = 25 * 2
// Vertical Period: 20 ms = 312.5 * 64 µs
// Vertical Equalizing Pulse Width: 2.35 µs ???
// Vertical sync polarity: Negative (burst)
// Sync pulse length (F): 0.576 ms (burst) ???
// Active video (H): 18.4 ms

// Vertical "Equalizing pulses":
// Vert. “front porch” *b: 2.5 lines = 160 µs ???
// Vert sync. pulse width *b: 2.5 lines = 160 µs ???
// Vert. “back porch” *b,*c: 2.5 + 17.5 = 20 lines = 20 * 64 µs = 1.28 ms
// Vertical Blanking Width: 25 lines = 25 * 64 µs = 1.6 ms
// Total vertical sync time: 1.6 ms = 25 * 64 µs

// *b Due to the interlaced format used in both systems, the vertical blanking interval is somewhat more complex than this description would indicate. “Equalizing pulses,” of twice the normal rate of the horizontal synchronization pulses but roughly half the duration, replace the standard H. sync pulse during the vertical front porch, sync pulse, and the first few lines of the back porch.

// *c The “back porch” timings given here are separated into the time during which equalization pulses are produced (thepostequalization period) and the remaining “normal” line times.

// Analog Video Vertical Sync: https://www.youtube.com/watch?v=NY2rIjkH1Xw
// PAL video timing specification: http://martin.hinner.info/vga/pal.html
// NTSC format description: http://martin.hinner.info/vga/pal.gif

// Timing settings for PAL
#define _PAL_LINE_FULL_FRAME 625 // lines
#define _PAL_LINE_FRAME (_PAL_LINE_FULL_FRAME / 2) // lines

#define _PAL_TIME_RENDERING_LINE 46 // µs
#define _PAL_LINE_DISPLAY 260 // lines
#define _PAL_LINE_MID ((_PAL_LINE_FRAME - _PAL_LINE_DISPLAY) / 2 + _PAL_LINE_DISPLAY / 2) // lines

#define _PAL_TIME_SCANLINE 64 // µs
#define _PAL_TIME_HORZ_SYNC 4.7 // µs
#define _PAL_TIME_OUTPUT_START 12.5 // µs

#define _PAL_CYCLES_SCANLINE ((_PAL_TIME_SCANLINE * _CYCLES_PER_US) - 1)
#define _PAL_CYCLES_HORZ_SYNC ((_PAL_TIME_HORZ_SYNC * _CYCLES_PER_US) - 1)
#define _PAL_CYCLES_OUTPUT_START ((_PAL_TIME_OUTPUT_START * _CYCLES_PER_US) - 1)

#define _PAL_TIME_VSYNC_SCANLINE (_PAL_TIME_SCANLINE / 2) // µs
#define _PAL_TIME_VSYNC_PRE_EQUALIZING 2.3 // µs 2.4
#define _PAL_TIME_VSYNC_INVERTED_EQUALIZING 4.7 // µs

#define _PAL_CYCLES_VSYNC_SCANLINE ((_PAL_TIME_VSYNC_SCANLINE * _CYCLES_PER_US) - 1)
#define _PAL_CYCLES_VSYNC_PRE_EQUALIZING ((_PAL_TIME_VSYNC_PRE_EQUALIZING * _CYCLES_PER_US) - 1)
#define _PAL_CYCLES_VSYNC_EQUALIZING (((_PAL_TIME_VSYNC_SCANLINE - _PAL_TIME_VSYNC_INVERTED_EQUALIZING) * _CYCLES_PER_US) - 1)

#define _PAL_LINE_NUMBER_TO_START_SECONDFRAME_VSYNC 310 // line# 311
#define _PAL_LINE_NUMBER_TO_START_SECONDFRAME_BLANKING 318 // line# 318

#define _PAL_LINE_NUMBER_TO_START_FIRSTFRAME_VSYNC 622 // line# 623
#define _PAL_LINE_NUMBER_TO_START_FIRSTFRAME_BLANKING 5 // line# 6

#endif
Empty file modified libs/TVout/version history.txt
100755 → 100644
Empty file.
Loading

0 comments on commit 1c6586f

Please sign in to comment.