Tim - could you explain a bit more what it is you don't understand? It's reading like maybe you don't recognise what the struct cast is doing? Either that, or from my skim reading of Danne's code, the parts I list below? I'll give my attempt to explain, my apologies if it's too low-level, or too high-level!
In answer to your specific question, which I will change to remove ambiguity of 2 vs 2:
[how to set] ADTG2 reg 8 to value 0x3 (decimal 3)
I believe you would create a new element in the adtg_new array, then set it like this:
adtg_new[22] = (struct adtg_new) {2, 8, 3};
However, literal 8 looks very suspicious to me given the other regs being in 0x8800 range.
IF YOU USE EXACTLY THAT CODE IT IS WRONG, MAY CRASH AND MAY BRICK YOUR CAM. Now you have to read my long explanation below to understand why (need to extend adtg_new array).
Please bear in mind I have never looked at this code before and I haven't read all this thread. I have good experience with C but none with this code, and I understand hardware register manipulation can be very risky. You are taking the risk, not me, and I recommend you not trust my explanation.
I am working from a specific version of crop_rec.c, and it might be a stupid version! It was simply the first version that a search found for me:
https://bitbucket.org/Dannephoto/magic-lantern/raw/49f23e49f96129f0777d10e65fdf82942ef48522/modules/crop_rec/crop_rec.cAll that said, it looks to me that dst is how you select which ADTGX is used. dst is passed into the function and the lower 4 bits are masked in (int dst = cs & 0xF;).
It's important to note that I think adtg_new is an array of changes that we wish to make to registers (if I've got that part wrong my following reasoning will be quite wrong). Here's the array declaration:
/* expand this as required */
struct adtg_new adtg_new[22] = {{0}};
Here's how a single element of the array is declared:
struct adtg_new
{
int dst;
int reg;
int val;
};
So, there are max 22 registers the code expects to change. Here's where an example element of the array is initialised:
adtg_new[13] = (struct adtg_new) {6, 0x8882, 250};
This sets the 14th element (or 13th depending on how you like to think about 0 indexing...) to have dst == 6, reg == 0x8882, val == 250. I will later call this "e", and "e.dst", "e.reg" etc.
Here's the code that I think is responsible for making changes to registers:
if ((reg == adtg_new[i].reg) && (dst & adtg_new[i].dst))
{
int new_value = adtg_new[i].val;
dbg_printf("ADTG%x[%x] = %x\n", dst, reg, new_value);
*(uint16_t*)copy_ptr = new_value;
This only changes a reg if some conditions are met. It's inside a loop that covers all 22 elements of the array. We read from data_buf, which I haven't tried to understand but I assume holds some list of potential registers to change. We check every reg struct in adtg_new against every element of data_buf. If the buffer holds a reg value that matches our e.reg, we then check if passed in dst has at least the bits set that e.dst does. Now, look at the dbg_printf! If the passed in dst is 6, with our e, it would print:
ADTG6[8882] = 250
So we know that the passed in dst says which ADTGX to use, and the first field of the struct selects if your change should be applied. If you want your change to apply to all, use 0xf, due to the logical "&" used earlier (you probably shouldn't do this! I don't know what the ADTG registers are but applying to all is likely dangerous and wrong). e.dst == 0x6 will cause the change to be applied if the passed in dst is 4, 2, or 6; i.e., if the passed in dst is ADTG2, ADTG4 or ADTG6.