it works!

Dependencies:   SDFileSystem2 mbed

Fork of manworm_tv_raster by Bayley Wang

Committer:
bwang
Date:
Sun Sep 30 18:03:58 2018 +0000
Revision:
14:5ee7843f2805
Parent:
13:9cf720873bf6
Child:
16:1f728d08b3a7
it works! slightly crunchy

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