├── CMakeLists.txt ├── dropping_monsters_usb ├── CMakeLists.txt ├── dropping_monsters_usb.c ├── dropping_monsters_usb.h ├── font8x8_basic.h ├── mini_gamepad.c ├── mini_gamepad.h ├── pico_ntsc_grph.c ├── pico_ntsc_grph.h ├── pico_sdk_import.cmake ├── pseudo_jp106.h └── tusb_config.h ├── font8x8_basic.h ├── host_hid.c ├── pico_ntsc_grph.c ├── pico_ntsc_grph.h ├── pico_sdk_import.cmake └── tusb_config.h /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.13) 2 | 3 | include(pico_sdk_import.cmake) 4 | 5 | project(test_project) 6 | 7 | pico_sdk_init() 8 | 9 | add_executable(host_hid 10 | host_hid.c pico_ntsc_grph.c 11 | ) 12 | 13 | target_include_directories(host_hid PRIVATE ${CMAKE_CURRENT_LIST_DIR}) 14 | target_link_libraries(host_hid PRIVATE pico_stdlib hardware_pwm tinyusb_host tinyusb_board) 15 | pico_add_extra_outputs(host_hid) 16 | 17 | # add url via pico_set_program_url 18 | #example_auto_set_url(host_hid) 19 | 20 | pico_enable_stdio_usb(host_hid 0) 21 | pico_enable_stdio_uart(host_hid 0) -------------------------------------------------------------------------------- /dropping_monsters_usb/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.13) 2 | 3 | include(pico_sdk_import.cmake) 4 | 5 | project(test_project) 6 | 7 | pico_sdk_init() 8 | 9 | add_executable(dropping_monsters_usb 10 | dropping_monsters_usb.c pico_ntsc_grph.c mini_gamepad.c 11 | ) 12 | 13 | target_include_directories(dropping_monsters_usb PRIVATE ${CMAKE_CURRENT_LIST_DIR}) 14 | # Pull in our (to be renamed) simple get you started dependencies 15 | target_link_libraries(dropping_monsters_usb PRIVATE pico_stdlib hardware_adc hardware_pwm tinyusb_host tinyusb_board) 16 | 17 | # create map/bin/hex file etc. 18 | pico_add_extra_outputs(dropping_monsters_usb) 19 | 20 | pico_enable_stdio_usb(dropping_monsters_usb 0) 21 | 22 | pico_enable_stdio_uart(dropping_monsters_usb 0) 23 | -------------------------------------------------------------------------------- /dropping_monsters_usb/dropping_monsters_usb.c: -------------------------------------------------------------------------------- 1 | /** 2 | * "DROPPING MONSTERS" game is implemented. 3 | * ATTENTION: You should compile this source with Release option of ARM compiler. 4 | * Mar.24, 2021 Pa@ART modified from test_ntsc_wall_grph.c 5 | */ 6 | 7 | #include 8 | #include 9 | #include "pico/stdlib.h" 10 | #include "hardware/irq.h" 11 | #include "hardware/pwm.h" 12 | #include "bsp/board.h" 13 | #include "pico_ntsc_grph.h" 14 | #include "mini_gamepad.h" 15 | #include "dropping_monsters_usb.h" 16 | #include "tusb_config.h" 17 | #include "pseudo_jp106.h" 18 | 19 | extern void hid_task(void); 20 | 21 | static bool state = true; 22 | static uint8_t map[VRAM_W][VRAM_H]; 23 | CFG_TUSB_MEM_SECTION static hid_keyboard_report_t usb_keyboard_report; 24 | uint8_t const keycode2ascii[128][2] = {HID_KEYCODE_PSEUDO_JP106_TO_ASCII}; 25 | 26 | 27 | #define UP 0x82 28 | #define DOWN 0x81 29 | #define LEFT 0x80 30 | #define RIGHT 0x8F 31 | 32 | // return key code 33 | uint8_t return_key_code( hid_keyboard_report_t const *p_new_report ) { 34 | bool const is_shift = 35 | p_new_report->modifier & (KEYBOARD_MODIFIER_LEFTSHIFT | KEYBOARD_MODIFIER_RIGHTSHIFT); 36 | uint8_t ch = keycode2ascii[p_new_report->keycode[0]][is_shift ? 1 : 0]; 37 | return ch; 38 | } 39 | 40 | void hid_task(void) { 41 | uint8_t const addr = 1; 42 | 43 | if (tuh_hid_keyboard_is_mounted(addr)) { 44 | if (!tuh_hid_keyboard_is_busy(addr)) { 45 | gvram_strings(GX(2), GY(0), "USB keyboard OK", WDOT); 46 | tuh_hid_keyboard_get_report(addr, &usb_keyboard_report); 47 | } 48 | } else { 49 | gvram_strings(GX(2), GY(0), " ", WDOT); 50 | } 51 | 52 | } 53 | 54 | // call back function when hid keyboard is mounted 55 | void tuh_hid_keyboard_mounted_cb(uint8_t dev_addr) { 56 | (void) dev_addr; 57 | } 58 | 59 | // call back function when hid keyboard is unmounted 60 | void tuh_hid_keyboard_unmounted_cb(uint8_t dev_addr) { 61 | (void) dev_addr; 62 | } 63 | 64 | // invoked ISR context 65 | void tuh_hid_keyboard_isr(uint8_t dev_addr, xfer_result_t event) { 66 | (void) dev_addr; 67 | (void) event; 68 | } 69 | 70 | // flip LED 71 | void flip_led( void ) { 72 | if (state == true) { 73 | LEDON; 74 | } else { 75 | LEDOFF; 76 | } 77 | state = !state; 78 | } 79 | 80 | // to clear VRAM contents (set to 0) 81 | void map_clear( void ) { 82 | for (int i = 0; i < VRAM_W; i++) { 83 | for (int j = 0; j < VRAM_H; j++) { 84 | map[i][j] = 0; 85 | } 86 | } 87 | } 88 | 89 | // to write a value into VRAM located at (x, y) 90 | void map_write ( int x, int y, unsigned char value ) { 91 | map[x][y] = value; 92 | } 93 | 94 | // initialize mouse array 95 | void init_mouse( entity *e ) { 96 | for (int i = 0; i < NMOUSE; i++) { 97 | e[i].x = -1; 98 | e[i].y = VRAM_H; 99 | e[i].c = CMOUSE; 100 | e[i].hp = 1; 101 | e[i].sp = 0; 102 | e[i].timer = 0; 103 | e[i].odd = false; 104 | } 105 | } 106 | 107 | void init_heart( entity *e ) { 108 | for (int i = 0; i < NHEART; i++) { 109 | e[i].x = -1; 110 | e[i].y = VRAM_H; 111 | e[i].c = CHEART; 112 | e[i].hp = 1; 113 | e[i].sp = 0; 114 | e[i].timer = 0; 115 | e[i].odd = false; 116 | } 117 | } 118 | // initialize me 119 | void init_me( entity *e ) { 120 | e->x = ME_X; 121 | e->y = ME_Y; 122 | e->c = CME; 123 | e->hp = ME_HP; 124 | e->sp = NORMALME; 125 | e->timer = 0; 126 | e->odd = true; 127 | } 128 | 129 | // draw one floor 130 | void draw_one_floor( int y ) { 131 | int count = 0; 132 | int xx, yy; 133 | // calculate yy 134 | yy = GY(y); 135 | // draw left and right end 136 | map_write(STARTW, y, CWALL); 137 | map_write(ENDW, y, CWALL); 138 | gvram_put_char(GX(STARTW), yy, CWALL, GDOT); 139 | gvram_put_char(GX(ENDW), yy, CWALL, GDOT); 140 | // draw wall and hole 141 | for (int x = STARTW + 1; x < ENDW; x++) { 142 | xx = GX(x); 143 | if ((rand() % 100) < 25) { 144 | map_write(x, y, ' '); 145 | gvram_put_char(xx, yy, ' ', GDOT); 146 | count++; 147 | } else { 148 | map_write(x, y, CWALL); 149 | gvram_put_char(xx, yy, CWALL, GDOT); 150 | } 151 | } 152 | // if there is no hole 153 | if (count == 0) { 154 | map_write(rand()%(ENDW - STARTW - 1) + STARTW + 1, y, ' '); 155 | gvram_put_char(GX(rand()%(ENDW - STARTW - 1) + STARTW + 1), GY(y), ' ', GDOT); 156 | } 157 | } 158 | 159 | // draw initial floors 160 | void init_floors( ) { 161 | int xx, yy; 162 | for (int y = LOXYGEN + 1; y <= ME_Y; y ++) { 163 | if (y % 2 == 0) { 164 | draw_one_floor(y); 165 | } else { 166 | yy = GY(y); 167 | map_write(STARTW, y, CWALL); 168 | map_write(ENDW, y, CWALL); 169 | gvram_put_char(GX(STARTW), yy, CWALL, GDOT); 170 | gvram_put_char(GX(ENDW), yy, CWALL, GDOT); 171 | } 172 | } 173 | for (int y = ME_Y + 1; y < VRAM_H; y++) { 174 | yy = GY(y); 175 | map_write(STARTW, y, CWALL); 176 | map_write(ENDW, y, CWALL); 177 | gvram_put_char(GX(STARTW), yy, CWALL, GDOT); 178 | gvram_put_char(GX(ENDW), yy, CWALL, GDOT); 179 | for (int x = STARTW + 1; x <= ENDW - 1; x++) { 180 | xx = GX(x); 181 | map_write(x, y, CGND); 182 | gvram_put_char(xx, yy, CGND, GDOT); 183 | } 184 | } 185 | } 186 | 187 | // move other entity 188 | void move_entity( entity *e, int max_num, int threshold ) { 189 | int i; 190 | // clear previous entity 191 | for (i = 0; i < max_num; i++) { 192 | if (e[i].y < VRAM_H) { 193 | map_write(e[i].x, e[i].y, ' '); 194 | gvram_put_char(GX(e[i].x), GY(e[i].y), ' ', WDOT); 195 | } 196 | } 197 | // move entity 198 | for (i = 0; i < max_num; i++) { 199 | // if the entity exists 200 | if (e[i].y < VRAM_H) { 201 | // if downward is empty 202 | if ((map[e[i].x][e[i].y + 1] != CWALL) && (map[e[i].x][e[i].y + 1] != CGND)) { 203 | e[i].y++; 204 | e[i].sp = 0; 205 | } else { 206 | // if rightward is a wall 207 | if (map[e[i].x + 1][e[i].y] == CWALL) { 208 | e[i].x--; 209 | e[i].sp = -1; 210 | // if leftward is a wall 211 | } else if (map[e[i].x - 1][e[i].y] == CWALL) { 212 | e[i].x++; 213 | e[i].sp = +1; 214 | // if rightward and leftward are both empty 215 | } else { 216 | if (e[i].sp == 0) { 217 | if ((rand() % 2) == 0) { 218 | e[i].x++; 219 | e[i].sp = +1; 220 | } else { 221 | e[i].x--; 222 | e[i].sp = -1; 223 | } 224 | } else { 225 | e[i].x += e[i].sp; 226 | } 227 | } 228 | } 229 | } 230 | } 231 | // generate new entity 232 | if (rand() % 100 < threshold) { 233 | // search disappeared entity position 234 | for (i = 0; i < max_num; i++) { 235 | if (e[i].y >= VRAM_H) break; 236 | } 237 | // if we can generate new entity 238 | if (i < max_num) { 239 | e[i].x = rand() % (ENDW - STARTW) + STARTW; 240 | e[i].y = LOXYGEN + 1; 241 | while (map[e[i].x][e[i].y] == CWALL) { 242 | e[i].x = rand() % (ENDW - STARTW) + STARTW; 243 | e[i].y = LOXYGEN + 1; 244 | } 245 | } 246 | } 247 | // draw present entity 248 | for (i = 0; i < max_num; i++) { 249 | // if the entity exists 250 | if (e[i].y < VRAM_H) { 251 | map_write(e[i].x, e[i].y, e[i].c); 252 | gvram_put_char(GX(e[i].x), GY(e[i].y), e[i].c, WDOT); 253 | } 254 | } 255 | } 256 | 257 | // scan keys and move me 258 | bool move_me( entity *me, entity *mouse, entity *heart, int floor ) { 259 | uint8_t keys; 260 | bool result = false; 261 | // clear previous me 262 | map_write(me->x, me->y, ' '); 263 | gvram_put_char(GX(me->x), GY(me->y), ' ', WDOT); 264 | // scan keys 265 | keys = return_key_code(&usb_keyboard_report); 266 | if (me->timer > 0) { 267 | me->timer--; 268 | if (me->timer <= 0) { 269 | me->sp = NORMALME; 270 | me->timer = 0; 271 | } 272 | } 273 | // move right 274 | if (keys == RIGHT) { 275 | if (me->x < ENDW - 1) { 276 | if (map[me->x + 1][me->y] != CWALL) { 277 | me->x++; 278 | } 279 | } 280 | } 281 | // move left 282 | if (keys == LEFT) { 283 | if (me->x > STARTW + 1) { 284 | if (map[me->x - 1][me->y] != CWALL) { 285 | me->x--; 286 | } 287 | } 288 | } 289 | // move up (move down floors) 290 | if (keys == UP) { 291 | // if I am in super mode 292 | if ((me->sp == SUPERME) && (me->timer > 0)) { 293 | map_write(me->x, me->y - 1, ' '); 294 | gvram_put_char(GX(me->x), GY(me->y - 1), ' ', WDOT); 295 | move_down_floors(mouse, heart, me->odd, floor); 296 | result = true; 297 | me->odd = !me->odd; 298 | } 299 | // if I am in normal mode 300 | if (map[me->x][me->y - 1] != CWALL) { 301 | move_down_floors(mouse, heart, me->odd, floor); 302 | result = true; 303 | me->odd = !me->odd; 304 | } 305 | } 306 | // draw present me 307 | map_write(me->x, me->y, me->c); 308 | gvram_put_char(GX(me->x), GY(me->y), me->c, WDOT); 309 | 310 | return result; 311 | } 312 | 313 | // move down floors 314 | void move_down_floors( entity *mouse, entity *heart, bool draw_floor, int floor ) { 315 | bool inner_draw_floor; 316 | // scroll down floors 317 | for (int y = VRAM_H - 2; y >= LOXYGEN + 1; y--) { 318 | for (int x = STARTW; x <= ENDW; x++) { 319 | map[x][y + 1] = map[x][y]; 320 | } 321 | } 322 | for (int y = LOXYGEN; y < VRAM_H; y++) { 323 | for (int x = STARTW; x <= ENDW; x++) { 324 | int c = map[x][y]; 325 | if (c == CWALL) { 326 | gvram_put_char(GX(x), GY(y), c, GDOT); 327 | } else { 328 | gvram_put_char(GX(x), GY(y), c, WDOT); 329 | } 330 | } 331 | } 332 | inner_draw_floor = draw_floor; 333 | // if near roof floor, not draw floor 334 | if (floor > MAXFLOOR - 8) { 335 | inner_draw_floor = false; 336 | } 337 | // if draw floor enabled (me.odd == true) 338 | if (inner_draw_floor == true) { 339 | draw_one_floor(LOXYGEN + 1); 340 | // if draw floor disabled (me.odd == false) 341 | } else { 342 | map_write(STARTW, LOXYGEN + 1, CWALL); 343 | gvram_put_char(GX(STARTW), GY(LOXYGEN + 1), CWALL, GDOT); 344 | for (int i = STARTW + 1; i <= ENDW - 1; i++) { 345 | map_write(i, LOXYGEN + 1, ' '); 346 | gvram_put_char(GX(i), GY(LOXYGEN + 1), ' ', GDOT); 347 | } 348 | map_write(ENDW, LOXYGEN + 1, CWALL); 349 | gvram_put_char(GX(ENDW), GY(LOXYGEN + 1), CWALL, GDOT); 350 | } 351 | // change mouse's position 352 | for (int i = 0; i < NMOUSE; i++) { 353 | if (mouse[i].y <= VRAM_H - 1) { 354 | mouse[i].y++; 355 | } 356 | } 357 | // change heart's position 358 | for (int i = 0; i < NHEART; i++) { 359 | if (heart[i].y <= VRAM_H - 1) { 360 | heart[i].y++; 361 | } 362 | } 363 | } 364 | 365 | // judge if I've got a heart or bumped into METEOR 366 | int judge_me( entity *me, entity *mouse, entity *heart) { 367 | int i; 368 | int bonus = 0; 369 | // heart 370 | for (i = 0; i < NHEART; i++) { 371 | // if I've got a heart 372 | if ((me->x == heart[i].x) && (me->y == heart[i].y)) { 373 | // normal me changed to super me 374 | me->sp = SUPERME; 375 | me->timer = rand() % MYTIMER + MYTIMER; 376 | // bonus point 377 | bonus = HEART_BONUS; 378 | // clear the heart 379 | map_write(heart[i].x, heart[i].y, ' '); 380 | gvram_put_char(GX(heart[i].x), GY(heart[i].y), ' ', WDOT); 381 | heart[i].y = VRAM_H; 382 | } 383 | } 384 | // mouse 385 | for (i = 0; i < NMOUSE; i++) { 386 | // if I've bumped with mouse 387 | if ((me->x == mouse[i].x) && (me->y == mouse[i].y)) { 388 | // power down my HP if I am in normal mode 389 | if (me->sp == NORMALME) { 390 | me->hp--; 391 | } 392 | // clear the mouse 393 | map_write(mouse[i].x, mouse[i].y, ' '); 394 | gvram_put_char(GX(mouse[i].x), GY(mouse[i].y), ' ', WDOT); 395 | mouse[i].y = VRAM_H; 396 | } 397 | } 398 | // return bonus score to be added 399 | return bonus; 400 | } 401 | 402 | int main() { 403 | // init stdio 404 | stdio_init_all(); 405 | // initialize video and LED GPIO 406 | init_video_and_led_GPIO(); 407 | // initialize key GPIO 408 | //init_key_GPIO(); 409 | // initialize board 410 | board_init(); 411 | // initialize USB 412 | tusb_init(); 413 | // clear VRAM 414 | vram_clear(); 415 | // initialize random seed 416 | init_random(); 417 | // initialize and start PWM interrupt by 64us period 418 | enable_PWM_interrupt( ); 419 | 420 | 421 | int countup = 0; 422 | int score = 0; 423 | int hi_score = 0; 424 | int mouse_rate = IMRATE; 425 | int p_mouse = IPMOUSE; 426 | int oxygen; 427 | int bonus; 428 | int floor = 0; 429 | int stages; 430 | int count_upstair = 0; 431 | int hp_up_score = HP_UP_SCORE; 432 | uint8_t keys; 433 | bool blink = true; 434 | bool initial; 435 | char mes[VRAM_W]; 436 | entity me, mouse[NMOUSE], heart[NHEART]; 437 | enum State {IDLE, PLAY, OVER, CLEAR} game_state; 438 | 439 | // initialize game state 440 | game_state = IDLE; 441 | 442 | while (1) { 443 | // monitoring process speed 444 | if (countup % 200000 == 0) { 445 | // flip LED 446 | flip_led(); 447 | } 448 | // read USB key status 449 | if (countup % MYRATE == 0) { 450 | // tinyusb host task 451 | tuh_task(); 452 | // HID task 453 | hid_task(); 454 | } 455 | // playing game 456 | if (game_state == PLAY) { 457 | // if needs initializing 458 | if (initial == true) { 459 | // initialize METEOR 460 | init_mouse(mouse); 461 | // initialize heart 462 | init_heart(heart); 463 | // if stage cleared 464 | if (floor >= MAXFLOOR) { 465 | score += bonus; 466 | stages++; 467 | me.odd = true; 468 | me.sp = NORMALME; 469 | me.timer = 0; 470 | // if game started 471 | } else { 472 | // clear score 473 | score = 0; 474 | // clear stages 475 | stages = 1; 476 | // initialize me 477 | init_me(&me); 478 | } 479 | // initialize oxygen 480 | oxygen = IOXGEN; 481 | // initialize bonus 482 | bonus = 0; 483 | // clear count upstair 484 | count_upstair = 0; 485 | // clear floor 486 | floor = 0; 487 | // clear map 488 | map_clear(); 489 | // clear graphical VRAM 490 | gvram_clear(); 491 | // initialize stage 492 | init_floors(); 493 | // clear initializing flag 494 | initial = false; 495 | } 496 | // oxygen turn 497 | if (countup % ORATE == 0) { 498 | oxygen--; 499 | } 500 | // my turn 501 | if (countup % MYRATE == 0) { 502 | // move me 503 | count_upstair += (move_me(&me, mouse, heart, floor) == true) ? 1 : 0; 504 | if (count_upstair >= 2) { 505 | count_upstair = 0; 506 | score += stages * BASE_SCORE; 507 | floor++; 508 | } 509 | // judge me (bump into mouse or get heart) 510 | score += judge_me(&me, mouse, heart) * stages; 511 | // if score is over hp_up_score 512 | if (score >= hp_up_score) { 513 | // HP++ 514 | me.hp++; 515 | // hp_up_score updates 516 | hp_up_score += HP_UP_SCORE; 517 | } 518 | // if HP is 0 519 | if ((me.hp <= 0) || (oxygen <= 0)) { 520 | // game state is game over 521 | game_state = OVER; 522 | } 523 | // if floor > MAXFLOOR 524 | if (floor >= MAXFLOOR) { 525 | // game state is clear stage 526 | game_state = CLEAR; 527 | } 528 | // display score, hi-score and HP 529 | sprintf(mes, " SCORE%6d HiSCORE%6d HP%2d", score, hi_score, me.hp); 530 | gvram_strings(0, LSCORE * CHAR_H, mes, WDOT); 531 | sprintf(mes, " OXYGEN%4d FLOOR%4d STAGE%3d", oxygen, MAXFLOOR - floor, stages); 532 | gvram_strings(0, LOXYGEN * CHAR_H, mes, WDOT); 533 | if (me.sp == SUPERME) { 534 | gvram_put_char(GX(34), GY(LOXYGEN), CHEART, WDOT); 535 | } else { 536 | gvram_put_char(GX(34), GY(LOXYGEN), ' ', WDOT); 537 | } 538 | } 539 | // mouse turn 540 | if (countup % mouse_rate == 0) { 541 | // move mouse 542 | move_entity(mouse, NMOUSE, p_mouse); 543 | // change mouse rate 544 | if (IMRATE - floor * 70 > MMRATE) { 545 | mouse_rate = IMRATE - floor * 70; 546 | } else { 547 | mouse_rate = MMRATE; 548 | } 549 | // change mouse probability 550 | p_mouse = IPMOUSE + floor / 6 + stages * 2; 551 | if (p_mouse >= 99) p_mouse = 99; 552 | } 553 | // heart turn 554 | if (countup % HTRATE == 0) { 555 | // move heart 556 | move_entity(heart, NHEART, PHEART); 557 | } 558 | } 559 | // clear, continue to play and add bonus score 560 | if (game_state == CLEAR) { 561 | if (countup % 200000 == 0) { 562 | int o_bonus, s_bonus; 563 | o_bonus = oxygen * BASE_SCORE * stages; 564 | s_bonus = stages * STAGE_BONUS; 565 | // stage clear title 566 | gvram_strings(GX(15), GY(10), "STAGE CLEAR!", WDOT); 567 | bonus = o_bonus + s_bonus; 568 | sprintf(mes, "OXYGEN BONUS: %4d", o_bonus); 569 | gvram_strings(GX(11), GY(12), mes, WDOT); 570 | sprintf(mes, "STAGE BONUS: %4d", s_bonus); 571 | gvram_strings(GX(11), GY(14), mes, WDOT); 572 | if (blink == true) { 573 | gvram_strings(GX(14), GY(18), "Push ENTER key ", WDOT); 574 | } else { 575 | gvram_strings(GX(14), GY(18), " ", WDOT); 576 | } 577 | blink = !blink; 578 | } 579 | if (countup % 200000) { 580 | // scan keys 581 | keys = return_key_code(&usb_keyboard_report); 582 | // if ENTER key is pushed 583 | if (keys == '\r') { 584 | // game state is 585 | game_state = PLAY; 586 | initial = true; 587 | } 588 | } 589 | } 590 | // idle, waiting for A button 591 | if (game_state == IDLE) { 592 | if (countup % 200000 == 0) { 593 | // game title 594 | gvram_strings(GX(15), GY(6), " DROPPING MONSTERS", WDOT); 595 | gvram_strings(GX(15), GY(8), " by Pa@ART 2021 ", WDOT); 596 | gvram_put_char(GX(15), GY(10), CME, WDOT); 597 | gvram_strings(GX(16), GY(10), ": YOU (SPACEMAN) ", WDOT); 598 | gvram_put_char(GX(15), GY(12), CMOUSE, WDOT); 599 | gvram_strings(GX(16), GY(12), ": MONSTER MOUSE ", WDOT); 600 | gvram_put_char(GX(15), GY(14), CHEART, WDOT); 601 | gvram_strings(GX(16), GY(14), ": POWER UP HEART ", WDOT); 602 | if (blink == true) { 603 | gvram_strings(GX(17), GY(18), "Push ENTER key ", WDOT); 604 | } else { 605 | gvram_strings(GX(17), GY(18), " ", WDOT); 606 | } 607 | blink = !blink; 608 | } 609 | if (countup % 200000 == 0) { 610 | // scan keys 611 | keys = return_key_code(&usb_keyboard_report); 612 | // if ENTER key is pushed 613 | if (keys == '\r') { 614 | // change game state to PLAY 615 | game_state = PLAY; 616 | // set initializing flag 617 | initial = true; 618 | } 619 | } 620 | } 621 | // game over, waiting for B button 622 | if (game_state == OVER) { 623 | if (countup % 200000 == 0) { 624 | // game over title 625 | gvram_strings(GX(15), GY(10), "GAME OVER!!", WDOT); 626 | // if oxygen has exhausted 627 | if (oxygen <= 0) { 628 | gvram_strings(GX(13), GY(12), "Oxygen exhausted!", WDOT); 629 | } 630 | // if score is higher than hi-score 631 | if (score > hi_score) { 632 | hi_score = score; 633 | gvram_strings(GX(15), GY(14), "Hi-Score!!", WDOT); 634 | } 635 | if (blink == true) { 636 | gvram_strings(GX(14), GY(18), "Push ENTER key ", WDOT); 637 | } else { 638 | gvram_strings(GX(14), GY(18), " ", WDOT); 639 | } 640 | blink = !blink; 641 | } 642 | if (countup % 200000) { 643 | // scan keys 644 | keys = return_key_code(&usb_keyboard_report); 645 | // if ENTER key is pushed 646 | if (keys == '\r') { 647 | // game state is IDLE 648 | game_state = IDLE; 649 | // clear map 650 | map_clear(); 651 | // clear graphical VRAM 652 | gvram_clear(); 653 | } 654 | } 655 | } 656 | countup++; 657 | } 658 | 659 | return 0; 660 | } 661 | -------------------------------------------------------------------------------- /dropping_monsters_usb/dropping_monsters_usb.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Header file for 3 | * "DROPPING MONSTERS" game is implemented. 4 | * ATTENTION: You should compile this source with Release option of ARM compiler. 5 | * Mar.24, 2021 Pa@ART modified from test_ntsc_wall_grph.c 6 | */ 7 | 8 | #ifndef __DROPPING_MONSTERS__ 9 | #define __DROPPING_MONSTERS__ 10 | 11 | #define CHAR_W 8 // character width 12 | #define CHAR_H 8 // character height 13 | #define CMOUSE 0xB // character of space mouse 14 | #define CHEART 0x8 // character of heart 15 | #define CME 0x7 // character of me 16 | #define CWALL 0x1 // character of wall 17 | #define CGND '*' // character of ground 18 | #define MAXFLOOR 150 // max floor number 19 | #define NMOUSE 25 // max number of mouse 20 | #define IMRATE 50000 // initial mouse rate 21 | #define MMRATE 10000 // minimum mouse rate 22 | #define IPMOUSE 10 // initial mouse probability 23 | #define NHEART 2 // max number of heart 24 | #define PHEART 5 // heart generation probability 25 | #define HTRATE 40000 // heart rate 26 | #define ORATE (MYRATE * 40) // oxygen rate 27 | #define IOXGEN 100 // initial oxygen 28 | #define MYRATE 30000 // my rate 29 | #define ME_X 10 // initial x of me 30 | #define ME_Y 17 // initial y of me 31 | #define ME_HP 5 // HP of me 32 | #define SUPERME 1 // superme mode flag 33 | #define NORMALME 0 // normalme mode flag 34 | #define MYTIMER 15 // superme mode timer value 35 | #define LSCORE 1 // line of score drawing 36 | #define LOXYGEN 2 // line of oxygen drawing 37 | #define STARTW 1 // start x of wall 38 | #define ENDW 36 // end x of wall 39 | #define HP_UP_SCORE 3000 // every HP_UP_SCORE, HP -> HP + 1 40 | #define HEART_BONUS 30 // bonus point for getting heart 41 | #define BASE_SCORE 10 // base score 42 | #define STAGE_BONUS 100 // base stage bonus 43 | 44 | #define GX(x) ((x) * CHAR_W) 45 | #define GY(y) ((y) * CHAR_H) 46 | 47 | typedef struct { 48 | int x; // x of entity 49 | int y; // y of entity 50 | int hp; // HP of entity 51 | char c; // character of entity 52 | int sp; // special power of entity 53 | int timer; // timer of entity 54 | bool odd; // true: draw new floor, false: draw empty floor 55 | } entity; 56 | 57 | #endif -------------------------------------------------------------------------------- /dropping_monsters_usb/font8x8_basic.h: -------------------------------------------------------------------------------- 1 | /** 2 | * 8x8 monochrome bitmap fonts for rendering 3 | * Author: Daniel Hepper 4 | * 5 | * License: Public Domain 6 | * 7 | * Based on: 8 | * // Summary: font8x8.h 9 | * // 8x8 monochrome bitmap fonts for rendering 10 | * // 11 | * // Author: 12 | * // Marcel Sondaar 13 | * // International Business Machines (public domain VGA fonts) 14 | * // 15 | * // License: 16 | * // Public Domain 17 | * 18 | * Fetched from: http://dimensionalrift.homelinux.net/combuster/mos3/?p=viewsource&file=/modules/gfx/font8_8.asm 19 | **/ 20 | /** 21 | * modified by Pa@ART on Feb.28, 2021 22 | * for NTSC signal generator 23 | **/ 24 | 25 | // Constant: font8x8_basic 26 | // Contains an 8x8 font map for unicode points U+0000 - U+007F (basic latin) 27 | #ifndef __FONT8x8_BASIC__ 28 | #define __FONT8x8_BASIC__ 29 | 30 | #define ASCII_CHAR_NUM 128 // numbers of ASCII characters 31 | #define CHAR_W 8 // width of character 32 | #define CHAR_H 8 // height of character 33 | 34 | volatile unsigned char ascii_table[ASCII_CHAR_NUM][CHAR_H] = { 35 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0000 (nul) 36 | { 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55}, // U+0001 hashed box 37 | { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, // U+0002 black box 38 | { 0xFF, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0xFF}, // U+0003 white box 39 | { 0x3C, 0x7E, 0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x3C}, // U+0004 fill ball 40 | { 0x88, 0x22, 0x44, 0x11, 0x88, 0x22, 0x44, 0x11}, // U+0005 dot back 41 | { 0x81, 0x99, 0xFF, 0x5A, 0x5A, 0x3C, 0x42, 0x81}, // U+0006 invader? 42 | { 0x1C, 0x1C, 0x08, 0x3E, 0x49, 0x08, 0x14, 0x22}, // U+0007 man 43 | { 0x66, 0xE7, 0xFF, 0xFF, 0xFF, 0x7E, 0x3C, 0x18}, // U+0008 heart mark 44 | { 0x0F, 0x1A, 0x24, 0xEC, 0xEC, 0x24, 0x1A, 0x0F}, // U+0009 star ship 45 | { 0x00, 0x60, 0x0E, 0xDD, 0x1F, 0x0E, 0xE0, 0x00}, // U+000A meteo 46 | { 0x42, 0xE7, 0x7E, 0x3C, 0x5A, 0x7E, 0x24, 0x18}, // U+000B m*cky mouse? 47 | { 0xCC, 0x33, 0xCC, 0x33, 0xCC, 0x33, 0xCC, 0x33}, // U+000C mosaic box 48 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000D 49 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000E 50 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000F 51 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0010 52 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0011 53 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0012 54 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0013 55 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0014 56 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0015 57 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0016 58 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0017 59 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0018 60 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0019 61 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001A 62 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001B 63 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001C 64 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001D 65 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001E 66 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001F 67 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0020 (space) 68 | { 0x18, 0x3C, 0x3C, 0x18, 0x18, 0x00, 0x18, 0x00}, // U+0021 (!) 69 | { 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0022 (") 70 | { 0x36, 0x36, 0x7F, 0x36, 0x7F, 0x36, 0x36, 0x00}, // U+0023 (#) 71 | { 0x0C, 0x3E, 0x03, 0x1E, 0x30, 0x1F, 0x0C, 0x00}, // U+0024 ($) 72 | { 0x00, 0x63, 0x33, 0x18, 0x0C, 0x66, 0x63, 0x00}, // U+0025 (%) 73 | { 0x1C, 0x36, 0x1C, 0x6E, 0x3B, 0x33, 0x6E, 0x00}, // U+0026 (&) 74 | { 0x06, 0x06, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0027 (') 75 | { 0x18, 0x0C, 0x06, 0x06, 0x06, 0x0C, 0x18, 0x00}, // U+0028 (() 76 | { 0x06, 0x0C, 0x18, 0x18, 0x18, 0x0C, 0x06, 0x00}, // U+0029 ()) 77 | { 0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00}, // U+002A (*) 78 | { 0x00, 0x0C, 0x0C, 0x3F, 0x0C, 0x0C, 0x00, 0x00}, // U+002B (+) 79 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x06}, // U+002C (,) 80 | { 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00}, // U+002D (-) 81 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x00}, // U+002E (.) 82 | { 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x00}, // U+002F (/) 83 | { 0x3E, 0x63, 0x73, 0x7B, 0x6F, 0x67, 0x3E, 0x00}, // U+0030 (0) 84 | { 0x0C, 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x3F, 0x00}, // U+0031 (1) 85 | { 0x1E, 0x33, 0x30, 0x1C, 0x06, 0x33, 0x3F, 0x00}, // U+0032 (2) 86 | { 0x1E, 0x33, 0x30, 0x1C, 0x30, 0x33, 0x1E, 0x00}, // U+0033 (3) 87 | { 0x38, 0x3C, 0x36, 0x33, 0x7F, 0x30, 0x78, 0x00}, // U+0034 (4) 88 | { 0x3F, 0x03, 0x1F, 0x30, 0x30, 0x33, 0x1E, 0x00}, // U+0035 (5) 89 | { 0x1C, 0x06, 0x03, 0x1F, 0x33, 0x33, 0x1E, 0x00}, // U+0036 (6) 90 | { 0x3F, 0x33, 0x30, 0x18, 0x0C, 0x0C, 0x0C, 0x00}, // U+0037 (7) 91 | { 0x1E, 0x33, 0x33, 0x1E, 0x33, 0x33, 0x1E, 0x00}, // U+0038 (8) 92 | { 0x1E, 0x33, 0x33, 0x3E, 0x30, 0x18, 0x0E, 0x00}, // U+0039 (9) 93 | { 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x00}, // U+003A (:) 94 | { 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x06}, // U+003B (;) 95 | { 0x18, 0x0C, 0x06, 0x03, 0x06, 0x0C, 0x18, 0x00}, // U+003C (<) 96 | { 0x00, 0x00, 0x3F, 0x00, 0x00, 0x3F, 0x00, 0x00}, // U+003D (=) 97 | { 0x06, 0x0C, 0x18, 0x30, 0x18, 0x0C, 0x06, 0x00}, // U+003E (>) 98 | { 0x1E, 0x33, 0x30, 0x18, 0x0C, 0x00, 0x0C, 0x00}, // U+003F (?) 99 | { 0x3E, 0x63, 0x7B, 0x7B, 0x7B, 0x03, 0x1E, 0x00}, // U+0040 (@) 100 | { 0x0C, 0x1E, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x00}, // U+0041 (A) 101 | { 0x3F, 0x66, 0x66, 0x3E, 0x66, 0x66, 0x3F, 0x00}, // U+0042 (B) 102 | { 0x3C, 0x66, 0x03, 0x03, 0x03, 0x66, 0x3C, 0x00}, // U+0043 (C) 103 | { 0x1F, 0x36, 0x66, 0x66, 0x66, 0x36, 0x1F, 0x00}, // U+0044 (D) 104 | { 0x7F, 0x46, 0x16, 0x1E, 0x16, 0x46, 0x7F, 0x00}, // U+0045 (E) 105 | { 0x7F, 0x46, 0x16, 0x1E, 0x16, 0x06, 0x0F, 0x00}, // U+0046 (F) 106 | { 0x3C, 0x66, 0x03, 0x03, 0x73, 0x66, 0x7C, 0x00}, // U+0047 (G) 107 | { 0x33, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x33, 0x00}, // U+0048 (H) 108 | { 0x1E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+0049 (I) 109 | { 0x78, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1E, 0x00}, // U+004A (J) 110 | { 0x67, 0x66, 0x36, 0x1E, 0x36, 0x66, 0x67, 0x00}, // U+004B (K) 111 | { 0x0F, 0x06, 0x06, 0x06, 0x46, 0x66, 0x7F, 0x00}, // U+004C (L) 112 | { 0x63, 0x77, 0x7F, 0x7F, 0x6B, 0x63, 0x63, 0x00}, // U+004D (M) 113 | { 0x63, 0x67, 0x6F, 0x7B, 0x73, 0x63, 0x63, 0x00}, // U+004E (N) 114 | { 0x1C, 0x36, 0x63, 0x63, 0x63, 0x36, 0x1C, 0x00}, // U+004F (O) 115 | { 0x3F, 0x66, 0x66, 0x3E, 0x06, 0x06, 0x0F, 0x00}, // U+0050 (P) 116 | { 0x1E, 0x33, 0x33, 0x33, 0x3B, 0x1E, 0x38, 0x00}, // U+0051 (Q) 117 | { 0x3F, 0x66, 0x66, 0x3E, 0x36, 0x66, 0x67, 0x00}, // U+0052 (R) 118 | { 0x1E, 0x33, 0x07, 0x0E, 0x38, 0x33, 0x1E, 0x00}, // U+0053 (S) 119 | { 0x3F, 0x2D, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+0054 (T) 120 | { 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x3F, 0x00}, // U+0055 (U) 121 | { 0x33, 0x33, 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x00}, // U+0056 (V) 122 | { 0x63, 0x63, 0x63, 0x6B, 0x7F, 0x77, 0x63, 0x00}, // U+0057 (W) 123 | { 0x63, 0x63, 0x36, 0x1C, 0x1C, 0x36, 0x63, 0x00}, // U+0058 (X) 124 | { 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x0C, 0x1E, 0x00}, // U+0059 (Y) 125 | { 0x7F, 0x63, 0x31, 0x18, 0x4C, 0x66, 0x7F, 0x00}, // U+005A (Z) 126 | { 0x1E, 0x06, 0x06, 0x06, 0x06, 0x06, 0x1E, 0x00}, // U+005B ([) 127 | { 0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x40, 0x00}, // U+005C (\) 128 | { 0x1E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1E, 0x00}, // U+005D (]) 129 | { 0x08, 0x1C, 0x36, 0x63, 0x00, 0x00, 0x00, 0x00}, // U+005E (^) 130 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF}, // U+005F (_) 131 | { 0x0C, 0x0C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0060 (`) 132 | { 0x00, 0x00, 0x1E, 0x30, 0x3E, 0x33, 0x6E, 0x00}, // U+0061 (a) 133 | { 0x07, 0x06, 0x06, 0x3E, 0x66, 0x66, 0x3B, 0x00}, // U+0062 (b) 134 | { 0x00, 0x00, 0x1E, 0x33, 0x03, 0x33, 0x1E, 0x00}, // U+0063 (c) 135 | { 0x38, 0x30, 0x30, 0x3e, 0x33, 0x33, 0x6E, 0x00}, // U+0064 (d) 136 | { 0x00, 0x00, 0x1E, 0x33, 0x3f, 0x03, 0x1E, 0x00}, // U+0065 (e) 137 | { 0x1C, 0x36, 0x06, 0x0f, 0x06, 0x06, 0x0F, 0x00}, // U+0066 (f) 138 | { 0x00, 0x00, 0x6E, 0x33, 0x33, 0x3E, 0x30, 0x1F}, // U+0067 (g) 139 | { 0x07, 0x06, 0x36, 0x6E, 0x66, 0x66, 0x67, 0x00}, // U+0068 (h) 140 | { 0x0C, 0x00, 0x0E, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+0069 (i) 141 | { 0x30, 0x00, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1E}, // U+006A (j) 142 | { 0x07, 0x06, 0x66, 0x36, 0x1E, 0x36, 0x67, 0x00}, // U+006B (k) 143 | { 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+006C (l) 144 | { 0x00, 0x00, 0x33, 0x7F, 0x7F, 0x6B, 0x63, 0x00}, // U+006D (m) 145 | { 0x00, 0x00, 0x1F, 0x33, 0x33, 0x33, 0x33, 0x00}, // U+006E (n) 146 | { 0x00, 0x00, 0x1E, 0x33, 0x33, 0x33, 0x1E, 0x00}, // U+006F (o) 147 | { 0x00, 0x00, 0x3B, 0x66, 0x66, 0x3E, 0x06, 0x0F}, // U+0070 (p) 148 | { 0x00, 0x00, 0x6E, 0x33, 0x33, 0x3E, 0x30, 0x78}, // U+0071 (q) 149 | { 0x00, 0x00, 0x3B, 0x6E, 0x66, 0x06, 0x0F, 0x00}, // U+0072 (r) 150 | { 0x00, 0x00, 0x3E, 0x03, 0x1E, 0x30, 0x1F, 0x00}, // U+0073 (s) 151 | { 0x08, 0x0C, 0x3E, 0x0C, 0x0C, 0x2C, 0x18, 0x00}, // U+0074 (t) 152 | { 0x00, 0x00, 0x33, 0x33, 0x33, 0x33, 0x6E, 0x00}, // U+0075 (u) 153 | { 0x00, 0x00, 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x00}, // U+0076 (v) 154 | { 0x00, 0x00, 0x63, 0x6B, 0x7F, 0x7F, 0x36, 0x00}, // U+0077 (w) 155 | { 0x00, 0x00, 0x63, 0x36, 0x1C, 0x36, 0x63, 0x00}, // U+0078 (x) 156 | { 0x00, 0x00, 0x33, 0x33, 0x33, 0x3E, 0x30, 0x1F}, // U+0079 (y) 157 | { 0x00, 0x00, 0x3F, 0x19, 0x0C, 0x26, 0x3F, 0x00}, // U+007A (z) 158 | { 0x38, 0x0C, 0x0C, 0x07, 0x0C, 0x0C, 0x38, 0x00}, // U+007B ({) 159 | { 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00}, // U+007C (|) 160 | { 0x07, 0x0C, 0x0C, 0x38, 0x0C, 0x0C, 0x07, 0x00}, // U+007D (}) 161 | { 0x6E, 0x3B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+007E (~) 162 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} // U+007F 163 | }; 164 | 165 | #endif -------------------------------------------------------------------------------- /dropping_monsters_usb/mini_gamepad.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Mini game pad driver 3 | * ATTENTION: You should compile this source with Release option of ARM compiler. 4 | * Mar.24, 2021 Pa@ART modified from test_ntsc_wall_grph.c 5 | */ 6 | 7 | 8 | #include 9 | #include 10 | #include "pico/stdlib.h" 11 | #include "hardware/adc.h" 12 | #include "mini_gamepad.h" 13 | 14 | // initialize Key GPIO setting 15 | void init_key_GPIO( ) { 16 | // GPIO init 17 | gpio_init(RKEYGP); 18 | gpio_init(UKEYGP); 19 | gpio_init(DKEYGP); 20 | gpio_init(LKEYGP); 21 | gpio_init(AKEYGP); 22 | gpio_init(BKEYGP); 23 | // GPIO direction 24 | gpio_set_dir(RKEYGP, GPIO_IN); 25 | gpio_set_dir(UKEYGP, GPIO_IN); 26 | gpio_set_dir(DKEYGP, GPIO_IN); 27 | gpio_set_dir(LKEYGP, GPIO_IN); 28 | gpio_set_dir(AKEYGP, GPIO_IN); 29 | gpio_set_dir(BKEYGP, GPIO_IN); 30 | // GPIO pullup 31 | gpio_pull_up(RKEYGP); 32 | gpio_pull_up(UKEYGP); 33 | gpio_pull_up(DKEYGP); 34 | gpio_pull_up(LKEYGP); 35 | gpio_pull_up(AKEYGP); 36 | gpio_pull_up(BKEYGP); 37 | } 38 | 39 | // scan keys 40 | uint32_t key_scan( ) { 41 | 42 | uint32_t result = 0x0; 43 | 44 | if (gpio_get(RKEYGP) == 0) result |= RKEY; 45 | if (gpio_get(UKEYGP) == 0) result |= UKEY; 46 | if (gpio_get(DKEYGP) == 0) result |= DKEY; 47 | if (gpio_get(LKEYGP) == 0) result |= LKEY; 48 | if (gpio_get(AKEYGP) == 0) result |= AKEY; 49 | if (gpio_get(BKEYGP) == 0) result |= BKEY; 50 | 51 | return result; 52 | } 53 | 54 | // initialize random seed by ADC data 55 | void init_random( ) { 56 | // init ADC 57 | adc_init(); 58 | // enable temperature sensor 59 | adc_set_temp_sensor_enabled(true); 60 | 61 | int seed_val = 0; 62 | for (int i = 0; i < 5; i++) { 63 | adc_select_input(i); 64 | seed_val += adc_read(); 65 | } 66 | srand(seed_val); 67 | } 68 | -------------------------------------------------------------------------------- /dropping_monsters_usb/mini_gamepad.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Header file for mini game pad driver 3 | * ATTENTION: You should compile this source with Release option of ARM compiler. 4 | * Mar.24, 2021 Pa@ART modified from test_ntsc_wall_grph.c 5 | */ 6 | 7 | 8 | #ifndef __MINI_GAMEPAD__ 9 | #define __MINI_GAMEPAD__ 10 | 11 | #include 12 | #include 13 | #include "pico/stdlib.h" 14 | #include "hardware/adc.h" 15 | 16 | #define RKEYGP 11 // Right key GP11 17 | #define UKEYGP 10 // Up key GP10 18 | #define DKEYGP 9 // Down key GP9 19 | #define LKEYGP 8 // Left key GP8 20 | #define AKEYGP 7 // A key GP7 21 | #define BKEYGP 6 // B key GP6 22 | #define RKEY (1 << RKEYGP) 23 | #define UKEY (1 << UKEYGP) 24 | #define LKEY (1 << LKEYGP) 25 | #define DKEY (1 << DKEYGP) 26 | #define AKEY (1 << AKEYGP) 27 | #define BKEY (1 << BKEYGP) 28 | 29 | // initialize Key GPIO setting 30 | void init_key_GPIO( ); 31 | // scan keys 32 | uint32_t key_scan( ); 33 | // initialize random seed by ADC data 34 | void init_random( ); 35 | 36 | #endif -------------------------------------------------------------------------------- /dropping_monsters_usb/pico_ntsc_grph.c: -------------------------------------------------------------------------------- 1 | /** 2 | * NTSC signal generation with PWM interrupt 3 | * ATTENTION: You should compile this source with Release option of ARM compiler. 4 | * Mar.24, 2021 Pa@ART modified from test_ntsc_wall_grph.c 5 | */ 6 | 7 | 8 | #include 9 | #include 10 | #include "pico/stdlib.h" 11 | #include "hardware/pwm.h" 12 | #include "font8x8_basic.h" 13 | #include "pico_ntsc_grph.h" 14 | 15 | static uint8_t gvram[GVRAM_W][GVRAM_H]; 16 | static uint8_t vram[VRAM_W][VRAM_H]; 17 | static int32_t count; 18 | 19 | // to clear VRAM contents (set to 0) 20 | void vram_clear( void ) { 21 | for (int i = 0; i < VRAM_W; i++) { 22 | for (int j = 0; j < VRAM_H; j++) { 23 | vram[i][j] = 0; 24 | } 25 | } 26 | } 27 | 28 | // to clear graphical VRAM contents (set to 0) 29 | void gvram_clear( void ) { 30 | for (int i = 0; i < GVRAM_W; i++) { 31 | for (int j = 0; j < GVRAM_H; j++) { 32 | gvram[i][j] = BDOT; 33 | } 34 | } 35 | } 36 | 37 | // to write a value into VRAM located at (x, y) 38 | void vram_write ( int x, int y, unsigned char value ) { 39 | vram[x][y] = value; 40 | } 41 | 42 | // to write a value into graphical VRAM located at (x, y) 43 | void gvram_write ( int x, int y, unsigned char value ) { 44 | gvram[x][y] = value; 45 | } 46 | 47 | // put a character on VRAM 48 | void gvram_put_char( int x, int y, char c, char col ) { 49 | unsigned char cp; 50 | for (int i = 0; i < CHAR_H; i++) { 51 | cp = ascii_table[c][i]; 52 | for (int j = 0; j < CHAR_W; j++) { 53 | if ((x + j < GVRAM_W) && (y + i < GVRAM_H)) { 54 | if ((cp & (1 << j)) != 0) { 55 | gvram[x + j][y + i] = col; 56 | } else { 57 | gvram[x + j][y + i] = BDOT; 58 | } 59 | } 60 | } 61 | } 62 | } 63 | 64 | // put strings on VRAM 65 | void gvram_strings( int x, int y, char *mes, char col ) { 66 | // if invalid (x, y), return 67 | if ((x < 0) || (x > GVRAM_W) || (y < 0) || (y > GVRAM_H)) { 68 | return; 69 | } 70 | int l = strlen(mes); 71 | for (int i = 0; i < l * CHAR_W; i += CHAR_W) { 72 | // if x position overflows, return 73 | if (x + i >= GVRAM_W) { 74 | return; 75 | // else put a character at the position 76 | } else { 77 | gvram_put_char(x + i, y, mes[i / CHAR_W], col); 78 | } 79 | } 80 | return; 81 | } 82 | 83 | // initialize video and LED GPIO 84 | void init_video_and_led_GPIO( ) { 85 | // initialize GPIO14 and GPIO15 for masked output 86 | gpio_init(GP14); 87 | gpio_init(GP15); 88 | gpio_init_mask(M14 | M15); 89 | gpio_set_dir(GP14, GPIO_OUT); 90 | gpio_set_dir(GP15, GPIO_OUT); 91 | // initialize LED GPIO 92 | gpio_init(LED); 93 | gpio_init_mask(MLED); 94 | gpio_set_dir(LED, GPIO_OUT); 95 | } 96 | 97 | // to generate horizontal sync siganl 98 | void hsync( void ) { 99 | SYNC; 100 | sleep_us(5); 101 | BLACK; 102 | sleep_us(7); 103 | } 104 | 105 | // to generate vertical sync siganl 106 | void vsync ( void ) { 107 | SYNC; 108 | sleep_us(10); 109 | sleep_us(5); 110 | sleep_us(10); 111 | BLACK; 112 | sleep_us(5); 113 | 114 | SYNC; 115 | sleep_us(10); 116 | sleep_us(5); 117 | sleep_us(10); 118 | BLACK; 119 | sleep_us(5); 120 | } 121 | 122 | // handler for holizontal line processing 123 | void horizontal_line( ) { 124 | // Clear the interrupt flag that brought us here 125 | pwm_clear_irq(pwm_gpio_to_slice_num(GPPWM)); 126 | 127 | // vertical synchronization duration 128 | if (count >= 3 && count <= 5) { 129 | vsync(); // vertical SYNC 130 | 131 | // VRAM drawing area 132 | } else if (count >= V_BASE && count < V_BASE + VRAM_H * CHAR_H) { 133 | hsync(); 134 | // left blank?? 135 | BLACK; 136 | sleep_us(0); // should be tuned 137 | 138 | int y = count - V_BASE; 139 | for (int x = 0; x < GVRAM_W; x++) { 140 | int c = gvram[x][y]; 141 | switch (c) { 142 | case BDOT: // black 143 | BLACK; 144 | break; 145 | case WDOT: // white 146 | WHITE; 147 | break; 148 | case GDOT: // gray 149 | GRAY; 150 | break; 151 | //case ZDOT: // dummy 152 | //break; 153 | default: 154 | BLACK; 155 | } 156 | } 157 | // right blank?? 158 | BLACK; 159 | sleep_us(0); 160 | } else { 161 | hsync(); 162 | BLACK; 163 | } 164 | // count up scan line 165 | count++; 166 | // if scan line reach to max 167 | if (count > 262) { 168 | count = 1; 169 | } 170 | return; 171 | } 172 | 173 | // initialize and start PWM interrupt by 64us period 174 | void enable_PWM_interrupt( ) { 175 | 176 | // GPPWM pin is the PWM output 177 | gpio_set_function(GPPWM, GPIO_FUNC_PWM); 178 | // Figure out which slice we just connected to the GPPWM pin 179 | uint slice_num = pwm_gpio_to_slice_num(GPPWM); 180 | 181 | // Mask our slice's IRQ output into the PWM block's single interrupt line, 182 | // and register our interrupt handler 183 | pwm_clear_irq(slice_num); 184 | pwm_set_irq_enabled(slice_num, true); 185 | irq_set_priority(PWM_IRQ_WRAP, 0xC0); // somehow this is needed if you compile with release option 186 | irq_set_exclusive_handler(PWM_IRQ_WRAP, horizontal_line); 187 | irq_set_enabled(PWM_IRQ_WRAP, true); 188 | 189 | // Set counter wrap value to generate PWM interrupt by this value 190 | pwm_set_wrap(slice_num, 7999); 191 | // Load the configuration into our PWM slice, and set it running. 192 | pwm_set_enabled(slice_num, true); 193 | } -------------------------------------------------------------------------------- /dropping_monsters_usb/pico_ntsc_grph.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Header file for NTSC signal generation with PWM interrupt 3 | * ATTENTION: You should compile this source with Release option of ARM compiler. 4 | * Mar.24, 2021 Pa@ART modified from test_ntsc_wall_grph.c 5 | */ 6 | 7 | 8 | #ifndef __PICO_NTSC_GRPH__ 9 | #define __PICO_NTSC_GRPH__ 10 | 11 | #include 12 | #include 13 | #include "pico/stdlib.h" 14 | #include "hardware/pwm.h" 15 | #include "hardware/irq.h" 16 | 17 | #define LED 25 // GPIO connected LED on the board 18 | #define MLED (1 << LED) 19 | #define LEDON gpio_put_masked(MLED, MLED) 20 | #define LEDOFF gpio_put_masked(MLED, 0) 21 | #define GPPWM 2 // GPIO2 is PWM output 22 | #define GP14 14 // GPIO14 connected to RCA+ pin via 330 ohm 23 | #define GP15 15 // GPIO15 connected to RCA+ pin via 1k ohm 24 | #define M14 (1 << GP14) // bit mask for GPIO14 25 | #define M15 (1 << GP15) // bit mask for GPIO15 26 | #define SYNC gpio_put_masked(M14 | M15, 0) // GPIO14='L' and GPIO15='L' 27 | #define WHITE gpio_put_masked(M14 | M15, M14 | M15) // GPIO14='H' and GPIO15='H' 28 | #define BLACK gpio_put_masked(M14 | M15, M15) // GPIO14='L' and GPIO15='H' 29 | #define GRAY gpio_put_masked(M14 | M15, M14) // GPIO14='H' and GPIO15='L' 30 | #define VRAM_W 40 // width size of VRAM 31 | #define VRAM_H 25 // height size of VRAM 32 | #define GVRAM_W (VRAM_W * CHAR_W) // width size of graphic VRAM 33 | #define GVRAM_H (VRAM_H * CHAR_H) // height size of graphic VRAM 34 | #define V_BASE 40 // horizontal line number to start displaying VRAM 35 | #define BDOT 0 // black dot 36 | #define WDOT 1 // white dot 37 | #define GDOT 2 // gray dot 38 | #define ZDOT 3 // dummy dot 39 | 40 | // to clear VRAM contents (set to 0) 41 | void vram_clear( ); 42 | // to clear graphical VRAM contents (set to 0) 43 | void gvram_clear( ); 44 | // to write a value into VRAM located at (x, y) 45 | void vram_write ( int x, int y, unsigned char value ); 46 | // to write a value into graphical VRAM located at (x, y) 47 | void gvram_write ( int x, int y, unsigned char value ); 48 | // put a character on VRAM 49 | void gvram_put_char( int x, int y, char c, char col ); 50 | // put strings on VRAM 51 | void gvram_strings( int x, int y, char *mes, char col ); 52 | // initialize video and LED GPIO 53 | void init_video_and_led_GPIO( ); 54 | // to generate horizontal sync siganl 55 | void hsync( ); 56 | // to generate vertical sync siganl 57 | void vsync ( ); 58 | // handler for holizontal line processing 59 | void horizontal_line( ); 60 | // initialize and start PWM interrupt by 64us period 61 | void enable_PWM_interrupt( ); 62 | 63 | #endif -------------------------------------------------------------------------------- /dropping_monsters_usb/pico_sdk_import.cmake: -------------------------------------------------------------------------------- 1 | # This is a copy of /external/pico_sdk_import.cmake 2 | 3 | # This can be dropped into an external project to help locate this SDK 4 | # It should be include()ed prior to project() 5 | 6 | if (DEFINED ENV{PICO_SDK_PATH} AND (NOT PICO_SDK_PATH)) 7 | set(PICO_SDK_PATH $ENV{PICO_SDK_PATH}) 8 | message("Using PICO_SDK_PATH from environment ('${PICO_SDK_PATH}')") 9 | endif () 10 | 11 | if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT} AND (NOT PICO_SDK_FETCH_FROM_GIT)) 12 | set(PICO_SDK_FETCH_FROM_GIT $ENV{PICO_SDK_FETCH_FROM_GIT}) 13 | message("Using PICO_SDK_FETCH_FROM_GIT from environment ('${PICO_SDK_FETCH_FROM_GIT}')") 14 | endif () 15 | 16 | if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT_PATH} AND (NOT PICO_SDK_FETCH_FROM_GIT_PATH)) 17 | set(PICO_SDK_FETCH_FROM_GIT_PATH $ENV{PICO_SDK_FETCH_FROM_GIT_PATH}) 18 | message("Using PICO_SDK_FETCH_FROM_GIT_PATH from environment ('${PICO_SDK_FETCH_FROM_GIT_PATH}')") 19 | endif () 20 | 21 | set(PICO_SDK_PATH "${PICO_SDK_PATH}" CACHE PATH "Path to the Raspberry Pi Pico SDK") 22 | set(PICO_SDK_FETCH_FROM_GIT "${PICO_SDK_FETCH_FROM_GIT}" CACHE BOOL "Set to ON to fetch copy of SDK from git if not otherwise locatable") 23 | set(PICO_SDK_FETCH_FROM_GIT_PATH "${PICO_SDK_FETCH_FROM_GIT_PATH}" CACHE FILEPATH "location to download SDK") 24 | 25 | if (NOT PICO_SDK_PATH) 26 | if (PICO_SDK_FETCH_FROM_GIT) 27 | include(FetchContent) 28 | set(FETCHCONTENT_BASE_DIR_SAVE ${FETCHCONTENT_BASE_DIR}) 29 | if (PICO_SDK_FETCH_FROM_GIT_PATH) 30 | get_filename_component(FETCHCONTENT_BASE_DIR "${PICO_SDK_FETCH_FROM_GIT_PATH}" REALPATH BASE_DIR "${CMAKE_SOURCE_DIR}") 31 | endif () 32 | FetchContent_Declare( 33 | pico_sdk 34 | GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk 35 | GIT_TAG master 36 | ) 37 | if (NOT pico_sdk) 38 | message("Downloading Raspberry Pi Pico SDK") 39 | FetchContent_Populate(pico_sdk) 40 | set(PICO_SDK_PATH ${pico_sdk_SOURCE_DIR}) 41 | endif () 42 | set(FETCHCONTENT_BASE_DIR ${FETCHCONTENT_BASE_DIR_SAVE}) 43 | else () 44 | message(FATAL_ERROR 45 | "SDK location was not specified. Please set PICO_SDK_PATH or set PICO_SDK_FETCH_FROM_GIT to on to fetch from git." 46 | ) 47 | endif () 48 | endif () 49 | 50 | get_filename_component(PICO_SDK_PATH "${PICO_SDK_PATH}" REALPATH BASE_DIR "${CMAKE_BINARY_DIR}") 51 | if (NOT EXISTS ${PICO_SDK_PATH}) 52 | message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' not found") 53 | endif () 54 | 55 | set(PICO_SDK_INIT_CMAKE_FILE ${PICO_SDK_PATH}/pico_sdk_init.cmake) 56 | if (NOT EXISTS ${PICO_SDK_INIT_CMAKE_FILE}) 57 | message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' does not appear to contain the Raspberry Pi Pico SDK") 58 | endif () 59 | 60 | set(PICO_SDK_PATH ${PICO_SDK_PATH} CACHE PATH "Path to the Raspberry Pi Pico SDK" FORCE) 61 | 62 | include(${PICO_SDK_INIT_CMAKE_FILE}) 63 | -------------------------------------------------------------------------------- /dropping_monsters_usb/pseudo_jp106.h: -------------------------------------------------------------------------------- 1 | #define HID_KEYCODE_PSEUDO_JP106_TO_ASCII \ 2 | {0 , 0 }, /* 0x00 */ \ 3 | {0 , 0 }, /* 0x01 */ \ 4 | {0 , 0 }, /* 0x02 */ \ 5 | {0 , 0 }, /* 0x03 */ \ 6 | {'a' , 'A' }, /* 0x04 */ \ 7 | {'b' , 'B' }, /* 0x05 */ \ 8 | {'c' , 'C' }, /* 0x06 */ \ 9 | {'d' , 'D' }, /* 0x07 */ \ 10 | {'e' , 'E' }, /* 0x08 */ \ 11 | {'f' , 'F' }, /* 0x09 */ \ 12 | {'g' , 'G' }, /* 0x0a */ \ 13 | {'h' , 'H' }, /* 0x0b */ \ 14 | {'i' , 'I' }, /* 0x0c */ \ 15 | {'j' , 'J' }, /* 0x0d */ \ 16 | {'k' , 'K' }, /* 0x0e */ \ 17 | {'l' , 'L' }, /* 0x0f */ \ 18 | {'m' , 'M' }, /* 0x10 */ \ 19 | {'n' , 'N' }, /* 0x11 */ \ 20 | {'o' , 'O' }, /* 0x12 */ \ 21 | {'p' , 'P' }, /* 0x13 */ \ 22 | {'q' , 'Q' }, /* 0x14 */ \ 23 | {'r' , 'R' }, /* 0x15 */ \ 24 | {'s' , 'S' }, /* 0x16 */ \ 25 | {'t' , 'T' }, /* 0x17 */ \ 26 | {'u' , 'U' }, /* 0x18 */ \ 27 | {'v' , 'V' }, /* 0x19 */ \ 28 | {'w' , 'W' }, /* 0x1a */ \ 29 | {'x' , 'X' }, /* 0x1b */ \ 30 | {'y' , 'Y' }, /* 0x1c */ \ 31 | {'z' , 'Z' }, /* 0x1d */ \ 32 | {'1' , '!' }, /* 0x1e */ \ 33 | {'2' , '\"' }, /* 0x1f */ \ 34 | {'3' , '#' }, /* 0x20 */ \ 35 | {'4' , '$' }, /* 0x21 */ \ 36 | {'5' , '%' }, /* 0x22 */ \ 37 | {'6' , '&' }, /* 0x23 */ \ 38 | {'7' , '\'' }, /* 0x24 */ \ 39 | {'8' , '(' }, /* 0x25 */ \ 40 | {'9' , ')' }, /* 0x26 */ \ 41 | {'0' , 0 }, /* 0x27 */ \ 42 | {'\r' , '\r' }, /* 0x28 */ \ 43 | {'\x1b', '\x1b' }, /* 0x29 */ \ 44 | {'\b' , '\b' }, /* 0x2a */ \ 45 | {'\t' , '\t' }, /* 0x2b */ \ 46 | {' ' , ' ' }, /* 0x2c */ \ 47 | {'-' , '=' }, /* 0x2d */ \ 48 | {'^' , '~' }, /* 0x2e */ \ 49 | {'@' , '`' }, /* 0x2f */ \ 50 | {'[' , '{' }, /* 0x30 */ \ 51 | {'\\' , '|' }, /* 0x31 */ \ 52 | {']' , '}' }, /* 0x32 */ \ 53 | {';' , '+' }, /* 0x33 */ \ 54 | {':' , '*' }, /* 0x34 */ \ 55 | {'\\' , '|' }, /* 0x35 */ \ 56 | {',' , '<' }, /* 0x36 */ \ 57 | {'.' , '>' }, /* 0x37 */ \ 58 | {'/' , '?' }, /* 0x38 */ \ 59 | \ 60 | {'_' , 0 }, /* 0x39 */ \ 61 | {0 , 0 }, /* 0x3a */ \ 62 | {0 , 0 }, /* 0x3b */ \ 63 | {0 , 0 }, /* 0x3c */ \ 64 | {0 , 0 }, /* 0x3d */ \ 65 | {0 , 0 }, /* 0x3e */ \ 66 | {0 , 0 }, /* 0x3f */ \ 67 | {0 , 0 }, /* 0x40 */ \ 68 | {0 , 0 }, /* 0x41 */ \ 69 | {0 , 0 }, /* 0x42 */ \ 70 | {0 , 0 }, /* 0x43 */ \ 71 | {0 , 0 }, /* 0x44 */ \ 72 | {0 , 0 }, /* 0x45 */ \ 73 | {0 , 0 }, /* 0x46 */ \ 74 | {0 , 0 }, /* 0x47 */ \ 75 | {0 , 0 }, /* 0x48 */ \ 76 | {0 , 0 }, /* 0x49 */ \ 77 | {0 , 0 }, /* 0x4a */ \ 78 | {0 , 0 }, /* 0x4b */ \ 79 | {0 , 0 }, /* 0x4c */ \ 80 | {0 , 0 }, /* 0x4d */ \ 81 | {0 , 0 }, /* 0x4e */ \ 82 | {0x8F , 0x8F }, /* 0x4f, right */ \ 83 | {0x80 , 0x80 }, /* 0x50, left */ \ 84 | {0x81 , 0x81 }, /* 0x51, down */ \ 85 | {0x82 , 0x82 }, /* 0x52, up */ \ 86 | {0 , 0 }, /* 0x53 */ \ 87 | \ 88 | {'/' , '/' }, /* 0x54 */ \ 89 | {'*' , '*' }, /* 0x55 */ \ 90 | {'-' , '-' }, /* 0x56 */ \ 91 | {'+' , '+' }, /* 0x57 */ \ 92 | {'\r' , '\r' }, /* 0x58 */ \ 93 | {'1' , 0 }, /* 0x59 */ \ 94 | {'2' , 0 }, /* 0x5a */ \ 95 | {'3' , 0 }, /* 0x5b */ \ 96 | {'4' , 0 }, /* 0x5c */ \ 97 | {'5' , '5' }, /* 0x5d */ \ 98 | {'6' , 0 }, /* 0x5e */ \ 99 | {'7' , 0 }, /* 0x5f */ \ 100 | {'8' , 0 }, /* 0x60 */ \ 101 | {'9' , 0 }, /* 0x61 */ \ 102 | {'0' , 0 }, /* 0x62 */ \ 103 | {'0' , 0 }, /* 0x63 */ \ 104 | {'=' , '=' }, /* 0x67 */ 105 | -------------------------------------------------------------------------------- /dropping_monsters_usb/tusb_config.h: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2019 Ha Thach (tinyusb.org) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | * 24 | */ 25 | 26 | #ifndef _TUSB_CONFIG_H_ 27 | #define _TUSB_CONFIG_H_ 28 | 29 | #ifdef __cplusplus 30 | extern "C" { 31 | #endif 32 | 33 | //-------------------------------------------------------------------- 34 | // COMMON CONFIGURATION 35 | //-------------------------------------------------------------------- 36 | 37 | // defined by compiler flags for flexibility 38 | #ifndef CFG_TUSB_MCU 39 | #error CFG_TUSB_MCU must be defined 40 | #endif 41 | 42 | #if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX 43 | #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_HOST | OPT_MODE_HIGH_SPEED) 44 | #else 45 | #define CFG_TUSB_RHPORT0_MODE OPT_MODE_HOST 46 | #endif 47 | 48 | #ifndef CFG_TUSB_MEM_SECTION 49 | #define CFG_TUSB_MEM_SECTION 50 | #endif 51 | 52 | #ifndef CFG_TUSB_MEM_ALIGN 53 | #define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) 54 | #endif 55 | 56 | //-------------------------------------------------------------------- 57 | // CONFIGURATION 58 | //-------------------------------------------------------------------- 59 | 60 | #define CFG_TUH_HUB 1 61 | #define CFG_TUH_HID_KEYBOARD 1 62 | #define CFG_TUH_HID_MOUSE 0 63 | #define CFG_TUSB_HOST_HID_GENERIC 0 // (not yet supported) 64 | #define CFG_TUH_MSC 0 65 | #define CFG_TUH_CDC 0 66 | 67 | #define CFG_TUSB_HOST_DEVICE_MAX (CFG_TUH_HUB ? 5 : 1) // normal hub has 4 ports 68 | 69 | #ifdef __cplusplus 70 | } 71 | #endif 72 | 73 | #endif /* _TUSB_CONFIG_H_ */ 74 | -------------------------------------------------------------------------------- /font8x8_basic.h: -------------------------------------------------------------------------------- 1 | /** 2 | * 8x8 monochrome bitmap fonts for rendering 3 | * Author: Daniel Hepper 4 | * 5 | * License: Public Domain 6 | * 7 | * Based on: 8 | * // Summary: font8x8.h 9 | * // 8x8 monochrome bitmap fonts for rendering 10 | * // 11 | * // Author: 12 | * // Marcel Sondaar 13 | * // International Business Machines (public domain VGA fonts) 14 | * // 15 | * // License: 16 | * // Public Domain 17 | * 18 | * Fetched from: http://dimensionalrift.homelinux.net/combuster/mos3/?p=viewsource&file=/modules/gfx/font8_8.asm 19 | **/ 20 | /** 21 | * modified by Pa@ART on Feb.28, 2021 22 | * for NTSC signal generator 23 | **/ 24 | 25 | // Constant: font8x8_basic 26 | // Contains an 8x8 font map for unicode points U+0000 - U+007F (basic latin) 27 | #ifndef __FONT8x8_BASIC__ 28 | #define __FONT8x8_BASIC__ 29 | 30 | #define ASCII_CHAR_NUM 128 // numbers of ASCII characters 31 | #define CHAR_W 8 // width of character 32 | #define CHAR_H 8 // height of character 33 | 34 | volatile unsigned char ascii_table[ASCII_CHAR_NUM][CHAR_H] = { 35 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0000 (nul) 36 | { 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55}, // U+0001 hashed box 37 | { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, // U+0002 black box 38 | { 0xFF, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0xFF}, // U+0003 white box 39 | { 0x3C, 0x7E, 0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x3C}, // U+0004 fill ball 40 | { 0x88, 0x22, 0x44, 0x11, 0x88, 0x22, 0x44, 0x11}, // U+0005 dot back 41 | { 0x81, 0x99, 0xFF, 0x5A, 0x5A, 0x3C, 0x42, 0x81}, // U+0006 invader? 42 | { 0x1C, 0x1C, 0x08, 0x3E, 0x49, 0x08, 0x14, 0x22}, // U+0007 man 43 | { 0x66, 0xE7, 0xFF, 0xFF, 0xFF, 0x7E, 0x3C, 0x18}, // U+0008 heart mark 44 | { 0x0F, 0x1A, 0x24, 0xEC, 0xEC, 0x24, 0x1A, 0x0F}, // U+0009 star ship 45 | { 0x00, 0x60, 0x0E, 0xDD, 0x1F, 0x0E, 0xE0, 0x00}, // U+000A meteo 46 | { 0x42, 0xE7, 0x7E, 0x3C, 0x5A, 0x7E, 0x24, 0x18}, // U+000B m*cky mouse? 47 | { 0xCC, 0x33, 0xCC, 0x33, 0xCC, 0x33, 0xCC, 0x33}, // U+000C mosaic box 48 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000D 49 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000E 50 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000F 51 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0010 52 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0011 53 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0012 54 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0013 55 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0014 56 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0015 57 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0016 58 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0017 59 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0018 60 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0019 61 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001A 62 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001B 63 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001C 64 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001D 65 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001E 66 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001F 67 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0020 (space) 68 | { 0x18, 0x3C, 0x3C, 0x18, 0x18, 0x00, 0x18, 0x00}, // U+0021 (!) 69 | { 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0022 (") 70 | { 0x36, 0x36, 0x7F, 0x36, 0x7F, 0x36, 0x36, 0x00}, // U+0023 (#) 71 | { 0x0C, 0x3E, 0x03, 0x1E, 0x30, 0x1F, 0x0C, 0x00}, // U+0024 ($) 72 | { 0x00, 0x63, 0x33, 0x18, 0x0C, 0x66, 0x63, 0x00}, // U+0025 (%) 73 | { 0x1C, 0x36, 0x1C, 0x6E, 0x3B, 0x33, 0x6E, 0x00}, // U+0026 (&) 74 | { 0x06, 0x06, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0027 (') 75 | { 0x18, 0x0C, 0x06, 0x06, 0x06, 0x0C, 0x18, 0x00}, // U+0028 (() 76 | { 0x06, 0x0C, 0x18, 0x18, 0x18, 0x0C, 0x06, 0x00}, // U+0029 ()) 77 | { 0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00}, // U+002A (*) 78 | { 0x00, 0x0C, 0x0C, 0x3F, 0x0C, 0x0C, 0x00, 0x00}, // U+002B (+) 79 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x06}, // U+002C (,) 80 | { 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00}, // U+002D (-) 81 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x00}, // U+002E (.) 82 | { 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x00}, // U+002F (/) 83 | { 0x3E, 0x63, 0x73, 0x7B, 0x6F, 0x67, 0x3E, 0x00}, // U+0030 (0) 84 | { 0x0C, 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x3F, 0x00}, // U+0031 (1) 85 | { 0x1E, 0x33, 0x30, 0x1C, 0x06, 0x33, 0x3F, 0x00}, // U+0032 (2) 86 | { 0x1E, 0x33, 0x30, 0x1C, 0x30, 0x33, 0x1E, 0x00}, // U+0033 (3) 87 | { 0x38, 0x3C, 0x36, 0x33, 0x7F, 0x30, 0x78, 0x00}, // U+0034 (4) 88 | { 0x3F, 0x03, 0x1F, 0x30, 0x30, 0x33, 0x1E, 0x00}, // U+0035 (5) 89 | { 0x1C, 0x06, 0x03, 0x1F, 0x33, 0x33, 0x1E, 0x00}, // U+0036 (6) 90 | { 0x3F, 0x33, 0x30, 0x18, 0x0C, 0x0C, 0x0C, 0x00}, // U+0037 (7) 91 | { 0x1E, 0x33, 0x33, 0x1E, 0x33, 0x33, 0x1E, 0x00}, // U+0038 (8) 92 | { 0x1E, 0x33, 0x33, 0x3E, 0x30, 0x18, 0x0E, 0x00}, // U+0039 (9) 93 | { 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x00}, // U+003A (:) 94 | { 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x06}, // U+003B (;) 95 | { 0x18, 0x0C, 0x06, 0x03, 0x06, 0x0C, 0x18, 0x00}, // U+003C (<) 96 | { 0x00, 0x00, 0x3F, 0x00, 0x00, 0x3F, 0x00, 0x00}, // U+003D (=) 97 | { 0x06, 0x0C, 0x18, 0x30, 0x18, 0x0C, 0x06, 0x00}, // U+003E (>) 98 | { 0x1E, 0x33, 0x30, 0x18, 0x0C, 0x00, 0x0C, 0x00}, // U+003F (?) 99 | { 0x3E, 0x63, 0x7B, 0x7B, 0x7B, 0x03, 0x1E, 0x00}, // U+0040 (@) 100 | { 0x0C, 0x1E, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x00}, // U+0041 (A) 101 | { 0x3F, 0x66, 0x66, 0x3E, 0x66, 0x66, 0x3F, 0x00}, // U+0042 (B) 102 | { 0x3C, 0x66, 0x03, 0x03, 0x03, 0x66, 0x3C, 0x00}, // U+0043 (C) 103 | { 0x1F, 0x36, 0x66, 0x66, 0x66, 0x36, 0x1F, 0x00}, // U+0044 (D) 104 | { 0x7F, 0x46, 0x16, 0x1E, 0x16, 0x46, 0x7F, 0x00}, // U+0045 (E) 105 | { 0x7F, 0x46, 0x16, 0x1E, 0x16, 0x06, 0x0F, 0x00}, // U+0046 (F) 106 | { 0x3C, 0x66, 0x03, 0x03, 0x73, 0x66, 0x7C, 0x00}, // U+0047 (G) 107 | { 0x33, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x33, 0x00}, // U+0048 (H) 108 | { 0x1E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+0049 (I) 109 | { 0x78, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1E, 0x00}, // U+004A (J) 110 | { 0x67, 0x66, 0x36, 0x1E, 0x36, 0x66, 0x67, 0x00}, // U+004B (K) 111 | { 0x0F, 0x06, 0x06, 0x06, 0x46, 0x66, 0x7F, 0x00}, // U+004C (L) 112 | { 0x63, 0x77, 0x7F, 0x7F, 0x6B, 0x63, 0x63, 0x00}, // U+004D (M) 113 | { 0x63, 0x67, 0x6F, 0x7B, 0x73, 0x63, 0x63, 0x00}, // U+004E (N) 114 | { 0x1C, 0x36, 0x63, 0x63, 0x63, 0x36, 0x1C, 0x00}, // U+004F (O) 115 | { 0x3F, 0x66, 0x66, 0x3E, 0x06, 0x06, 0x0F, 0x00}, // U+0050 (P) 116 | { 0x1E, 0x33, 0x33, 0x33, 0x3B, 0x1E, 0x38, 0x00}, // U+0051 (Q) 117 | { 0x3F, 0x66, 0x66, 0x3E, 0x36, 0x66, 0x67, 0x00}, // U+0052 (R) 118 | { 0x1E, 0x33, 0x07, 0x0E, 0x38, 0x33, 0x1E, 0x00}, // U+0053 (S) 119 | { 0x3F, 0x2D, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+0054 (T) 120 | { 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x3F, 0x00}, // U+0055 (U) 121 | { 0x33, 0x33, 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x00}, // U+0056 (V) 122 | { 0x63, 0x63, 0x63, 0x6B, 0x7F, 0x77, 0x63, 0x00}, // U+0057 (W) 123 | { 0x63, 0x63, 0x36, 0x1C, 0x1C, 0x36, 0x63, 0x00}, // U+0058 (X) 124 | { 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x0C, 0x1E, 0x00}, // U+0059 (Y) 125 | { 0x7F, 0x63, 0x31, 0x18, 0x4C, 0x66, 0x7F, 0x00}, // U+005A (Z) 126 | { 0x1E, 0x06, 0x06, 0x06, 0x06, 0x06, 0x1E, 0x00}, // U+005B ([) 127 | { 0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x40, 0x00}, // U+005C (\) 128 | { 0x1E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1E, 0x00}, // U+005D (]) 129 | { 0x08, 0x1C, 0x36, 0x63, 0x00, 0x00, 0x00, 0x00}, // U+005E (^) 130 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF}, // U+005F (_) 131 | { 0x0C, 0x0C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0060 (`) 132 | { 0x00, 0x00, 0x1E, 0x30, 0x3E, 0x33, 0x6E, 0x00}, // U+0061 (a) 133 | { 0x07, 0x06, 0x06, 0x3E, 0x66, 0x66, 0x3B, 0x00}, // U+0062 (b) 134 | { 0x00, 0x00, 0x1E, 0x33, 0x03, 0x33, 0x1E, 0x00}, // U+0063 (c) 135 | { 0x38, 0x30, 0x30, 0x3e, 0x33, 0x33, 0x6E, 0x00}, // U+0064 (d) 136 | { 0x00, 0x00, 0x1E, 0x33, 0x3f, 0x03, 0x1E, 0x00}, // U+0065 (e) 137 | { 0x1C, 0x36, 0x06, 0x0f, 0x06, 0x06, 0x0F, 0x00}, // U+0066 (f) 138 | { 0x00, 0x00, 0x6E, 0x33, 0x33, 0x3E, 0x30, 0x1F}, // U+0067 (g) 139 | { 0x07, 0x06, 0x36, 0x6E, 0x66, 0x66, 0x67, 0x00}, // U+0068 (h) 140 | { 0x0C, 0x00, 0x0E, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+0069 (i) 141 | { 0x30, 0x00, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1E}, // U+006A (j) 142 | { 0x07, 0x06, 0x66, 0x36, 0x1E, 0x36, 0x67, 0x00}, // U+006B (k) 143 | { 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+006C (l) 144 | { 0x00, 0x00, 0x33, 0x7F, 0x7F, 0x6B, 0x63, 0x00}, // U+006D (m) 145 | { 0x00, 0x00, 0x1F, 0x33, 0x33, 0x33, 0x33, 0x00}, // U+006E (n) 146 | { 0x00, 0x00, 0x1E, 0x33, 0x33, 0x33, 0x1E, 0x00}, // U+006F (o) 147 | { 0x00, 0x00, 0x3B, 0x66, 0x66, 0x3E, 0x06, 0x0F}, // U+0070 (p) 148 | { 0x00, 0x00, 0x6E, 0x33, 0x33, 0x3E, 0x30, 0x78}, // U+0071 (q) 149 | { 0x00, 0x00, 0x3B, 0x6E, 0x66, 0x06, 0x0F, 0x00}, // U+0072 (r) 150 | { 0x00, 0x00, 0x3E, 0x03, 0x1E, 0x30, 0x1F, 0x00}, // U+0073 (s) 151 | { 0x08, 0x0C, 0x3E, 0x0C, 0x0C, 0x2C, 0x18, 0x00}, // U+0074 (t) 152 | { 0x00, 0x00, 0x33, 0x33, 0x33, 0x33, 0x6E, 0x00}, // U+0075 (u) 153 | { 0x00, 0x00, 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x00}, // U+0076 (v) 154 | { 0x00, 0x00, 0x63, 0x6B, 0x7F, 0x7F, 0x36, 0x00}, // U+0077 (w) 155 | { 0x00, 0x00, 0x63, 0x36, 0x1C, 0x36, 0x63, 0x00}, // U+0078 (x) 156 | { 0x00, 0x00, 0x33, 0x33, 0x33, 0x3E, 0x30, 0x1F}, // U+0079 (y) 157 | { 0x00, 0x00, 0x3F, 0x19, 0x0C, 0x26, 0x3F, 0x00}, // U+007A (z) 158 | { 0x38, 0x0C, 0x0C, 0x07, 0x0C, 0x0C, 0x38, 0x00}, // U+007B ({) 159 | { 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00}, // U+007C (|) 160 | { 0x07, 0x0C, 0x0C, 0x38, 0x0C, 0x0C, 0x07, 0x00}, // U+007D (}) 161 | { 0x6E, 0x3B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+007E (~) 162 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} // U+007F 163 | }; 164 | 165 | #endif -------------------------------------------------------------------------------- /host_hid.c: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2019 Ha Thach (tinyusb.org) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | * 24 | */ 25 | 26 | #include 27 | #include 28 | #include 29 | 30 | #include "hardware/irq.h" 31 | #include "hardware/pwm.h" 32 | #include "pico/stdlib.h" 33 | #include "bsp/board.h" 34 | #include "pico_ntsc_grph.h" 35 | #include "tusb.h" 36 | 37 | void print_greeting(void); 38 | void led_blinking_task(void); 39 | extern void hid_task(void); 40 | 41 | #define GX(x) (x * 8) 42 | #define GY(y) (y * 8) 43 | 44 | int cx = 0; 45 | int cy = 4; 46 | 47 | int main(void) { 48 | 49 | // initialize video and LED GPIO 50 | init_video_and_led_GPIO(); 51 | // init stdio 52 | stdio_init_all(); 53 | // initialize and start PWM interrupt by 64us period 54 | enable_PWM_interrupt( ); 55 | gvram_clear(); 56 | gvram_strings(0, 0, "Hello!", WDOT); 57 | 58 | board_init(); 59 | print_greeting(); 60 | 61 | // return 0; 62 | 63 | tusb_init(); 64 | 65 | while (1) { 66 | // tinyusb host task 67 | tuh_task(); 68 | led_blinking_task(); 69 | 70 | #if CFG_TUH_HID_KEYBOARD || CFG_TUH_HID_MOUSE 71 | hid_task(); 72 | #endif 73 | } 74 | 75 | return 0; 76 | } 77 | 78 | //--------------------------------------------------------------------+ 79 | // USB HID 80 | //--------------------------------------------------------------------+ 81 | #if CFG_TUH_HID_KEYBOARD 82 | 83 | CFG_TUSB_MEM_SECTION static hid_keyboard_report_t usb_keyboard_report; 84 | uint8_t const keycode2ascii[128][2] = {HID_KEYCODE_TO_ASCII}; 85 | 86 | // look up new key in previous keys 87 | static inline bool find_key_in_report(hid_keyboard_report_t const *p_report, uint8_t keycode) { 88 | for (uint8_t i = 0; i < 6; i++) { 89 | if (p_report->keycode[i] == keycode) return true; 90 | } 91 | 92 | return false; 93 | } 94 | 95 | static inline void process_kbd_report(hid_keyboard_report_t const *p_new_report) { 96 | static hid_keyboard_report_t prev_report = {0, 0, {0}}; // previous report to check key released 97 | 98 | //------------- example code ignore control (non-printable) key affects -------------// 99 | for (uint8_t i = 0; i < 6; i++) { 100 | if (p_new_report->keycode[i]) { 101 | if (find_key_in_report(&prev_report, p_new_report->keycode[i])) { 102 | // exist in previous report means the current key is holding 103 | } else { 104 | // not existed in previous report means the current key is pressed 105 | bool const is_shift = 106 | p_new_report->modifier & (KEYBOARD_MODIFIER_LEFTSHIFT | KEYBOARD_MODIFIER_RIGHTSHIFT); 107 | uint8_t ch = keycode2ascii[p_new_report->keycode[i]][is_shift ? 1 : 0]; 108 | putchar(ch); 109 | if (ch == '\r') putchar('\n'); // added new line for enter key 110 | gvram_put_char(GX(cx), GY(cy), ch, WDOT); 111 | cx++; 112 | if (cx > VRAM_W) { 113 | cx = 0; 114 | cy++; 115 | if (cy > VRAM_H) { 116 | cy = 4; 117 | } 118 | } 119 | if (ch == '\r') { 120 | cy++; cx = 0; 121 | } 122 | fflush(stdout); // flush right away, else nanolib will wait for newline 123 | } 124 | } 125 | // TODO example skips key released 126 | } 127 | 128 | prev_report = *p_new_report; 129 | } 130 | 131 | void tuh_hid_keyboard_mounted_cb(uint8_t dev_addr) { 132 | // application set-up 133 | char mes[VRAM_W]; 134 | printf("A Keyboard device (address %d) is mounted\r\n", dev_addr); 135 | sprintf(mes, "A Keyboard device (address %d) is mounted\r\n", dev_addr); 136 | gvram_strings(0, 24, mes, WDOT); 137 | tuh_hid_keyboard_get_report(dev_addr, &usb_keyboard_report); 138 | } 139 | 140 | void tuh_hid_keyboard_unmounted_cb(uint8_t dev_addr) { 141 | // application tear-down 142 | char mes[VRAM_W]; 143 | printf("A Keyboard device (address %d) is unmounted\r\n", dev_addr); 144 | sprintf(mes, "A Keyboard device (address %d) is unmounted\r\n", dev_addr); 145 | gvram_strings(0, 24, mes, WDOT); 146 | } 147 | 148 | // invoked ISR context 149 | void tuh_hid_keyboard_isr(uint8_t dev_addr, xfer_result_t event) { 150 | (void) dev_addr; 151 | (void) event; 152 | } 153 | 154 | #endif 155 | 156 | #if CFG_TUH_HID_MOUSE 157 | 158 | CFG_TUSB_MEM_SECTION static hid_mouse_report_t usb_mouse_report; 159 | 160 | void cursor_movement(int8_t x, int8_t y, int8_t wheel) { 161 | //------------- X -------------// 162 | if (x < 0) { 163 | printf(ANSI_CURSOR_BACKWARD(%d), (-x)); // move left 164 | } else if (x > 0) { 165 | printf(ANSI_CURSOR_FORWARD(%d), x); // move right 166 | } else {} 167 | 168 | //------------- Y -------------// 169 | if (y < 0) { 170 | printf(ANSI_CURSOR_UP(%d), (-y)); // move up 171 | } else if (y > 0) { 172 | printf(ANSI_CURSOR_DOWN(%d), y); // move down 173 | } else {} 174 | 175 | //------------- wheel -------------// 176 | if (wheel < 0) { 177 | printf(ANSI_SCROLL_UP(%d), (-wheel)); // scroll up 178 | } else if (wheel > 0) { 179 | printf(ANSI_SCROLL_DOWN(%d), wheel); // scroll down 180 | } else {} 181 | } 182 | 183 | static inline void process_mouse_report(hid_mouse_report_t const *p_report) { 184 | static hid_mouse_report_t prev_report = {0}; 185 | 186 | //------------- button state -------------// 187 | uint8_t button_changed_mask = p_report->buttons ^prev_report.buttons; 188 | if (button_changed_mask & p_report->buttons) { 189 | printf(" %c%c%c ", 190 | p_report->buttons & MOUSE_BUTTON_LEFT ? 'L' : '-', 191 | p_report->buttons & MOUSE_BUTTON_MIDDLE ? 'M' : '-', 192 | p_report->buttons & MOUSE_BUTTON_RIGHT ? 'R' : '-'); 193 | } 194 | 195 | //------------- cursor movement -------------// 196 | cursor_movement(p_report->x, p_report->y, p_report->wheel); 197 | } 198 | 199 | 200 | void tuh_hid_mouse_mounted_cb(uint8_t dev_addr) { 201 | // application set-up 202 | printf("A Mouse device (address %d) is mounted\r\n", dev_addr); 203 | } 204 | 205 | void tuh_hid_mouse_unmounted_cb(uint8_t dev_addr) { 206 | // application tear-down 207 | printf("A Mouse device (address %d) is unmounted\r\n", dev_addr); 208 | } 209 | 210 | // invoked ISR context 211 | void tuh_hid_mouse_isr(uint8_t dev_addr, xfer_result_t event) { 212 | (void) dev_addr; 213 | (void) event; 214 | } 215 | 216 | #endif 217 | 218 | 219 | void hid_task(void) { 220 | uint8_t const addr = 1; 221 | 222 | #if CFG_TUH_HID_KEYBOARD 223 | if (tuh_hid_keyboard_is_mounted(addr)) { 224 | if (!tuh_hid_keyboard_is_busy(addr)) { 225 | process_kbd_report(&usb_keyboard_report); 226 | tuh_hid_keyboard_get_report(addr, &usb_keyboard_report); 227 | } 228 | } 229 | #endif 230 | 231 | #if CFG_TUH_HID_MOUSE 232 | if (tuh_hid_mouse_is_mounted(addr)) { 233 | if (!tuh_hid_mouse_is_busy(addr)) { 234 | process_mouse_report(&usb_mouse_report); 235 | tuh_hid_mouse_get_report(addr, &usb_mouse_report); 236 | } 237 | } 238 | #endif 239 | } 240 | 241 | 242 | //--------------------------------------------------------------------+ 243 | // BLINKING TASK 244 | //--------------------------------------------------------------------+ 245 | void led_blinking_task(void) { 246 | const uint32_t interval_ms = 250; 247 | static uint32_t start_ms = 0; 248 | 249 | static bool led_state = false; 250 | 251 | // Blink every interval ms 252 | if (board_millis() - start_ms < interval_ms) return; // not enough time 253 | start_ms += interval_ms; 254 | 255 | board_led_write(led_state); 256 | led_state = 1 - led_state; // toggle 257 | } 258 | 259 | //--------------------------------------------------------------------+ 260 | // HELPER FUNCTION 261 | //--------------------------------------------------------------------+ 262 | void print_greeting(void) { 263 | printf("This Host demo is configured to support:\n"); 264 | if (CFG_TUH_HID_KEYBOARD) puts(" - HID Keyboard"); 265 | if (CFG_TUH_HID_MOUSE) puts(" - HID Mouse"); 266 | gvram_strings(0, 0, "This Host demo is configured to support:", WDOT); 267 | if (CFG_TUH_HID_KEYBOARD) gvram_strings(0, 8, " - HID Keyboard", WDOT); 268 | if (CFG_TUH_HID_MOUSE) gvram_strings(0, 16, " - HID Mouse", WDOT); 269 | } 270 | -------------------------------------------------------------------------------- /pico_ntsc_grph.c: -------------------------------------------------------------------------------- 1 | /** 2 | * NTSC signal generation with PWM interrupt 3 | * ATTENTION: You should compile this source with Release option of ARM compiler. 4 | * Mar.24, 2021 Pa@ART modified from test_ntsc_wall_grph.c 5 | */ 6 | 7 | 8 | #include 9 | #include 10 | #include "pico/stdlib.h" 11 | #include "hardware/pwm.h" 12 | #include "font8x8_basic.h" 13 | #include "pico_ntsc_grph.h" 14 | 15 | static uint8_t gvram[GVRAM_W][GVRAM_H]; 16 | static uint8_t vram[VRAM_W][VRAM_H]; 17 | static int32_t count; 18 | 19 | // to clear VRAM contents (set to 0) 20 | void vram_clear( void ) { 21 | for (int i = 0; i < VRAM_W; i++) { 22 | for (int j = 0; j < VRAM_H; j++) { 23 | vram[i][j] = 0; 24 | } 25 | } 26 | } 27 | 28 | // to clear graphical VRAM contents (set to 0) 29 | void gvram_clear( void ) { 30 | for (int i = 0; i < GVRAM_W; i++) { 31 | for (int j = 0; j < GVRAM_H; j++) { 32 | gvram[i][j] = BDOT; 33 | } 34 | } 35 | } 36 | 37 | // to write a value into VRAM located at (x, y) 38 | void vram_write ( int x, int y, unsigned char value ) { 39 | vram[x][y] = value; 40 | } 41 | 42 | // to write a value into graphical VRAM located at (x, y) 43 | void gvram_write ( int x, int y, unsigned char value ) { 44 | gvram[x][y] = value; 45 | } 46 | 47 | // put a character on VRAM 48 | void gvram_put_char( int x, int y, char c, char col ) { 49 | unsigned char cp; 50 | for (int i = 0; i < CHAR_H; i++) { 51 | cp = ascii_table[c][i]; 52 | for (int j = 0; j < CHAR_W; j++) { 53 | if ((x + j < GVRAM_W) && (y + i < GVRAM_H)) { 54 | if ((cp & (1 << j)) != 0) { 55 | gvram[x + j][y + i] = col; 56 | } else { 57 | gvram[x + j][y + i] = BDOT; 58 | } 59 | } 60 | } 61 | } 62 | } 63 | 64 | // put strings on VRAM 65 | void gvram_strings( int x, int y, char *mes, char col ) { 66 | // if invalid (x, y), return 67 | if ((x < 0) || (x > GVRAM_W) || (y < 0) || (y > GVRAM_H)) { 68 | return; 69 | } 70 | int l = strlen(mes); 71 | for (int i = 0; i < l * CHAR_W; i += CHAR_W) { 72 | // if x position overflows, return 73 | if (x + i >= GVRAM_W) { 74 | return; 75 | // else put a character at the position 76 | } else { 77 | gvram_put_char(x + i, y, mes[i / CHAR_W], col); 78 | } 79 | } 80 | return; 81 | } 82 | 83 | // initialize video and LED GPIO 84 | void init_video_and_led_GPIO( ) { 85 | // initialize GPIO14 and GPIO15 for masked output 86 | gpio_init(GP14); 87 | gpio_init(GP15); 88 | gpio_init_mask(M14 | M15); 89 | gpio_set_dir(GP14, GPIO_OUT); 90 | gpio_set_dir(GP15, GPIO_OUT); 91 | // initialize LED GPIO 92 | gpio_init(LED); 93 | gpio_init_mask(MLED); 94 | gpio_set_dir(LED, GPIO_OUT); 95 | } 96 | 97 | // to generate horizontal sync siganl 98 | void hsync( void ) { 99 | SYNC; 100 | sleep_us(5); 101 | BLACK; 102 | sleep_us(7); 103 | } 104 | 105 | // to generate vertical sync siganl 106 | void vsync ( void ) { 107 | SYNC; 108 | sleep_us(10); 109 | sleep_us(5); 110 | sleep_us(10); 111 | BLACK; 112 | sleep_us(5); 113 | 114 | SYNC; 115 | sleep_us(10); 116 | sleep_us(5); 117 | sleep_us(10); 118 | BLACK; 119 | sleep_us(5); 120 | } 121 | 122 | // handler for holizontal line processing 123 | void horizontal_line( ) { 124 | // Clear the interrupt flag that brought us here 125 | pwm_clear_irq(pwm_gpio_to_slice_num(GPPWM)); 126 | 127 | // vertical synchronization duration 128 | if (count >= 3 && count <= 5) { 129 | vsync(); // vertical SYNC 130 | 131 | // VRAM drawing area 132 | } else if (count >= V_BASE && count < V_BASE + VRAM_H * CHAR_H) { 133 | hsync(); 134 | // left blank?? 135 | BLACK; 136 | sleep_us(0); // should be tuned 137 | 138 | int y = count - V_BASE; 139 | for (int x = 0; x < GVRAM_W; x++) { 140 | int c = gvram[x][y]; 141 | switch (c) { 142 | case BDOT: // black 143 | BLACK; 144 | break; 145 | case WDOT: // white 146 | WHITE; 147 | break; 148 | case GDOT: // gray 149 | GRAY; 150 | break; 151 | //case ZDOT: // dummy 152 | //break; 153 | default: 154 | BLACK; 155 | } 156 | } 157 | // right blank?? 158 | BLACK; 159 | sleep_us(0); 160 | } else { 161 | hsync(); 162 | BLACK; 163 | } 164 | // count up scan line 165 | count++; 166 | // if scan line reach to max 167 | if (count > 262) { 168 | count = 1; 169 | } 170 | return; 171 | } 172 | 173 | // initialize and start PWM interrupt by 64us period 174 | void enable_PWM_interrupt( ) { 175 | 176 | // GPPWM pin is the PWM output 177 | gpio_set_function(GPPWM, GPIO_FUNC_PWM); 178 | // Figure out which slice we just connected to the GPPWM pin 179 | uint slice_num = pwm_gpio_to_slice_num(GPPWM); 180 | 181 | // Mask our slice's IRQ output into the PWM block's single interrupt line, 182 | // and register our interrupt handler 183 | pwm_clear_irq(slice_num); 184 | pwm_set_irq_enabled(slice_num, true); 185 | irq_set_priority(PWM_IRQ_WRAP, 0xC0); // somehow this is needed if you compile with release option 186 | irq_set_exclusive_handler(PWM_IRQ_WRAP, horizontal_line); 187 | irq_set_enabled(PWM_IRQ_WRAP, true); 188 | 189 | // Set counter wrap value to generate PWM interrupt by this value 190 | pwm_set_wrap(slice_num, 7999); 191 | // Load the configuration into our PWM slice, and set it running. 192 | pwm_set_enabled(slice_num, true); 193 | } -------------------------------------------------------------------------------- /pico_ntsc_grph.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Header file for NTSC signal generation with PWM interrupt 3 | * ATTENTION: You should compile this source with Release option of ARM compiler. 4 | * Mar.24, 2021 Pa@ART modified from test_ntsc_wall_grph.c 5 | */ 6 | 7 | 8 | #ifndef __PICO_NTSC_GRPH__ 9 | #define __PICO_NTSC_GRPH__ 10 | 11 | #include 12 | #include 13 | #include "pico/stdlib.h" 14 | #include "hardware/pwm.h" 15 | #include "hardware/irq.h" 16 | 17 | #define LED 25 // GPIO connected LED on the board 18 | #define MLED (1 << LED) 19 | #define LEDON gpio_put_masked(MLED, MLED) 20 | #define LEDOFF gpio_put_masked(MLED, 0) 21 | #define GPPWM 2 // GPIO2 is PWM output 22 | #define GP14 14 // GPIO14 connected to RCA+ pin via 330 ohm 23 | #define GP15 15 // GPIO15 connected to RCA+ pin via 1k ohm 24 | #define M14 (1 << GP14) // bit mask for GPIO14 25 | #define M15 (1 << GP15) // bit mask for GPIO15 26 | #define SYNC gpio_put_masked(M14 | M15, 0) // GPIO14='L' and GPIO15='L' 27 | #define WHITE gpio_put_masked(M14 | M15, M14 | M15) // GPIO14='H' and GPIO15='H' 28 | #define BLACK gpio_put_masked(M14 | M15, M15) // GPIO14='L' and GPIO15='H' 29 | #define GRAY gpio_put_masked(M14 | M15, M14) // GPIO14='H' and GPIO15='L' 30 | #define VRAM_W 50 // width size of VRAM 31 | #define VRAM_H 25 // height size of VRAM 32 | #define GVRAM_W (VRAM_W * CHAR_W) // width size of graphic VRAM 33 | #define GVRAM_H (VRAM_H * CHAR_H) // height size of graphic VRAM 34 | #define V_BASE 40 // horizontal line number to start displaying VRAM 35 | #define BDOT 0 // black dot 36 | #define WDOT 1 // white dot 37 | #define GDOT 2 // gray dot 38 | #define ZDOT 3 // dummy dot 39 | 40 | // to clear VRAM contents (set to 0) 41 | void vram_clear( ); 42 | // to clear graphical VRAM contents (set to 0) 43 | void gvram_clear( ); 44 | // to write a value into VRAM located at (x, y) 45 | void vram_write ( int x, int y, unsigned char value ); 46 | // to write a value into graphical VRAM located at (x, y) 47 | void gvram_write ( int x, int y, unsigned char value ); 48 | // put a character on VRAM 49 | void gvram_put_char( int x, int y, char c, char col ); 50 | // put strings on VRAM 51 | void gvram_strings( int x, int y, char *mes, char col ); 52 | // initialize video and LED GPIO 53 | void init_video_and_led_GPIO( ); 54 | // to generate horizontal sync siganl 55 | void hsync( ); 56 | // to generate vertical sync siganl 57 | void vsync ( ); 58 | // handler for holizontal line processing 59 | void horizontal_line( ); 60 | // initialize and start PWM interrupt by 64us period 61 | void enable_PWM_interrupt( ); 62 | 63 | #endif -------------------------------------------------------------------------------- /pico_sdk_import.cmake: -------------------------------------------------------------------------------- 1 | # This is a copy of /external/pico_sdk_import.cmake 2 | 3 | # This can be dropped into an external project to help locate this SDK 4 | # It should be include()ed prior to project() 5 | 6 | if (DEFINED ENV{PICO_SDK_PATH} AND (NOT PICO_SDK_PATH)) 7 | set(PICO_SDK_PATH $ENV{PICO_SDK_PATH}) 8 | message("Using PICO_SDK_PATH from environment ('${PICO_SDK_PATH}')") 9 | endif () 10 | 11 | if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT} AND (NOT PICO_SDK_FETCH_FROM_GIT)) 12 | set(PICO_SDK_FETCH_FROM_GIT $ENV{PICO_SDK_FETCH_FROM_GIT}) 13 | message("Using PICO_SDK_FETCH_FROM_GIT from environment ('${PICO_SDK_FETCH_FROM_GIT}')") 14 | endif () 15 | 16 | if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT_PATH} AND (NOT PICO_SDK_FETCH_FROM_GIT_PATH)) 17 | set(PICO_SDK_FETCH_FROM_GIT_PATH $ENV{PICO_SDK_FETCH_FROM_GIT_PATH}) 18 | message("Using PICO_SDK_FETCH_FROM_GIT_PATH from environment ('${PICO_SDK_FETCH_FROM_GIT_PATH}')") 19 | endif () 20 | 21 | set(PICO_SDK_PATH "${PICO_SDK_PATH}" CACHE PATH "Path to the Raspberry Pi Pico SDK") 22 | set(PICO_SDK_FETCH_FROM_GIT "${PICO_SDK_FETCH_FROM_GIT}" CACHE BOOL "Set to ON to fetch copy of SDK from git if not otherwise locatable") 23 | set(PICO_SDK_FETCH_FROM_GIT_PATH "${PICO_SDK_FETCH_FROM_GIT_PATH}" CACHE FILEPATH "location to download SDK") 24 | 25 | if (NOT PICO_SDK_PATH) 26 | if (PICO_SDK_FETCH_FROM_GIT) 27 | include(FetchContent) 28 | set(FETCHCONTENT_BASE_DIR_SAVE ${FETCHCONTENT_BASE_DIR}) 29 | if (PICO_SDK_FETCH_FROM_GIT_PATH) 30 | get_filename_component(FETCHCONTENT_BASE_DIR "${PICO_SDK_FETCH_FROM_GIT_PATH}" REALPATH BASE_DIR "${CMAKE_SOURCE_DIR}") 31 | endif () 32 | FetchContent_Declare( 33 | pico_sdk 34 | GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk 35 | GIT_TAG master 36 | ) 37 | if (NOT pico_sdk) 38 | message("Downloading Raspberry Pi Pico SDK") 39 | FetchContent_Populate(pico_sdk) 40 | set(PICO_SDK_PATH ${pico_sdk_SOURCE_DIR}) 41 | endif () 42 | set(FETCHCONTENT_BASE_DIR ${FETCHCONTENT_BASE_DIR_SAVE}) 43 | else () 44 | message(FATAL_ERROR 45 | "SDK location was not specified. Please set PICO_SDK_PATH or set PICO_SDK_FETCH_FROM_GIT to on to fetch from git." 46 | ) 47 | endif () 48 | endif () 49 | 50 | get_filename_component(PICO_SDK_PATH "${PICO_SDK_PATH}" REALPATH BASE_DIR "${CMAKE_BINARY_DIR}") 51 | if (NOT EXISTS ${PICO_SDK_PATH}) 52 | message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' not found") 53 | endif () 54 | 55 | set(PICO_SDK_INIT_CMAKE_FILE ${PICO_SDK_PATH}/pico_sdk_init.cmake) 56 | if (NOT EXISTS ${PICO_SDK_INIT_CMAKE_FILE}) 57 | message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' does not appear to contain the Raspberry Pi Pico SDK") 58 | endif () 59 | 60 | set(PICO_SDK_PATH ${PICO_SDK_PATH} CACHE PATH "Path to the Raspberry Pi Pico SDK" FORCE) 61 | 62 | include(${PICO_SDK_INIT_CMAKE_FILE}) 63 | -------------------------------------------------------------------------------- /tusb_config.h: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2019 Ha Thach (tinyusb.org) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | * 24 | */ 25 | 26 | #ifndef _TUSB_CONFIG_H_ 27 | #define _TUSB_CONFIG_H_ 28 | 29 | #ifdef __cplusplus 30 | extern "C" { 31 | #endif 32 | 33 | //-------------------------------------------------------------------- 34 | // COMMON CONFIGURATION 35 | //-------------------------------------------------------------------- 36 | 37 | // defined by compiler flags for flexibility 38 | #ifndef CFG_TUSB_MCU 39 | #error CFG_TUSB_MCU must be defined 40 | #endif 41 | 42 | #if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX 43 | #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_HOST | OPT_MODE_HIGH_SPEED) 44 | #else 45 | #define CFG_TUSB_RHPORT0_MODE OPT_MODE_HOST 46 | #endif 47 | 48 | #ifndef CFG_TUSB_MEM_SECTION 49 | #define CFG_TUSB_MEM_SECTION 50 | #endif 51 | 52 | #ifndef CFG_TUSB_MEM_ALIGN 53 | #define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) 54 | #endif 55 | 56 | //-------------------------------------------------------------------- 57 | // CONFIGURATION 58 | //-------------------------------------------------------------------- 59 | 60 | #define CFG_TUH_HUB 1 61 | #define CFG_TUH_HID_KEYBOARD 1 62 | #define CFG_TUH_HID_MOUSE 0 63 | #define CFG_TUSB_HOST_HID_GENERIC 0 // (not yet supported) 64 | #define CFG_TUH_MSC 0 65 | #define CFG_TUH_CDC 0 66 | 67 | #define CFG_TUSB_HOST_DEVICE_MAX (CFG_TUH_HUB ? 5 : 1) // normal hub has 4 ports 68 | 69 | #ifdef __cplusplus 70 | } 71 | #endif 72 | 73 | #endif /* _TUSB_CONFIG_H_ */ 74 | --------------------------------------------------------------------------------