it works!
Dependencies: SDFileSystem2 mbed
Fork of manworm_tv_raster by
main.cpp@16:1f728d08b3a7, 2018-10-04 (annotated)
- 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?
User | Revision | Line number | New 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 |