Subtracting frames low-level code (works on DIGIC IV) :
Process time similar to raw bit depth reduction (few milliseconds more).
static void sub_dark(struct raw_info * raw_info, void* buf1, void* buf2, void* buf3)
{
uint32_t edmac_read_chan = 0xa;
uint32_t edmac_read_chan2 = 0xb;
uint32_t edmac_write_chan = 3;
uint32_t edmac_read_connection = 0;
uint32_t edmac_read_connection2 = 1;
uint32_t edmac_write_connection = 0x10;
/* it locks up without reslock */
if (!resLock)
{
int edmac_read_ch_index = edmac_channel_to_index(edmac_read_chan);
int edmac_read_ch_index2 = edmac_channel_to_index(edmac_read_chan2);
int edmac_write_ch_index = edmac_channel_to_index(edmac_write_chan);
uint32_t resIds[] = {
0x00000003 | edmac_write_ch_index, /* write edmac channel */
0x00010002 | edmac_read_ch_index, /* read edmac channel */
0x00010003 | edmac_read_ch_index2, /* read edmac channel */
0x00020010 | edmac_write_connection, /* write connection */
0x00030000 | edmac_read_connection, /* read connection */
0x00030001 | edmac_read_connection2, /* read connection */
0x00050002, /* DSUNPACK? */
0x00050003, /* UNPACK24? */
0x00050006, /* DARK? */
0x0005001d, /* PACK16/WDMAC16 */
0x0005001f, /* PACK16/WDMAC16 */
};
resLock = CreateResLockEntry(resIds, COUNT(resIds));
}
LockEngineResources(resLock);
/* configure image processing modules */
/* register addresses from strings */
const uint32_t DS_SEL = 0xC0F08104;
const uint32_t PACK16_ISEL = 0xC0F082D0;
const uint32_t WDMAC16_ISEL = 0xC0F082D8;
const uint32_t DSUNPACK_ENB = 0xC0F08060;
const uint32_t DSUNPACK_MODE = 0xC0F08064;
const uint32_t DSUNPACK_DM_EN = 0xC0F08274;
const uint32_t UNPACK24_ENB = 0xC0F08070;
const uint32_t UNPACK24_MODE = 0xC0F08074;
const uint32_t UNPACK24_DM_EN = 0xC0F08260;
const uint32_t DARK_ENB = 0xC0F08000;
const uint32_t DARK_MODE = 0xC0F08004;
const uint32_t DARK_SETUP = 0xC0F08008;
const uint32_t DARK_LIMIT = 0xC0F0800C;
const uint32_t DARK_SETUP_14_12 = 0xC0F08010;
const uint32_t DARK_LIMIT_14_12 = 0xC0F08014;
const uint32_t DARK_SAT_LIMIT = 0xC0F08018;
const uint32_t DARK_KZMK_SAV_A = 0xC0F082A0;
const uint32_t DARK_KZMK_SAV_B = 0xC0F082A4;
const uint32_t PACK16_ENB = 0xC0F08120;
const uint32_t PACK16_MODE = 0xC0F08124;
const uint32_t PACK16_DEFM_ON = 0xC0F082B8;
const uint32_t PACK16_ILIM = 0xC0F085B4;
/* for PACK16_MODE, DSUNPACK_MODE, ADUNPACK_MODE (mask 0x131) */
const uint32_t MODE_14BIT = 0x030;
engio_write((uint32_t[]) {
/* input selection for the processing modules? */
DS_SEL, 0,
PACK16_ISEL, 0,
WDMAC16_ISEL, 0,
/* DSUNPACK module (input image data) */
DSUNPACK_ENB, 0x80000000,
DSUNPACK_MODE, MODE_14BIT,
DSUNPACK_DM_EN, 0,
/* UNPACK24 module (input image data?) */
UNPACK24_ENB, 0x80000000,
UNPACK24_MODE, MODE_14BIT,
UNPACK24_DM_EN, 0,
/* DARK module */
DARK_ENB, 0x80000000,
DARK_MODE, 0x11014,
DARK_SETUP, 0x110,
DARK_LIMIT, 0x7c,
DARK_SETUP_14_12, 0x400,
DARK_LIMIT_14_12, 0x3fff,
DARK_SAT_LIMIT, 0x3fff,
DARK_KZMK_SAV_A, 0x1,
DARK_KZMK_SAV_B, 0x0,
/* PACK16 module (output image data) */
PACK16_ENB, 0x80000000,
PACK16_MODE, MODE_14BIT,
PACK16_DEFM_ON, 1,
PACK16_ILIM, 0x3FFF, /* white level? */
/* whew! */
0xFFFFFFFF, 0xFFFFFFFF
});
/* EDMAC setup */
RegisterEDmacCompleteCBR(edmac_read_chan, edmac_read_complete_cbr, 0);
RegisterEDmacCompleteCBR(edmac_read_chan2, edmac_read_complete_cbr, 0);
RegisterEDmacCompleteCBR(edmac_write_chan, edmac_write_complete_cbr, 0);
ConnectWriteEDmac(edmac_write_chan, edmac_write_connection);
ConnectReadEDmac(edmac_read_chan, edmac_read_connection);
ConnectReadEDmac(edmac_read_chan2, edmac_read_connection2);
struct edmac_info src_edmac_info = {
.xb = raw_info->pitch,
.yb = raw_info->height - 1,
};
SetEDmac(edmac_read_chan, buf1, &src_edmac_info, 0x20000);
SetEDmac(edmac_read_chan2, buf2, &src_edmac_info, 0x20000);
SetEDmac(edmac_write_chan, buf3, &src_edmac_info, 1);
/* time the operation */
info_led_on();
int64_t t0 = get_us_clock_value();
/* start processing */
StartEDmac(edmac_write_chan, 0);
/* start operation */
engio_write((uint32_t[]) {
PACK16_ENB, 1,
DARK_ENB, 1,
DSUNPACK_ENB, 1,
UNPACK24_ENB, 1,
0xFFFFFFFF, 0xFFFFFFFF
});
StartEDmac(edmac_read_chan, 2);
StartEDmac(edmac_read_chan2, 4);
/* wait for everything to finish */
take_semaphore(edmac_write_done_sem, 0);
int64_t t1 = get_us_clock_value();
info_led_off();
/* finished */
/* reset processing modules */
engio_write((uint32_t[]) {
PACK16_ENB, 0x80000000,
DARK_ENB, 0x80000000,
DSUNPACK_ENB, 0x80000000,
UNPACK24_ENB, 0x80000000,
0xFFFFFFFF, 0xFFFFFFFF
});
UnregisterEDmacCompleteCBR(edmac_read_chan);
UnregisterEDmacCompleteCBR(edmac_read_chan2);
UnregisterEDmacCompleteCBR(edmac_write_chan);
UnLockEngineResources(resLock);
printf("Process time: %d us\n", (int)(t1 - t0));
/* update raw_info */
raw_info->buffer = buf3;
}
Question is how add frames on DIGIC IV.
Digic V uses the unknown module that is not available on DIGIC IV.