it works!

Dependencies:   SDFileSystem2 mbed

Fork of manworm_tv_raster by Bayley Wang

Committer:
bwang
Date:
Thu Oct 04 12:37:25 2018 +0000
Revision:
16:1f728d08b3a7
Parent:
14:5ee7843f2805
improved timing

Who changed what in which revision?

UserRevisionLine numberNew contents of line
dicarloj 0:7757ab3f7206 1 #include "mbed.h"
dicarloj 0:7757ab3f7206 2 #include <math.h>
dicarloj 9:2a47b9ff8911 3 #include "main.h"
bwang 14:5ee7843f2805 4 #include "SDFileSystem.h"
dicarloj 9:2a47b9ff8911 5
dicarloj 12:e99cc1e9d928 6 #define TEXT_LEVEL 5
dicarloj 12:e99cc1e9d928 7
dicarloj 9:2a47b9ff8911 8 #define TX 24 // number of characters in X
bwang 14:5ee7843f2805 9 #define TY 10 // number of characters in Y
dicarloj 0:7757ab3f7206 10
dicarloj 9:2a47b9ff8911 11 #define CHECK_BIT(var,pos) ((var) & (1<<(pos)))
dicarloj 9:2a47b9ff8911 12 #define MIN(a,b) (((a)<(b))?(a):(b))
dicarloj 9:2a47b9ff8911 13 #define MAX(a,b) (((a)>(b))?(a):(b))
dicarloj 9:2a47b9ff8911 14
dicarloj 11:537cde55b27f 15
dicarloj 12:e99cc1e9d928 16 // DAC stuff
dicarloj 12:e99cc1e9d928 17 #define DAC_SYNC 2
dicarloj 12:e99cc1e9d928 18
dicarloj 9:2a47b9ff8911 19 uint8_t char_col = 0; // current column counter
dicarloj 9:2a47b9ff8911 20 uint8_t char_row = 0; // current row counter
dicarloj 9:2a47b9ff8911 21
dicarloj 9:2a47b9ff8911 22 Serial pc(USBTX, USBRX);
dicarloj 0:7757ab3f7206 23
bwang 13:9cf720873bf6 24 #include "vincent_data.h"
dicarloj 9:2a47b9ff8911 25
bwang 14:5ee7843f2805 26 //DigitalOut sout(D8); //sync PA_9
bwang 14:5ee7843f2805 27 //DigitalOut vout(D7); //video PA_8
dicarloj 9:2a47b9ff8911 28
dicarloj 12:e99cc1e9d928 29 DigitalOut dac0(PA_4);
dicarloj 12:e99cc1e9d928 30 DigitalOut dac1(PA_5);
dicarloj 12:e99cc1e9d928 31 DigitalOut dac2(PA_6);
dicarloj 12:e99cc1e9d928 32 DigitalOut dac3(PA_7);
dicarloj 12:e99cc1e9d928 33
bwang 14:5ee7843f2805 34 DigitalOut user_led(PB_14);
bwang 14:5ee7843f2805 35 int led_state = 1;
bwang 14:5ee7843f2805 36
dicarloj 9:2a47b9ff8911 37 // trigger horizontal line draw
dicarloj 0:7757ab3f7206 38 Ticker t;
dicarloj 9:2a47b9ff8911 39
dicarloj 9:2a47b9ff8911 40 uint8_t bl_line_s[H_RES]; //blank line sync buffer
dicarloj 9:2a47b9ff8911 41 uint8_t bl_line_v[H_RES]; //blank line video buffer
dicarloj 9:2a47b9ff8911 42 uint8_t vb_line_s[H_RES]; //vertical sync, sync buffer
dicarloj 9:2a47b9ff8911 43 uint8_t vb_line_v[H_RES]; //vertical sync, video buffer
dicarloj 9:2a47b9ff8911 44 uint8_t im_line_s[H_RES]; //image sync buffer
bwang 14:5ee7843f2805 45
bwang 14:5ee7843f2805 46 //buffers
bwang 14:5ee7843f2805 47 uint8_t current_frame[YL][XL / 2];
dicarloj 9:2a47b9ff8911 48 uint8_t im_line_va_1[H_RES*V_RES];
bwang 14:5ee7843f2805 49 uint8_t im_line_va_2[H_RES*V_RES];
bwang 14:5ee7843f2805 50
bwang 14:5ee7843f2805 51 //double buffered drawing
bwang 14:5ee7843f2805 52 uint8_t* im_line_va;
bwang 14:5ee7843f2805 53 uint8_t* im_back;
bwang 6:0a34891a82c7 54
dicarloj 0:7757ab3f7206 55 uint16_t l=0; //current line of scan
bwang 14:5ee7843f2805 56 uint32_t tics = 0; //timer
dicarloj 0:7757ab3f7206 57
dicarloj 9:2a47b9ff8911 58 // positive or negative?
dicarloj 9:2a47b9ff8911 59 int16_t sign(int16_t a)
bwang 6:0a34891a82c7 60 {
dicarloj 9:2a47b9ff8911 61 if(a > 0) return 1;
dicarloj 9:2a47b9ff8911 62 if(a < 0) return -1;
dicarloj 9:2a47b9ff8911 63 return 0;
dicarloj 0:7757ab3f7206 64 }
dicarloj 0:7757ab3f7206 65
dicarloj 9:2a47b9ff8911 66 // clear the screen and the text buffer
bwang 3:d9edc0575aa3 67 void clr()
bwang 3:d9edc0575aa3 68 {
bwang 3:d9edc0575aa3 69 for(int i = 0; i < H_RES; i++)
bwang 3:d9edc0575aa3 70 for(int j = 0; j < V_RES; j++)
bwang 14:5ee7843f2805 71 im_line_va[i+j*H_RES] = 0;
bwang 3:d9edc0575aa3 72 }
bwang 3:d9edc0575aa3 73
dicarloj 9:2a47b9ff8911 74 // initialize video buffers
dicarloj 0:7757ab3f7206 75 void init_buffers()
dicarloj 0:7757ab3f7206 76 {
dicarloj 9:2a47b9ff8911 77 clr(); // zero buffers
dicarloj 0:7757ab3f7206 78 for(int i = 0; i < H_RES; i++)
dicarloj 0:7757ab3f7206 79 {
dicarloj 12:e99cc1e9d928 80 im_line_s[i] = DAC_SYNC;
dicarloj 12:e99cc1e9d928 81 bl_line_s[i] = DAC_SYNC;
dicarloj 0:7757ab3f7206 82 bl_line_v[i] = 0;
dicarloj 0:7757ab3f7206 83 vb_line_s[i] = 0;
dicarloj 0:7757ab3f7206 84 vb_line_v[i] = 0;
dicarloj 0:7757ab3f7206 85 }
dicarloj 0:7757ab3f7206 86 im_line_s[0] = 0;
dicarloj 0:7757ab3f7206 87 im_line_s[1] = 0;
dicarloj 0:7757ab3f7206 88 im_line_s[2] = 0;
dicarloj 9:2a47b9ff8911 89 im_line_s[3] = 0;
dicarloj 9:2a47b9ff8911 90
bwang 13:9cf720873bf6 91 for(int i = 0; i < 15; i++) im_line_s[i] = 0;
dicarloj 9:2a47b9ff8911 92
dicarloj 0:7757ab3f7206 93 bl_line_s[0] = 0;
dicarloj 12:e99cc1e9d928 94 vb_line_s[0] = DAC_SYNC;
dicarloj 0:7757ab3f7206 95 bl_line_s[1] = 0;
dicarloj 12:e99cc1e9d928 96 vb_line_s[1] = DAC_SYNC;
dicarloj 0:7757ab3f7206 97
dicarloj 9:2a47b9ff8911 98 bl_line_s[3] = 0;
dicarloj 12:e99cc1e9d928 99 vb_line_s[3] = DAC_SYNC;
dicarloj 9:2a47b9ff8911 100 bl_line_s[2] = 0;
dicarloj 12:e99cc1e9d928 101 vb_line_s[2] = DAC_SYNC;
dicarloj 0:7757ab3f7206 102 }
dicarloj 9:2a47b9ff8911 103
dicarloj 9:2a47b9ff8911 104 // video interrupt
dicarloj 0:7757ab3f7206 105 void isr()
dicarloj 0:7757ab3f7206 106 {
bwang 14:5ee7843f2805 107 uint8_t nop = 0, img = 0; //use nops or use wait_us
dicarloj 0:7757ab3f7206 108 uint8_t* sptr; //pointer to sync buffer for line
dicarloj 0:7757ab3f7206 109 uint8_t* vptr; //pointer to video buffer for line
bwang 14:5ee7843f2805 110 uint8_t* pptr; //porch
bwang 14:5ee7843f2805 111
bwang 14:5ee7843f2805 112 if (l < V_PORCH_SIZE) {
bwang 14:5ee7843f2805 113 vptr = bl_line_v;
bwang 14:5ee7843f2805 114 sptr = im_line_s;
bwang 14:5ee7843f2805 115 nop = 1;
bwang 14:5ee7843f2805 116 }
bwang 14:5ee7843f2805 117 else if (l < YL + V_PORCH_SIZE) {
bwang 14:5ee7843f2805 118 vptr = im_line_va + (l - 30) * H_RES;
bwang 14:5ee7843f2805 119 sptr = im_line_s;
bwang 14:5ee7843f2805 120 nop = 1;
bwang 14:5ee7843f2805 121 img = 1;
bwang 14:5ee7843f2805 122 }
bwang 14:5ee7843f2805 123 else if (l < 254) {
bwang 14:5ee7843f2805 124 vptr = bl_line_v;
bwang 14:5ee7843f2805 125 sptr = bl_line_s;
bwang 14:5ee7843f2805 126 nop = 0;
bwang 14:5ee7843f2805 127 }
bwang 14:5ee7843f2805 128 else {
bwang 14:5ee7843f2805 129 vptr = vb_line_v;
bwang 14:5ee7843f2805 130 sptr = vb_line_s;
dicarloj 9:2a47b9ff8911 131 nop = 1;
bwang 14:5ee7843f2805 132 }
bwang 14:5ee7843f2805 133
bwang 14:5ee7843f2805 134 pptr = img ? bl_line_v : vptr;
bwang 14:5ee7843f2805 135
bwang 14:5ee7843f2805 136 if (nop) {
bwang 14:5ee7843f2805 137 for (uint16_t i = 0; i < H_PORCH_SIZE; i++) {
bwang 14:5ee7843f2805 138 GPIOA->ODR = (pptr[i] + sptr[i]) << 4;
bwang 14:5ee7843f2805 139
bwang 14:5ee7843f2805 140 asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");
bwang 14:5ee7843f2805 141 asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");
bwang 14:5ee7843f2805 142 }
bwang 14:5ee7843f2805 143
bwang 14:5ee7843f2805 144 for (uint16_t i = 0; i < H_RES; i++) //loop over each column
dicarloj 0:7757ab3f7206 145 {
bwang 14:5ee7843f2805 146 GPIOA->ODR = (vptr[i] + sptr[i]) << 4;
bwang 14:5ee7843f2805 147
bwang 14:5ee7843f2805 148 asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");
bwang 14:5ee7843f2805 149 asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");
dicarloj 0:7757ab3f7206 150 }
bwang 14:5ee7843f2805 151 } else {
bwang 14:5ee7843f2805 152 for(uint16_t i = 0; i < 12; i++) //loop over each column
bwang 14:5ee7843f2805 153 {
bwang 14:5ee7843f2805 154 GPIOA->ODR = sptr[i] << 4;
bwang 14:5ee7843f2805 155
bwang 14:5ee7843f2805 156 asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");
bwang 16:1f728d08b3a7 157 asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");
bwang 16:1f728d08b3a7 158 asm("nop");asm("nop");asm("nop");asm("nop");
bwang 14:5ee7843f2805 159 }
dicarloj 0:7757ab3f7206 160 }
bwang 14:5ee7843f2805 161
dicarloj 0:7757ab3f7206 162 //move to next line
dicarloj 0:7757ab3f7206 163 l++;
bwang 14:5ee7843f2805 164 tics++;
dicarloj 0:7757ab3f7206 165 if(l > 255) l = 0;
dicarloj 0:7757ab3f7206 166 }
dicarloj 0:7757ab3f7206 167
dicarloj 9:2a47b9ff8911 168 // draw letter
dicarloj 9:2a47b9ff8911 169 void draw_vincent(uint16_t x0, uint16_t y0, uint8_t c)
dicarloj 0:7757ab3f7206 170 {
dicarloj 9:2a47b9ff8911 171 if(c == 40) c = 41;
dicarloj 9:2a47b9ff8911 172 else if(c == 41) c = 40;
dicarloj 9:2a47b9ff8911 173 char* letter = vincent_data[c];
dicarloj 9:2a47b9ff8911 174 for(uint16_t xp = 0; xp < 8; xp++)
dicarloj 0:7757ab3f7206 175 {
dicarloj 9:2a47b9ff8911 176 for(uint16_t yp = 0; yp < 8; yp++)
dicarloj 0:7757ab3f7206 177 {
dicarloj 12:e99cc1e9d928 178 im_line_va[H_RES*(yp+y0) + xp + x0] = CHECK_BIT(letter[yp],8-xp)?TEXT_LEVEL:0;
dicarloj 0:7757ab3f7206 179 }
dicarloj 0:7757ab3f7206 180 }
dicarloj 0:7757ab3f7206 181 }
dicarloj 0:7757ab3f7206 182
dicarloj 9:2a47b9ff8911 183 // draw string
dicarloj 9:2a47b9ff8911 184 void draw_vincent_string(char* str)
dicarloj 9:2a47b9ff8911 185 {
dicarloj 9:2a47b9ff8911 186 for(int i = 0; i < strlen(str); i++)
dicarloj 9:2a47b9ff8911 187 {
bwang 13:9cf720873bf6 188 if(str[i] == 0) return;
dicarloj 9:2a47b9ff8911 189 char_col++;
dicarloj 9:2a47b9ff8911 190 if(char_col >= TX)
dicarloj 9:2a47b9ff8911 191 {
dicarloj 9:2a47b9ff8911 192 char_col = 0;
dicarloj 9:2a47b9ff8911 193 char_row++;
bwang 3:d9edc0575aa3 194 }
dicarloj 9:2a47b9ff8911 195 if(char_row >= TY)
dicarloj 9:2a47b9ff8911 196 {
dicarloj 9:2a47b9ff8911 197 char_row = 0;
dicarloj 9:2a47b9ff8911 198 }
bwang 3:d9edc0575aa3 199
dicarloj 9:2a47b9ff8911 200 draw_vincent(X0 +2 + 8*char_col, Y0 + 14 + 8*char_row,
dicarloj 9:2a47b9ff8911 201 str[i]);
bwang 3:d9edc0575aa3 202 }
bwang 3:d9edc0575aa3 203 }
bwang 3:d9edc0575aa3 204
dicarloj 9:2a47b9ff8911 205 void set_status_string(char* str)
dicarloj 9:2a47b9ff8911 206 {
dicarloj 9:2a47b9ff8911 207 uint8_t char_col_backup = char_col;
dicarloj 9:2a47b9ff8911 208 uint8_t char_row_backup = char_row;
dicarloj 9:2a47b9ff8911 209 char_col = 0;
dicarloj 9:2a47b9ff8911 210 char_row = TY - 1;
dicarloj 9:2a47b9ff8911 211
dicarloj 9:2a47b9ff8911 212 draw_vincent_string(str);
dicarloj 9:2a47b9ff8911 213
dicarloj 9:2a47b9ff8911 214 char_col = char_col_backup;
dicarloj 9:2a47b9ff8911 215 char_row = char_row_backup;
dicarloj 9:2a47b9ff8911 216 }
dicarloj 9:2a47b9ff8911 217
dicarloj 9:2a47b9ff8911 218 int main()
dicarloj 9:2a47b9ff8911 219 {
bwang 14:5ee7843f2805 220 uint8_t *buf_swap_tmp;
dicarloj 9:2a47b9ff8911 221 im_line_va = im_line_va_1;
bwang 14:5ee7843f2805 222 im_back = im_line_va_2;
bwang 14:5ee7843f2805 223
bwang 13:9cf720873bf6 224 //init serial
dicarloj 9:2a47b9ff8911 225 pc.baud(115200);
dicarloj 9:2a47b9ff8911 226 pc.printf("derp!\r\n");
dicarloj 9:2a47b9ff8911 227
bwang 13:9cf720873bf6 228 //init buffers
dicarloj 9:2a47b9ff8911 229 init_buffers();
bwang 13:9cf720873bf6 230 //init timer
dicarloj 9:2a47b9ff8911 231 t.attach_us(&isr,64);
bwang 14:5ee7843f2805 232
bwang 14:5ee7843f2805 233 /*init SD card, wait for card insertion*/
bwang 14:5ee7843f2805 234 SDFileSystem sd(DI, DO, SCK, CS, "sd");
bwang 14:5ee7843f2805 235 while (sd.disk_status()) {
bwang 14:5ee7843f2805 236 sd.disk_initialize();
bwang 14:5ee7843f2805 237 wait(0.5);
bwang 14:5ee7843f2805 238 }
bwang 14:5ee7843f2805 239
bwang 14:5ee7843f2805 240 FILE *fp;
bwang 4:02e3ae7a3aea 241
bwang 16:1f728d08b3a7 242 fp = fopen("/sd/man.worm.starwars", "rb");
bwang 14:5ee7843f2805 243
bwang 14:5ee7843f2805 244 uint32_t old_tics = tics;
bwang 14:5ee7843f2805 245 for(;;)
bwang 16:1f728d08b3a7 246 {
bwang 16:1f728d08b3a7 247 if (feof(fp)) rewind(fp);
bwang 14:5ee7843f2805 248 fread(current_frame, 1, VIDEO_FRAME_SIZE, fp);
bwang 14:5ee7843f2805 249 for(int x = 0; x < XL; x += 2)
dicarloj 12:e99cc1e9d928 250 {
bwang 14:5ee7843f2805 251 for(int y = 0; y < YL; y++)
dicarloj 12:e99cc1e9d928 252 {
bwang 14:5ee7843f2805 253 im_back[H_RES*(y+Y0) + x + X0] = current_frame[YL - y][x >> 1] >> 4;
bwang 14:5ee7843f2805 254 im_back[H_RES*(y+Y0) + x + 1 + X0] = current_frame[YL - y][x >> 1];
dicarloj 12:e99cc1e9d928 255 }
dicarloj 12:e99cc1e9d928 256 }
dicarloj 12:e99cc1e9d928 257
bwang 14:5ee7843f2805 258 buf_swap_tmp = im_line_va;
bwang 14:5ee7843f2805 259 im_line_va = im_back;
bwang 14:5ee7843f2805 260 im_back = buf_swap_tmp;
bwang 14:5ee7843f2805 261
bwang 14:5ee7843f2805 262 led_state = !led_state;
bwang 14:5ee7843f2805 263 user_led = led_state;
bwang 13:9cf720873bf6 264
bwang 14:5ee7843f2805 265 char status_string[20];
bwang 14:5ee7843f2805 266 sprintf(status_string, "%.1f", 15625.f / (float)(tics - old_tics));
bwang 14:5ee7843f2805 267 old_tics = tics;
bwang 16:1f728d08b3a7 268 set_status_string(status_string);
bwang 6:0a34891a82c7 269 }
bwang 6:0a34891a82c7 270 }
bwang 6:0a34891a82c7 271
dicarloj 9:2a47b9ff8911 272