Commits

a1ex committed 785dfa0

5D3: enabled an workaround for fixing some timing issues with certain cards (e.g. Kingston 266x) - http://www.magiclantern.fm/forum/index.php?topic=2528.0 . Reworked the DebugMsg hack to be always active.

Comments (0)

Files changed (2)

     MENU_SET_ICON(cf_present ? MNI_ON : MNI_OFF, 0);
 }
 
+/* enable to slow down the write speed, which improves compatibility with certain cards */
+/* only enable if needed */
+CONFIG_INT("cf.workaround", cf_card_workaround, 0);
+
 void card_test(int type)
 {
     // some cards have timing issues on 5D3
     // ML will test for this bug at startup, and refuse to run on cards that can cause trouble
     // http://www.magiclantern.fm/forum/index.php?topic=2528.0
-    
+
+    if (!cf_card_workaround)
+    {
+        /* save the config with workaround enabled now, because if the test fails, we'll no longer able to save it */
+        cf_card_workaround = 1;
+        save_config(0,0);
+        cf_card_workaround = 0;
+    }
+
     if (is_dir(type ? "B:/" : "A:/"))
     {
         FILE* f = FIO_CreateFileEx(type ? "B:/test.dat" : "A:/test.dat");
             while(1)
             {
                 bmp_fill(COLOR_BLACK, 0, 0, 550, 80);
-                bfnt_puts(type ? "SD card test failed!" : "CF card test failed!", 0, 0, COLOR_WHITE, COLOR_BLACK);
-                bfnt_puts("Do not use this card on 5D3!", 0, 40, COLOR_WHITE, COLOR_BLACK);
+                if (cf_card_workaround==0 && type==0)
+                {
+                    bfnt_puts("CF test fail, enabling workaround.", 0, 0, COLOR_WHITE, COLOR_BLACK);
+                    bfnt_puts("Restart the camera and try again!", 0, 40, COLOR_WHITE, COLOR_BLACK);
+                }
+                else
+                {
+                    bfnt_puts(type ? "SD card test failed!" : "CF card test failed!", 0, 0, COLOR_WHITE, COLOR_BLACK);
+                    bfnt_puts("Do not use this card on 5D3!", 0, 40, COLOR_WHITE, COLOR_BLACK);
+                }
                 beep();
                 info_led_blink(1, 1000, 1000);
             }
                 .name = "Card test at startup", 
                 .priv = &card_test_enabled,
                 .max = 1,
-                .help = "File write test. Disable ONLY after testing ALL your cards!"
+                .help = "File write test. Some cards may have compatibility issues.",
+            },
+            {
+                .name = "CF card workaround",
+                .priv = &cf_card_workaround,
+                .max = 1,
+                .help = "Slows down the CF write speed to let you use certain cards.",
+                .help2 = "(e.g. Kingston 16GB 266x is known to require this)"
             },
             {
                 .name = "Preferred card", 
 int is_canon_bottom_bar_dirty() { return bottom_bar_dirty; }
 int get_last_time_active() { return last_time_active; }
 
+#ifdef CONFIG_5D3
+extern int cf_card_workaround;
+#endif
+
 #if defined(CONFIG_5D3) || defined(CONFIG_6D) || defined(CONFIG_EOSM) || defined(CONFIG_650D)
 // disable Canon bottom bar
-static uint32_t orig_DebugMsg_instr = 0;
+static int bottom_bar_hack = 0;
+
 static void hacked_DebugMsg(int class, int level, char* fmt, ...)
 {
-    if (class == 131 && level == 1)
+    if (bottom_bar_hack && class == 131 && level == 1)
     #if defined(CONFIG_5D3)
         MEM(0x3334C) = 0; // LvApp_struct.off_0x60 /*0x3334C*/ = ret_str:JudgeBottomInfoDispTimerState_FF4B0970
     #elif defined(CONFIG_6D)
     #elif defined(CONFIG_650D)
         MEM(0x41868+0x58) = 0;
     #endif
+
+    #ifdef CONFIG_5D3
+    if (cf_card_workaround)
+    {
+        if (class == 34 && level == 1) // cfDMAWriteBlk
+        {
+            for (int i = 0; i < 10000; i++) 
+                asm("nop");
+        }
+    }
+    #endif
     
 #ifdef CONFIG_5D3
     extern int rec_led_off;
     if ((class == 34 || class == 35) && level == 1 && rec_led_off && recording) // cfWriteBlk, sdWriteBlk
         *(uint32_t*) (CARD_LED_ADDRESS) = (LEDOFF);
 #endif
+
     return;
 }
+
+static uint32_t orig_DebugMsg_instr = 0;
+
+static void DebugMsg_hack()
+{
+    if (!orig_DebugMsg_instr)
+    {
+        uint32_t d = (uint32_t)&DryosDebugMsg;
+        orig_DebugMsg_instr = *(uint32_t*)(d);
+        *(uint32_t*)(d) = B_INSTR((uint32_t)&DryosDebugMsg, hacked_DebugMsg);
+    }
+}
+
+static void DebugMsg_uninstall()
+{
+    // uninstall our mean hack (not used)
+    
+    if (orig_DebugMsg_instr)
+    {
+        uint32_t d = (uint32_t)&DryosDebugMsg;
+        *(uint32_t*)(d) = orig_DebugMsg_instr;
+        orig_DebugMsg_instr = 0;
+    }
+}
+
+INIT_FUNC("debugmsg-hack", DebugMsg_hack);
+
 #endif
 
-
 int handle_other_events(struct event * event)
 {
     extern int ml_started;
     {
         if (lv_disp_mode == 0 && get_global_draw_setting() && liveview_display_idle() && lv_dispsize == 1)
         {
-            // use a modified DebugMsg which disables bottom bar display timer instead of doing what it normally does
-            if (!orig_DebugMsg_instr)
-            {
-                uint32_t d = (uint32_t)&DryosDebugMsg;
-                orig_DebugMsg_instr = *(uint32_t*)(d);
-                *(uint32_t*)(d) = B_INSTR((uint32_t)&DryosDebugMsg, hacked_DebugMsg);
-            }
-            
+            bottom_bar_hack = 1;
             if (get_halfshutter_pressed()) bottom_bar_dirty = 10;
 
             if (UNAVI_FEEDBACK_TIMER_ACTIVE)
         }
         else
         {
-            // uninstall our mean hack
-            if (orig_DebugMsg_instr)
-            {
-                uint32_t d = (uint32_t)&DryosDebugMsg;
-                *(uint32_t*)(d) = orig_DebugMsg_instr;
-                orig_DebugMsg_instr = 0;
-            }
-
+            bottom_bar_hack  = 0;
             bottom_bar_dirty = 0;
         }