[lua_fix] focus_pos not reported correctly on 650d

Issue #2861 new
AlexT created an issue

focus_pos is not returned on 650d, tested with different lenses

printf("%d : %d\n", lens.focus_distance, lens.focus_pos)

is only returning " : focus_distance"

when running lens_focus() and lens.focus(), console shows Lens moving (0, 40000) or (0, 0) while focusing and 41000 or 1000 when focus soft limit is reached

tested same code with same lenses on 50d and got correct values printing focus_pos, but slightly different numbers from lens_focus() and lens.focus()

Comments (5)

  1. Alex

    Mind running api_test.lua and uploading the log?

    Call for testers - no results on this section from 650D/700D (though 700D seems to be working).

    If you can compile from source, can you check struct prop_lv_lens in lens.h? The CONFIG_EOSM version might also apply to 650D.

    You could also run a startup log in LiveView while autofocusing (or turning the focus ring, if you have a focus-by-wire lens). You have to be very quick after entering LiveView, as the logging buffer fills really fast.

  2. AlexT reporter

    I just ran a startup log while autofocusing in LiveView and uploaded some logs

    I can compile from source and I found struct prop_lv_lens but I'm not sure, what to do with it.

    #if defined(CONFIG_6D) || defined(CONFIG_5D3_123) || defined(CONFIG_100D)
    struct prop_lv_lens
    {  
            uint32_t                lens_rotation; // Identical Doesn't Change
            uint32_t                lens_step; // Value Matches initial but doesn't move.
            uint32_t                off_0x08;
            uint32_t                off_0x0c;
            uint32_t                off_0x10;
            uint32_t                off_0x14;
            uint32_t                off_0x18;
            uint32_t                off_0x1c;
            uint16_t                off_0x20;
            uint8_t                 off_0x22;
            uint16_t                focus_pos; // off_0x23
            uint8_t                 off_0x25;
            uint16_t                off_0x26;
            uint32_t                off_0x28;
            uint16_t                off_0x2c;        
            uint8_t                 off_0x2e;
            uint16_t                focal_len;  // off_0x2f
            uint16_t                off_0x31;
            uint16_t                focus_dist; // off_0x33
            uint32_t                off_0x35;
            uint32_t                off_0x39;
            uint8_t                 off_0x3d;
            uint8_t                 off_0x3e;
            uint8_t                 off_0x3f;
    
    } __attribute__((packed));
    
    SIZE_CHECK_STRUCT( prop_lv_lens, 64 );
    
    #elif defined(CONFIG_EOSM)
    struct prop_lv_lens
    {
            uint32_t                lens_rotation;
            uint32_t                lens_step;
            uint32_t                off_0x08;
            uint32_t                off_0x0c;
            uint32_t                off_0x10;
            uint32_t                off_0x14;
            uint32_t                off_0x18;
            uint32_t                off_0x1c;
            uint16_t                off_0x20;
            uint16_t                focus_pos;  // off_0x22; guess (not tested)
            uint32_t                off_0x24;
            uint32_t                off_0x28;
            uint16_t                off_0x2c;
            uint16_t                focal_len;  // off_0x2e
            uint16_t                focus_dist; // One FD; off_0x30
            uint16_t                focus_dist2;// off_0x32
            uint16_t                off_0x34;
            uint16_t                off_0x36;
            uint16_t                off_0x38;
            uint16_t                off_0x3a;
            uint8_t                 off_0x3c;
    } __attribute__((packed));
    
    SIZE_CHECK_STRUCT( prop_lv_lens, 61 );
    
    #else
    struct prop_lv_lens
    {
            uint32_t                lens_rotation; // float in little-endian actually
            uint32_t                lens_step; // float in little-endian actually
            uint32_t                off_0x08;
            uint32_t                off_0x0c;
            uint32_t                off_0x10;
            uint32_t                off_0x14;
            uint32_t                off_0x18;
            uint32_t                off_0x1c;
            int16_t                 focus_pos;  /* off_0x20; see lens_info.focus_pos */
            uint16_t                off_0x22;
            uint32_t                off_0x24;
            uint32_t                off_0x28;
            uint16_t                focal_len;      // off_0x2c;
            uint16_t                focus_dist;     // off_0x2e;
            uint32_t                off_0x30;
            uint32_t                off_0x34;
            uint16_t                off_0x38;
    } __attribute__((packed));
    
    SIZE_CHECK_STRUCT( prop_lv_lens, 58 );
    
  3. Alex

    Yeah, that's it. Try CONFIG_650D instead of CONFIG_EOSM.

    If that won't work: in lens.c, PROP_LENS, print the contents of the buffer (example, but replace qprintf with printf or bmp_printf, since qprintf is only for QEMU) and find out what offset changes a lot and looks like a step counter for the AF motor.

    It takes some fiddling to get useful logs, unfortunately. The attached log didn't even show the complete startup process; LiveView is a LOT more verbose.

    The default buffer size (dm-spy.c in dm-spy-experiments branch) is 512K and it fills really fast; some models accept 2MB. You may try tweaking it, but 2MB are probably not enough either - will cover a few LiveView frames (less than 1 second) if lucky.

    However, logging just the autofocusing process should work. Compile the dm-spy-experiments branch with CONFIG_DEBUG_INTERCEPT=y in Makefile.user, then go to LiveView, select from menu: Debug -> DebugMsg Log, autofocus, then select DebugMsg Log again to save the log.

    Logging starts 1 second after the first click, and fills after a few LiveView frames. Reducing FPS to 10 or so may help.

    Alternative: quiet all the messages from Canon and log only our own. In dm-spy.c, my_DebugMsg, return early (skip the message) if class or level are nonzero: if (class || level) return; (our logging code calls DebugMsg with class=0 and level=0). That will include MPU messages (where the focus_pos is coming from). In this case, a small buffer should be enough.

  4. AlexT reporter

    CONFIG_650D instead of CONFIG_EOSM did not work. I looked into the buffer of PROP_LV_LENS and could not find anything behaving like focus_pos should have(tried it on my 50D and could find everything). I could find focal_len at off_0x2c and focus_dist at off_0x2e.

    Something interesting I observed on both 650D an 50D: the 3rd highest byte of PROP_LV_LENS buffer always had the high nibble at 1 if focus soft limit was reached and most of other times at 0 (while autofocusing and with lens_focus()). Could probably be helpful, because lens_focus() sometimes takes a long time to return false at soft limit(at least on 650D).

    edit: added a few DebugMsg Logs

  5. Log in to comment