![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
it works!
Dependencies: SDFileSystem2 mbed
Fork of manworm_tv_raster by
main.cpp
- Committer:
- bwang
- Date:
- 2018-10-04
- Revision:
- 16:1f728d08b3a7
- Parent:
- 14:5ee7843f2805
File content as of revision 16:1f728d08b3a7:
#include "mbed.h" #include <math.h> #include "main.h" #include "SDFileSystem.h" #define TEXT_LEVEL 5 #define TX 24 // number of characters in X #define TY 10 // number of characters in Y #define CHECK_BIT(var,pos) ((var) & (1<<(pos))) #define MIN(a,b) (((a)<(b))?(a):(b)) #define MAX(a,b) (((a)>(b))?(a):(b)) // DAC stuff #define DAC_SYNC 2 uint8_t char_col = 0; // current column counter uint8_t char_row = 0; // current row counter Serial pc(USBTX, USBRX); #include "vincent_data.h" //DigitalOut sout(D8); //sync PA_9 //DigitalOut vout(D7); //video PA_8 DigitalOut dac0(PA_4); DigitalOut dac1(PA_5); DigitalOut dac2(PA_6); DigitalOut dac3(PA_7); DigitalOut user_led(PB_14); int led_state = 1; // trigger horizontal line draw Ticker t; uint8_t bl_line_s[H_RES]; //blank line sync buffer uint8_t bl_line_v[H_RES]; //blank line video buffer uint8_t vb_line_s[H_RES]; //vertical sync, sync buffer uint8_t vb_line_v[H_RES]; //vertical sync, video buffer uint8_t im_line_s[H_RES]; //image sync buffer //buffers uint8_t current_frame[YL][XL / 2]; uint8_t im_line_va_1[H_RES*V_RES]; uint8_t im_line_va_2[H_RES*V_RES]; //double buffered drawing uint8_t* im_line_va; uint8_t* im_back; uint16_t l=0; //current line of scan uint32_t tics = 0; //timer // positive or negative? int16_t sign(int16_t a) { if(a > 0) return 1; if(a < 0) return -1; return 0; } // clear the screen and the text buffer void clr() { for(int i = 0; i < H_RES; i++) for(int j = 0; j < V_RES; j++) im_line_va[i+j*H_RES] = 0; } // initialize video buffers void init_buffers() { clr(); // zero buffers for(int i = 0; i < H_RES; i++) { im_line_s[i] = DAC_SYNC; bl_line_s[i] = DAC_SYNC; bl_line_v[i] = 0; vb_line_s[i] = 0; vb_line_v[i] = 0; } im_line_s[0] = 0; im_line_s[1] = 0; im_line_s[2] = 0; im_line_s[3] = 0; for(int i = 0; i < 15; i++) im_line_s[i] = 0; bl_line_s[0] = 0; vb_line_s[0] = DAC_SYNC; bl_line_s[1] = 0; vb_line_s[1] = DAC_SYNC; bl_line_s[3] = 0; vb_line_s[3] = DAC_SYNC; bl_line_s[2] = 0; vb_line_s[2] = DAC_SYNC; } // video interrupt void isr() { uint8_t nop = 0, img = 0; //use nops or use wait_us uint8_t* sptr; //pointer to sync buffer for line uint8_t* vptr; //pointer to video buffer for line uint8_t* pptr; //porch if (l < V_PORCH_SIZE) { vptr = bl_line_v; sptr = im_line_s; nop = 1; } else if (l < YL + V_PORCH_SIZE) { vptr = im_line_va + (l - 30) * H_RES; sptr = im_line_s; nop = 1; img = 1; } else if (l < 254) { vptr = bl_line_v; sptr = bl_line_s; nop = 0; } else { vptr = vb_line_v; sptr = vb_line_s; nop = 1; } pptr = img ? bl_line_v : vptr; if (nop) { for (uint16_t i = 0; i < H_PORCH_SIZE; i++) { GPIOA->ODR = (pptr[i] + sptr[i]) << 4; asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop"); asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop"); } for (uint16_t i = 0; i < H_RES; i++) //loop over each column { GPIOA->ODR = (vptr[i] + sptr[i]) << 4; asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop"); asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop"); } } else { for(uint16_t i = 0; i < 12; i++) //loop over each column { GPIOA->ODR = sptr[i] << 4; asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop"); asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop"); asm("nop");asm("nop");asm("nop");asm("nop"); } } //move to next line l++; tics++; if(l > 255) l = 0; } // draw letter void draw_vincent(uint16_t x0, uint16_t y0, uint8_t c) { if(c == 40) c = 41; else if(c == 41) c = 40; char* letter = vincent_data[c]; for(uint16_t xp = 0; xp < 8; xp++) { for(uint16_t yp = 0; yp < 8; yp++) { im_line_va[H_RES*(yp+y0) + xp + x0] = CHECK_BIT(letter[yp],8-xp)?TEXT_LEVEL:0; } } } // draw string void draw_vincent_string(char* str) { for(int i = 0; i < strlen(str); i++) { if(str[i] == 0) return; char_col++; if(char_col >= TX) { char_col = 0; char_row++; } if(char_row >= TY) { char_row = 0; } draw_vincent(X0 +2 + 8*char_col, Y0 + 14 + 8*char_row, str[i]); } } void set_status_string(char* str) { uint8_t char_col_backup = char_col; uint8_t char_row_backup = char_row; char_col = 0; char_row = TY - 1; draw_vincent_string(str); char_col = char_col_backup; char_row = char_row_backup; } int main() { uint8_t *buf_swap_tmp; im_line_va = im_line_va_1; im_back = im_line_va_2; //init serial pc.baud(115200); pc.printf("derp!\r\n"); //init buffers init_buffers(); //init timer t.attach_us(&isr,64); /*init SD card, wait for card insertion*/ SDFileSystem sd(DI, DO, SCK, CS, "sd"); while (sd.disk_status()) { sd.disk_initialize(); wait(0.5); } FILE *fp; fp = fopen("/sd/man.worm.starwars", "rb"); uint32_t old_tics = tics; for(;;) { if (feof(fp)) rewind(fp); fread(current_frame, 1, VIDEO_FRAME_SIZE, fp); for(int x = 0; x < XL; x += 2) { for(int y = 0; y < YL; y++) { im_back[H_RES*(y+Y0) + x + X0] = current_frame[YL - y][x >> 1] >> 4; im_back[H_RES*(y+Y0) + x + 1 + X0] = current_frame[YL - y][x >> 1]; } } buf_swap_tmp = im_line_va; im_line_va = im_back; im_back = buf_swap_tmp; led_state = !led_state; user_led = led_state; char status_string[20]; sprintf(status_string, "%.1f", 15625.f / (float)(tics - old_tics)); old_tics = tics; set_status_string(status_string); } }