6868#define TIMEOUT_ABORT 100
6969
7070#define VMU_BLOCK_SIZE 512
71- #define VMU_WRITE_ACCESSES 4
72- #define VMU_READ_ACCESSES 1
7371
7472#define wait_100ns () asm("movi a8, 5\n\tloop a8, waitend%=\n\tnop\n\twaitend%=:\n":::"a8");
7573#define wait_500ns () asm("movi a8, 49\n\tloop a8, waitend%=\n\tnop\n\twaitend%=:\n":::"a8");
@@ -89,6 +87,11 @@ struct maple_pkt {
8987 };
9088};
9189
90+ typedef union {
91+ uint8_t bytes [4 ];
92+ uint32_t val ;
93+ } u32_val_t ;
94+
9295static const uint8_t gpio_pin [][2 ] = {
9396 {21 , 22 },
9497#ifndef CONFIG_BLUERETRO_WIRED_TRACE
@@ -192,7 +195,8 @@ static inline void load_mouse_axes(uint8_t port, uint16_t *axes) {
192195}
193196#endif
194197
195- static void maple_tx (uint32_t port , uint32_t maple0 , uint32_t maple1 , uint8_t * data , uint32_t len ) {
198+ static uint8_t maple_tx (uint32_t port , uint32_t maple0 , uint32_t maple1 , uint8_t * data , uint32_t len ) {
199+ uint8_t crc_ret = 0 ;
196200 uint8_t * crc = data + (len - 1 );
197201 * crc = 0x00 ;
198202
@@ -248,6 +252,7 @@ static void maple_tx(uint32_t port, uint32_t maple0, uint32_t maple1, uint8_t *d
248252 GPIO .out_w1tc = maple1 ;
249253 wait_200ns ();
250254 }
255+ crc_ret = * crc ;
251256 * crc ^= * data ;
252257 }
253258 GPIO .out_w1ts = maple0 ;
@@ -269,6 +274,7 @@ static void maple_tx(uint32_t port, uint32_t maple0, uint32_t maple1, uint8_t *d
269274 core0_stall_end ();
270275 gpio_set_direction_iram (gpio_pin [port ][0 ], GPIO_MODE_INPUT );
271276 gpio_set_direction_iram (gpio_pin [port ][1 ], GPIO_MODE_INPUT );
277+ return crc_ret ;
272278}
273279
274280static unsigned maple_rx (unsigned cause ) {
@@ -277,13 +283,12 @@ static unsigned maple_rx(unsigned cause) {
277283 uint32_t bit_cnt = 0 ;
278284 uint32_t gpio ;
279285 uint8_t * data = pkt .data ;
280- #ifdef CONFIG_BLUERETRO_WIRED_TRACE
281286 uint32_t byte ;
282- #endif
283287 uint32_t port ;
284288 uint32_t bad_frame ;
285- uint8_t len , cmd , src , dst , crc = 0 ;
289+ uint8_t len , cmd , src , dst , crc = 0 , wcrc = 0 ;
286290 uint32_t maple1 ;
291+ u32_val_t func ;
287292 uint8_t phase ;
288293 uint8_t block_no ;
289294
@@ -331,7 +336,8 @@ static unsigned maple_rx(unsigned cause) {
331336 * data &= ~mask ;
332337 }
333338 }
334- crc ^= * data ;
339+ crc = wcrc ;
340+ wcrc ^= * data ;
335341 ++ data ;
336342 }
337343maple_end :
@@ -358,6 +364,7 @@ static unsigned maple_rx(unsigned cause) {
358364 ets_printf ("\n" );
359365#else
360366 len = ((bit_cnt - 1 ) / 32 ) - 1 ;
367+ byte = ((bit_cnt - 1 ) / 8 );
361368 /* Fix up to 7 bits loss */
362369 if (bad_frame ) {
363370 cmd = maple_fix_byte (bad_frame , pkt .data [2 ], pkt .data [3 ]);
@@ -369,7 +376,7 @@ static unsigned maple_rx(unsigned cause) {
369376 cmd = pkt .data [2 ];
370377 src = pkt .data [1 ];
371378 dst = pkt .data [0 ];
372- bad_frame = 1 ;
379+ bad_frame = 8 ;
373380 }
374381 else {
375382 cmd = pkt .cmd ;
@@ -558,8 +565,16 @@ static unsigned maple_rx(unsigned cause) {
558565 case ADDR_MEM :
559566 pkt .src = src ;
560567 pkt .dst = dst ;
568+ func .bytes [0 ] = maple_fix_byte (bad_frame , pkt .data [3 ], pkt .data [4 ]);
569+ func .bytes [1 ] = maple_fix_byte (bad_frame , pkt .data [4 ], pkt .data [5 ]);
570+ func .bytes [2 ] = maple_fix_byte (bad_frame , pkt .data [5 ], pkt .data [6 ]);
571+ func .bytes [3 ] = maple_fix_byte (bad_frame , pkt .data [6 ], pkt .data [7 ]);
572+ block_no = maple_fix_byte (bad_frame , pkt .data [7 ], pkt .data [8 ]);
573+ phase = maple_fix_byte (bad_frame , pkt .data [9 ], pkt .data [10 ]);
574+ // ets_printf("%ld S: %ld C: %02X F: %08X B: %02X P: %02X\n", bad_frame, byte, cmd, func.val, block_no, phase);
561575 switch (cmd ) {
562576 case CMD_INFO_REQ :
577+ case CMD_EXT_INFO_REQ :
563578 pkt .len = 28 ;
564579 pkt .cmd = CMD_INFO_RSP ;
565580 pkt .data32 [0 ] = ID_VMU_CLK | ID_VMU_LCD | ID_VMU_MEM ;
@@ -571,39 +586,60 @@ static unsigned maple_rx(unsigned cause) {
571586 pkt .data32 [27 ] = PWR_VMU ;
572587 maple_tx (port , maple0 , maple1 , pkt .data , pkt .len * 4 + 5 );
573588 break ;
574- case CMD_EXT_INFO_REQ : /* unimplemented */
575589 case CMD_GET_CONDITION :
576590 case CMD_MEM_INFO_REQ :
577- pkt .len = 0x07 ;
578591 pkt .cmd = CMD_DATA_TX ;
579- pkt .data32 [0 ] = ID_VMU_MEM ;
580- memcpy ((void * )& pkt .data32 [1 ], vmu_media_info , sizeof (vmu_media_info ));
581- maple_tx (port , maple0 , maple1 , pkt .data , pkt .len * 4 + 5 );
592+ pkt .data32 [0 ] = func .val ;
593+ switch (func .val ) {
594+ case ID_VMU_MEM :
595+ pkt .len = 0x07 ;
596+ memcpy ((void * )& pkt .data32 [1 ], vmu_media_info , sizeof (vmu_media_info ));
597+ maple_tx (port , maple0 , maple1 , pkt .data , pkt .len * 4 + 5 );
598+ break ;
599+ case ID_VMU_LCD :
600+ pkt .len = 0x02 ;
601+ pkt .data32 [1 ] = 0x2F1F1002 ;
602+ maple_tx (port , maple0 , maple1 , pkt .data , pkt .len * 4 + 5 );
603+ break ;
604+ }
582605 break ;
583606 case CMD_BLOCK_READ :
607+ if (func .val != ID_VMU_MEM ) {
608+ ets_printf ("RD ERR func: 0x%08X\n" , pkt .data32 [0 ]);
609+ }
584610 pkt .len = 0x82 ;
585611 pkt .cmd = CMD_DATA_TX ;
586- pkt .data32 [0 ] = ID_VMU_MEM ;
587- phase = ( uint8_t )(( pkt .data32 [1 ] >> 16 ) & 0x00FF ) ;
612+ pkt .data32 [0 ] = func . val ;
613+ pkt .data32 [1 ] = ( phase << 16 ) | block_no ;
588614 if (phase ) {
589- ets_printf ("Block Read with unexpected phase: 0x%02X , expected 0\n" , phase );
615+ ets_printf ("RD ERR phase: %d , expected 0\n" , phase );
590616 }
591- block_no = (uint8_t )((pkt .data32 [1 ]) & 0x00FF );
592617 mc_read (block_no * VMU_BLOCK_SIZE , (void * )& pkt .data32 [2 ], VMU_BLOCK_SIZE );
593- maple_tx (port , maple0 , maple1 , pkt .data , pkt .len * 4 + 5 );
618+ crc = maple_tx (port , maple0 , maple1 , pkt .data , pkt .len * 4 + 5 );
619+ // ets_printf("R: %02X %d %02X\n", block_no, phase, crc);
594620 break ;
595621 case CMD_BLOCK_WRITE :
596- if (pkt .len != (32 + 2 ) && pkt .data32 [0 ] == ID_VMU_MEM ) {
597- ets_printf ("Unexpected Block Write packet length: 0x%02X, expected 0x22\n" , pkt .len );
598- }
622+ // if (pkt.len != (32 + 2) && func.val == ID_VMU_MEM) {
623+ // ets_printf("WR ERR: %d words, expected 34\n", pkt.len);
624+ // }
625+ // if (func.val == ID_VMU_MEM) {
626+ // if (crc != pkt.data[pkt.len * 4 + 4]) {
627+ // ets_printf("CRC ERR: 0x%02X, 0x%02X\n", pkt.data[pkt.len * 4 + 4], crc);
628+ // }
629+ // }
599630 pkt .len = 0x00 ;
600631 pkt .cmd = CMD_ACK ;
601- if ((!bad_frame ) && pkt .data32 [0 ] == ID_VMU_MEM ) {
602- phase = (uint8_t )((pkt .data32 [1 ] >> 16 ) & 0x00FF );
603- block_no = (uint8_t )((pkt .data32 [1 ]) & 0x00FF );
604- /* Data is written to the MC module in wire byte order. */
605- /* If creating a read/write function, this must be accounted for. */
606- mc_write ((block_no * VMU_BLOCK_SIZE ) + (128 * phase ), (void * )& pkt .data32 [2 ], 128 );
632+ if (func .val == ID_VMU_MEM ) {
633+ // ets_printf("W: %02X %d %02X\n", block_no, phase, crc);
634+ if (bad_frame ) {
635+ for (uint32_t i = 0 ; i < 128 ; i ++ ) {
636+ uint8_t mc_data = maple_fix_byte (bad_frame , pkt .data [i + 11 ], pkt .data [i + 12 ]);
637+ mc_write ((block_no * VMU_BLOCK_SIZE ) + (128 * phase ) + i , & mc_data , 1 );
638+ }
639+ }
640+ else {
641+ mc_write ((block_no * VMU_BLOCK_SIZE ) + (128 * phase ), (void * )& pkt .data32 [2 ], 128 );
642+ }
607643 }
608644 maple_tx (port , maple0 , maple1 , pkt .data , pkt .len * 4 + 5 );
609645 break ;
@@ -613,7 +649,7 @@ static unsigned maple_rx(unsigned cause) {
613649 maple_tx (port , maple0 , maple1 , pkt .data , pkt .len * 4 + 5 );
614650 break ;
615651 default :
616- ets_printf ("%02X: Unk cmd: 0x %02X\n" , dst , cmd );
652+ ets_printf ("%02X: Unk cmd: %02X %02X %ld \n" , dst , cmd , crc , byte );
617653 break ;
618654 }
619655 break ;
0 commit comments