use array_concat::*;

use crate::constants::*;
use crate::Register;

/* Helpers */
// Register Helpers for 1 to 13 sets
const fn mode_entry_1_reg(mode: u32, r0: u32, m0: u8, v0: u8) -> [u8; 7] {
    [(mode << 8) as u8, (mode & 0xFF) as u8, 1, (r0 << 8) as u8, (r0 & 0xFF) as u8, m0, v0]
}

const fn mode_entry_2_reg(mode: u32, r0: u32, m0: u8, v0: u8, r1: u32, m1: u8, v1: u8) -> [u8; 11] {
    [(mode << 8) as u8, (mode & 0xFF) as u8, 2, (r0 << 8) as u8, (r0 & 0xFF) as u8, m0, v0, (r1 << 8) as u8, (r1 & 0xFF) as u8, m1, v1]
}

const fn mode_entry_3_reg(mode: u32, r0: u32, m0: u8, v0: u8, r1: u32, m1: u8, v1: u8, r2: u32, m2: u8, v2: u8) -> [u8; 15] {
    [(mode << 8) as u8, (mode & 0xFF) as u8, 3, (r0 << 8) as u8, (r0 & 0xFF) as u8, m0, v0, (r1 << 8) as u8, (r1 & 0xFF) as u8, m1, v1, (r2 << 8) as u8, (r2 & 0xFF) as u8, m2, v2]
}

const fn mode_entry_4_reg(mode: u32, r0: u32, m0: u8, v0: u8, r1: u32, m1: u8, v1: u8, r2: u32, m2: u8, v2: u8, r3: u32, m3: u8, v3: u8) -> [u8; 19] {
    [(mode << 8) as u8, (mode & 0xFF) as u8, 4, (r0 << 8) as u8, (r0 & 0xFF) as u8, m0, v0, (r1 << 8) as u8, (r1 & 0xFF) as u8, m1, v1, (r2 << 8) as u8, (r2 & 0xFF) as u8, m2, v2, (r3 << 8) as u8, (r3 & 0xFF) as u8, m3, v3]
}

const fn mode_entry_5_reg(mode: u32, r0: u32, m0: u8, v0: u8, r1: u32, m1: u8, v1: u8, r2: u32, m2: u8, v2: u8, r3: u32, m3: u8, v3: u8, r4: u32, m4: u8, v4: u8) -> [u8; 23] {
    [(mode << 8) as u8, (mode & 0xFF) as u8, 5, (r0 << 8) as u8, (r0 & 0xFF) as u8, m0, v0, (r1 << 8) as u8, (r1 & 0xFF) as u8, m1, v1, (r2 << 8) as u8, (r2 & 0xFF) as u8, m2, v2, (r3 << 8) as u8, (r3 & 0xFF) as u8, m3, v3, (r4 << 8) as u8, (r4 & 0xFF) as u8, m4, v4]
}

const fn mode_entry_6_reg(mode: u32, r0: u32, m0: u8, v0: u8, r1: u32, m1: u8, v1: u8, r2: u32, m2: u8, v2: u8, r3: u32, m3: u8, v3: u8, r4: u32, m4: u8, v4: u8, r5: u32, m5: u8, v5: u8) -> [u8; 27] {
    [(mode << 8) as u8, (mode & 0xFF) as u8, 6, (r0 << 8) as u8, (r0 & 0xFF) as u8, m0, v0, (r1 << 8) as u8, (r1 & 0xFF) as u8, m1, v1, (r2 << 8) as u8, (r2 & 0xFF) as u8, m2, v2, (r3 << 8) as u8, (r3 & 0xFF) as u8, m3, v3, (r4 << 8) as u8, (r4 & 0xFF) as u8, m4, v4, (r5 << 8) as u8, (r5 & 0xFF) as u8, m5, v5]
}

const fn mode_entry_7_reg(mode: u32, r0: u32, m0: u8, v0: u8, r1: u32, m1: u8, v1: u8, r2: u32, m2: u8, v2: u8, r3: u32, m3: u8, v3: u8, r4: u32, m4: u8, v4: u8, r5: u32, m5: u8, v5: u8, r6: u32, m6: u8, v6: u8) -> [u8; 31] {
    [(mode << 8) as u8, (mode & 0xFF) as u8, 7, (r0 << 8) as u8, (r0 & 0xFF) as u8, m0, v0, (r1 << 8) as u8, (r1 & 0xFF) as u8, m1, v1, (r2 << 8) as u8, (r2 & 0xFF) as u8, m2, v2, (r3 << 8) as u8, (r3 & 0xFF) as u8, m3, v3, (r4 << 8) as u8, (r4 & 0xFF) as u8, m4, v4, (r5 << 8) as u8, (r5 & 0xFF) as u8, m5, v5, (r6 << 8) as u8, (r6 & 0xFF) as u8, m6, v6]
}

const fn mode_entry_8_reg(mode: u32, r0: u32, m0: u8, v0: u8, r1: u32, m1: u8, v1: u8, r2: u32, m2: u8, v2: u8, r3: u32, m3: u8, v3: u8, r4: u32, m4: u8, v4: u8, r5: u32, m5: u8, v5: u8, r6: u32, m6: u8, v6: u8, r7: u32, m7: u8, v7: u8) -> [u8; 35] {
    [(mode << 8) as u8, (mode & 0xFF) as u8, 8, (r0 << 8) as u8, (r0 & 0xFF) as u8, m0, v0, (r1 << 8) as u8, (r1 & 0xFF) as u8, m1, v1, (r2 << 8) as u8, (r2 & 0xFF) as u8, m2, v2, (r3 << 8) as u8, (r3 & 0xFF) as u8, m3, v3, (r4 << 8) as u8, (r4 & 0xFF) as u8, m4, v4, (r5 << 8) as u8, (r5 & 0xFF) as u8, m5, v5, (r6 << 8) as u8, (r6 & 0xFF) as u8, m6, v6, (r7 << 8) as u8, (r7 & 0xFF) as u8, m7, v7]
}

const fn mode_entry_9_reg(mode: u32, r0: u32, m0: u8, v0: u8, r1: u32, m1: u8, v1: u8, r2: u32, m2: u8, v2: u8, r3: u32, m3: u8, v3: u8, r4: u32, m4: u8, v4: u8, r5: u32, m5: u8, v5: u8, r6: u32, m6: u8, v6: u8, r7: u32, m7: u8, v7: u8, r8: u32, m8: u8, v8: u8) -> [u8; 39] {
    [(mode << 8) as u8, (mode & 0xFF) as u8, 9, (r0 << 8) as u8, (r0 & 0xFF) as u8, m0, v0, (r1 << 8) as u8, (r1 & 0xFF) as u8, m1, v1, (r2 << 8) as u8, (r2 & 0xFF) as u8, m2, v2, (r3 << 8) as u8, (r3 & 0xFF) as u8, m3, v3, (r4 << 8) as u8, (r4 & 0xFF) as u8, m4, v4, (r5 << 8) as u8, (r5 & 0xFF) as u8, m5, v5, (r6 << 8) as u8, (r6 & 0xFF) as u8, m6, v6, (r7 << 8) as u8, (r7 & 0xFF) as u8, m7, v7, (r8 << 8) as u8, (r8 & 0xFF) as u8, m8, v8]
}

const fn mode_entry_10_reg(mode: u32, r0: u32, m0: u8, v0: u8, r1: u32, m1: u8, v1: u8, r2: u32, m2: u8, v2: u8, r3: u32, m3: u8, v3: u8, r4: u32, m4: u8, v4: u8, r5: u32, m5: u8, v5: u8, r6: u32, m6: u8, v6: u8, r7: u32, m7: u8, v7: u8, r8: u32, m8: u8, v8: u8, r9: u32, m9: u8, v9: u8) -> [u8; 43] {
    [(mode << 8) as u8, (mode & 0xFF) as u8, 10, (r0 << 8) as u8, (r0 & 0xFF) as u8, m0, v0, (r1 << 8) as u8, (r1 & 0xFF) as u8, m1, v1, (r2 << 8) as u8, (r2 & 0xFF) as u8, m2, v2, (r3 << 8) as u8, (r3 & 0xFF) as u8, m3, v3, (r4 << 8) as u8, (r4 & 0xFF) as u8, m4, v4, (r5 << 8) as u8, (r5 & 0xFF) as u8, m5, v5, (r6 << 8) as u8, (r6 & 0xFF) as u8, m6, v6, (r7 << 8) as u8, (r7 & 0xFF) as u8, m7, v7, (r8 << 8) as u8, (r8 & 0xFF) as u8, m8, v8, (r9 << 8) as u8, (r9 & 0xFF) as u8, m9, v9]
}

const fn mode_entry_11_reg(mode: u32, r0: u32, m0: u8, v0: u8, r1: u32, m1: u8, v1: u8, r2: u32, m2: u8, v2: u8, r3: u32, m3: u8, v3: u8, r4: u32, m4: u8, v4: u8, r5: u32, m5: u8, v5: u8, r6: u32, m6: u8, v6: u8, r7: u32, m7: u8, v7: u8, r8: u32, m8: u8, v8: u8, r9: u32, m9: u8, v9: u8, r10: u32, m10: u8, v10: u8) -> [u8; 47] {
    [(mode << 8) as u8, (mode & 0xFF) as u8, 11, (r0 << 8) as u8, (r0 & 0xFF) as u8, m0, v0, (r1 << 8) as u8, (r1 & 0xFF) as u8, m1, v1, (r2 << 8) as u8, (r2 & 0xFF) as u8, m2, v2, (r3 << 8) as u8, (r3 & 0xFF) as u8, m3, v3, (r4 << 8) as u8, (r4 & 0xFF) as u8, m4, v4, (r5 << 8) as u8, (r5 & 0xFF) as u8, m5, v5, (r6 << 8) as u8, (r6 & 0xFF) as u8, m6, v6, (r7 << 8) as u8, (r7 & 0xFF) as u8, m7, v7, (r8 << 8) as u8, (r8 & 0xFF) as u8, m8, v8, (r9 << 8) as u8, (r9 & 0xFF) as u8, m9, v9, (r10 << 8) as u8, (r10 & 0xFF) as u8, m10, v10]
}

const fn mode_entry_12_reg(mode: u32, r0: u32, m0: u8, v0: u8, r1: u32, m1: u8, v1: u8, r2: u32, m2: u8, v2: u8, r3: u32, m3: u8, v3: u8, r4: u32, m4: u8, v4: u8, r5: u32, m5: u8, v5: u8, r6: u32, m6: u8, v6: u8, r7: u32, m7: u8, v7: u8, r8: u32, m8: u8, v8: u8, r9: u32, m9: u8, v9: u8, r10: u32, m10: u8, v10: u8, r11: u32, m11: u8, v11: u8) -> [u8; 51] {
    [(mode << 8) as u8, (mode & 0xFF) as u8, 12, (r0 << 8) as u8, (r0 & 0xFF) as u8, m0, v0, (r1 << 8) as u8, (r1 & 0xFF) as u8, m1, v1, (r2 << 8) as u8, (r2 & 0xFF) as u8, m2, v2, (r3 << 8) as u8, (r3 & 0xFF) as u8, m3, v3, (r4 << 8) as u8, (r4 & 0xFF) as u8, m4, v4, (r5 << 8) as u8, (r5 & 0xFF) as u8, m5, v5, (r6 << 8) as u8, (r6 & 0xFF) as u8, m6, v6, (r7 << 8) as u8, (r7 & 0xFF) as u8, m7, v7, (r8 << 8) as u8, (r8 & 0xFF) as u8, m8, v8, (r9 << 8) as u8, (r9 & 0xFF) as u8, m9, v9, (r10 << 8) as u8, (r10 & 0xFF) as u8, m10, v10, (r11 << 8) as u8, (r11 & 0xFF) as u8, m11, v11]
}

const fn mode_entry_13_reg(mode: u32, r0: u32, m0: u8, v0: u8, r1: u32, m1: u8, v1: u8, r2: u32, m2: u8, v2: u8, r3: u32, m3: u8, v3: u8, r4: u32, m4: u8, v4: u8, r5: u32, m5: u8, v5: u8, r6: u32, m6: u8, v6: u8, r7: u32, m7: u8, v7: u8, r8: u32, m8: u8, v8: u8, r9: u32, m9: u8, v9: u8, r10: u32, m10: u8, v10: u8, r11: u32, m11: u8, v11: u8, r12: u32, m12: u8, v12: u8) -> [u8; 55] {
    [(mode << 8) as u8, (mode & 0xFF) as u8, 13, (r0 << 8) as u8, (r0 & 0xFF) as u8, m0, v0, (r1 << 8) as u8, (r1 & 0xFF) as u8, m1, v1, (r2 << 8) as u8, (r2 & 0xFF) as u8, m2, v2, (r3 << 8) as u8, (r3 & 0xFF) as u8, m3, v3, (r4 << 8) as u8, (r4 & 0xFF) as u8, m4, v4, (r5 << 8) as u8, (r5 & 0xFF) as u8, m5, v5, (r6 << 8) as u8, (r6 & 0xFF) as u8, m6, v6, (r7 << 8) as u8, (r7 & 0xFF) as u8, m7, v7, (r8 << 8) as u8, (r8 & 0xFF) as u8, m8, v8, (r9 << 8) as u8, (r9 & 0xFF) as u8, m9, v9, (r10 << 8) as u8, (r10 & 0xFF) as u8, m10, v10, (r11 << 8) as u8, (r11 & 0xFF) as u8, m11, v11, (r12 << 8) as u8, (r12 & 0xFF) as u8, m12, v12]
}

const AM_MOD_DRIVER_LEVEL_DEFAULT: u8 = 0xb9;

const ANALOG_CONFIG_LUT_SIZE: u32 = 87;     /* Maximum number of Configuration IDs in the Loop Up Table     */
const ANALOG_CONFIG_LUT_NOT_FOUND: u32 = 0xFF;   /* Index value indicating no Configuration IDs found            */

const ANALOG_CONFIG_TBL_SIZE: u32 = 1024;   /* Maximum number of Register-Mask-Value in the Setting List    */


const ANALOG_CONFIG_POLL_LISTEN_MODE_MASK: u32 = 0x8000; /* Mask bit of Poll Mode in Analog Configuration ID             */
const ANALOG_CONFIG_TECH_MASK: u32 = 0x7F00; /* Mask bits for Technology in Analog Configuration ID          */
const ANALOG_CONFIG_BITRATE_MASK: u32 = 0x00F0; /* Mask bits for Bit rate in Analog Configuration ID            */
const ANALOG_CONFIG_DIRECTION_MASK: u32 = 0x0003; /* Mask bits for Direction in Analog Configuration ID           */
const ANALOG_CONFIG_CHIP_SPECIFIC_MASK: u32 = 0x00FF; /* Mask bits for Chip Specific Technology                       */

const ANALOG_CONFIG_POLL_LISTEN_MODE_SHIFT: u32 = 15;     /* Shift value of Poll Mode in Analog Configuration ID          */
const ANALOG_CONFIG_TECH_SHIFT: u32 = 8;      /* Shift value for Technology in Analog Configuration ID        */
const ANALOG_CONFIG_BITRATE_SHIFT: u32 = 4;      /* Shift value for Technology in Analog Configuration ID        */
const ANALOG_CONFIG_DIRECTION_SHIFT: u32 = 0;      /* Shift value for Direction in Analog Configuration ID         */

const ANALOG_CONFIG_POLL: u32 = 0x0000; /* Poll Mode bit setting in Analog Configuration ID             */
const ANALOG_CONFIG_LISTEN: u32 = 0x8000; /* Listen Mode bit setting in Analog Configuration ID           */

const ANALOG_CONFIG_TECH_CHIP: u32 = 0x0000; /* Chip-Specific bit setting in Analog Configuration ID         */
const ANALOG_CONFIG_TECH_NFCA: u32 = 0x0100; /* NFC-A Technology bits setting in Analog Configuration ID     */
const ANALOG_CONFIG_TECH_NFCB: u32 = 0x0200; /* NFC-B Technology bits setting in Analog Configuration ID     */
const ANALOG_CONFIG_TECH_NFCF: u32 = 0x0400; /* NFC-F Technology bits setting in Analog Configuration ID     */
const ANALOG_CONFIG_TECH_AP2P: u32 = 0x0800; /* AP2P Technology bits setting in Analog Configuration ID      */
const ANALOG_CONFIG_TECH_NFCV: u32 = 0x1000; /* NFC-V Technology bits setting in Analog Configuration ID     */
const ANALOG_CONFIG_TECH_RFU: u32 = 0x2000; /* RFU for Technology bits */

const ANALOG_CONFIG_BITRATE_COMMON: u32 = 0x0000; /* Common settings for all bit rates in Analog Configuration ID */
const ANALOG_CONFIG_BITRATE_106: u32 = 0x0010; /* 106kbits/s settings in Analog Configuration ID               */
const ANALOG_CONFIG_BITRATE_212: u32 = 0x0020; /* 212kbits/s settings in Analog Configuration ID               */
const ANALOG_CONFIG_BITRATE_424: u32 = 0x0030; /* 424kbits/s settings in Analog Configuration ID               */
const ANALOG_CONFIG_BITRATE_848: u32 = 0x0040; /* 848kbits/s settings in Analog Configuration ID               */
const ANALOG_CONFIG_BITRATE_1695: u32 = 0x0050; /* 1695kbits/s settings in Analog Configuration ID              */
const ANALOG_CONFIG_BITRATE_3390: u32 = 0x0060; /* 3390kbits/s settings in Analog Configuration ID              */
const ANALOG_CONFIG_BITRATE_6780: u32 = 0x0070; /* 6780kbits/s settings in Analog Configuration ID              */
const ANALOG_CONFIG_BITRATE_1OF4: u32 = 0x00C0; /* 1 out of 4 for NFC-V setting in Analog Configuration ID      */
const ANALOG_CONFIG_BITRATE_1OF256: u32 = 0x00D0; /* 1 out of 256 for NFC-V setting in Analog Configuration ID    */

const ANALOG_CONFIG_NO_DIRECTION: u32 = 0x0000; /* No direction setting in Analog Conf ID (Chip Specific only)  */
const ANALOG_CONFIG_TX: u32 = 0x0001; /* Transmission bit setting in Analog Configuration ID          */
const ANALOG_CONFIG_RX: u32 = 0x0002; /* Reception bit setting in Analog Configuration ID             */
const ANALOG_CONFIG_ANTICOL: u32 = 0x0003;  /* Anticollision setting in Analog Configuration ID             */

const ANALOG_CONFIG_CHIP_INIT: u32 = 0x0000;  /* Chip-Specific event: Startup;Reset;Initialize                */
const ANALOG_CONFIG_CHIP_DEINIT: u32 = 0x0001;  /* Chip-Specific event: Deinitialize                            */
const ANALOG_CONFIG_CHIP_FIELD_ON: u32 = 0x0002;  /* Chip-Specific event: Field On                                */
const ANALOG_CONFIG_CHIP_FIELD_OFF: u32 = 0x0003;  /* Chip-Specific event: Field Off                               */
const ANALOG_CONFIG_CHIP_WAKEUP_ON: u32 = 0x0004;  /* Chip-Specific event: Wake-up On                              */
const ANALOG_CONFIG_CHIP_WAKEUP_OFF: u32 = 0x0005;  /* Chip-Specific event: Wake-up Off                             */
const ANALOG_CONFIG_CHIP_LISTEN_ON: u32 = 0x0006;  /* Chip-Specific event: Listen On                               */
const ANALOG_CONFIG_CHIP_LISTEN_OFF: u32 = 0x0007;  /* Chip-Specific event: Listen Off                              */
const ANALOG_CONFIG_CHIP_POLL_COMMON: u32 = 0x0008;  /* Chip-Specific event: Poll common                             */
const ANALOG_CONFIG_CHIP_LISTEN_COMMON: u32 = 0x0009;  /* Chip-Specific event: Listen common                           */

const ANALOG_CONFIG_UPDATE_LAST: u32 = 0x00;   /* Value indicating Last configuration set during update        */
const ANALOG_CONFIG_UPDATE_MORE: u32 = 0x01;   /* Value indicating More configuration set coming during update */

//****** Default Analog Configuration for Chip-Specific Reset. ******/
const RESET_INIT: [u8; 43] = mode_entry_10_reg(
    ANALOG_CONFIG_TECH_CHIP | ANALOG_CONFIG_CHIP_INIT,
    Register::OperationControl as u32, 0x30, 0x10,  //Default to AM
    Register::IOConfiguration1 as u32, 0x06, 0x06,  //MCUCLK: HF clk off
    Register::IOConfiguration1 as u32, IOConfiguration1Bits::MaskOutCl as u8 | IOConfiguration1Bits::LfClkOff as u8, 0x07, // MCUCLK: LF clk off
    Register::IOConfiguration2 as u32, 0x18, 0x18, // pull downs
    Register::ReceiverConfiguration4 as u32, ReceiverConfiguration4Mask::MaskRg2Pm as u8, 0x1 << ReceiverConfiguration4Mask::ShiftRg2Pm as u8, //increase digitizer windows for PM
    Register::AnntenaCalibrationTarget as u32, 0xFF, 0x80, // 90 deg,
    Register::AnntenaCalibrationControl as u32, 0xF8, 0x00, // trim value from calibrate antenna
    Register::AMModulationDepthControl as u32, AMModulationDepthControlConstans::AmS as u8, AMModulationDepthControlConstans::AmS as u8, // AM modulated level is defined by RFO AM Modulated Level Def Reg, fixed setting, no automatic adjustment
    Register::ExternalFieldDetectorThreshold as u32, EXT_FIELD_DET_TRG_MASK, ExternalFieldDetectorThresholdTrgVoltage::Trg75mV as u8,
    Register::ExternalFieldDetectorThreshold as u32, EXT_FIELD_DET_RFE_MASK, ExternalFieldDetectorThresholdRfeVoltage::Rfe75mV as u8,
);

//****** Default Analog Configuration for Poll NFC-A Rx. ******/
const NFCA_TX_COMMON: [u8; 7] = mode_entry_1_reg(
    ANALOG_CONFIG_POLL | ANALOG_CONFIG_TECH_NFCA | ANALOG_CONFIG_BITRATE_COMMON | ANALOG_CONFIG_TX,
    Register::RFOAMModulationLevelDefinition as u32, 0xff, 0xf0, // Used for 848 TX: very high AM to keep wave shapes
);
const NFCA_TX_106: [u8; 7] = mode_entry_1_reg(
    ANALOG_CONFIG_POLL | ANALOG_CONFIG_TECH_NFCA | ANALOG_CONFIG_BITRATE_106 | ANALOG_CONFIG_TX,
    Register::AuxDefinition as u32, AuxDefinitionBits::TrAm as u8, 0x00, // OOK
);
const NFCA_TX_212: [u8; 7] = mode_entry_1_reg(
    ANALOG_CONFIG_POLL | ANALOG_CONFIG_TECH_NFCA | ANALOG_CONFIG_BITRATE_212 | ANALOG_CONFIG_TX,
    Register::AuxDefinition as u32, AuxDefinitionBits::TrAm as u8, 0x00, // OOK
);
const NFCA_TX_424: [u8; 7] = mode_entry_1_reg(
    ANALOG_CONFIG_POLL | ANALOG_CONFIG_TECH_NFCA | ANALOG_CONFIG_BITRATE_424 | ANALOG_CONFIG_TX,
    Register::AuxDefinition as u32, AuxDefinitionBits::TrAm as u8, 0x00, // OOK
);
const NFCA_TX_848: [u8; 7] = mode_entry_1_reg(
    ANALOG_CONFIG_POLL | ANALOG_CONFIG_TECH_NFCA | ANALOG_CONFIG_BITRATE_848 | ANALOG_CONFIG_TX,
    Register::AuxDefinition as u32, AuxDefinitionBits::TrAm as u8, 0x00, // OOK
);
const NFCA_TX_848_AUX: [u8; 11] = mode_entry_2_reg(
    ANALOG_CONFIG_POLL | ANALOG_CONFIG_TECH_NFCA | ANALOG_CONFIG_BITRATE_848 | ANALOG_CONFIG_TX,
    Register::AuxDefinition as u32, AuxDefinitionBits::TrAm as u8, AuxDefinitionBits::TrAm as u8, // AM
    Register::RFOAMModulationLevelDefinition as u32, 0xff, 0x00, // Used for 848 TX: very high AM to keep wave shapes
);

//****** Default Analog Configuration for Poll NFC-A Rx. ******/
const NFCA_RX_COMMON: [u8; 15] = mode_entry_3_reg(
    ANALOG_CONFIG_POLL | ANALOG_CONFIG_TECH_NFCA | ANALOG_CONFIG_BITRATE_COMMON | ANALOG_CONFIG_RX,
    Register::ReceiverConfiguration3 as u32, 0xff, 0x18,
    Register::ReceiverConfiguration4 as u32, ReceiverConfiguration4Mask::MaskRg2Am as u8, 0x2 << ReceiverConfiguration4Mask::ShiftRg2Am as u8, //increase digitizer windows for AM
    Register::AuxDefinition as u32, AuxDefinitionBits::RxTol as u8, 0x00, //rx_tol off
);
const NFCA_RX_106: [u8; 7] = mode_entry_1_reg(
    ANALOG_CONFIG_POLL | ANALOG_CONFIG_TECH_NFCA | ANALOG_CONFIG_BITRATE_106 | ANALOG_CONFIG_RX,
    Register::ReceiverConfiguration1 as u32, 0x7f, 0x00,
);
const NFCA_RX_212: [u8; 7] = mode_entry_1_reg(
    ANALOG_CONFIG_POLL | ANALOG_CONFIG_TECH_NFCA | ANALOG_CONFIG_BITRATE_212 | ANALOG_CONFIG_RX,
    Register::ReceiverConfiguration1 as u32, 0x7f, 0x04,
);
const NFCA_RX_424: [u8; 7] = mode_entry_1_reg(
    ANALOG_CONFIG_POLL | ANALOG_CONFIG_TECH_NFCA | ANALOG_CONFIG_BITRATE_424 | ANALOG_CONFIG_RX,
    Register::ReceiverConfiguration1 as u32, 0x7f, 0x22,
);
const NFCA_RX_848: [u8; 7] = mode_entry_1_reg(
    ANALOG_CONFIG_POLL | ANALOG_CONFIG_TECH_NFCA | ANALOG_CONFIG_BITRATE_848 | ANALOG_CONFIG_RX,
    Register::ReceiverConfiguration1 as u32, 0x7f, 0x22,
);

//****** Default Analog Configuration for Poll NFC-B Tx. ******/
const NFCB_TX_COMMON: [u8; 11] = mode_entry_2_reg(
    ANALOG_CONFIG_POLL | ANALOG_CONFIG_TECH_NFCB | ANALOG_CONFIG_BITRATE_COMMON | ANALOG_CONFIG_TX,
    Register::AuxDefinition as u32, AuxDefinitionBits::TrAm as u8, AuxDefinitionBits::TrAm as u8, // AM
    Register::RFOAMModulationLevelDefinition as u32, 0xff, AM_MOD_DRIVER_LEVEL_DEFAULT, //Fixed driver for AM level: -14%
);

//****** Default Analog Configuration for Poll NFC-B Rx. ******/
const NFCB_RX_COMMON: [u8; 15] = mode_entry_3_reg(
    ANALOG_CONFIG_POLL | ANALOG_CONFIG_TECH_NFCB | ANALOG_CONFIG_BITRATE_COMMON | ANALOG_CONFIG_RX,
    Register::ReceiverConfiguration3 as u32, 0xff, 0x18,
    Register::ReceiverConfiguration4 as u32, ReceiverConfiguration4Mask::MaskRg2Am as u8, 0x2 << ReceiverConfiguration4Mask::ShiftRg2Am as u8, //increase digitizer windows for AM
    Register::AuxDefinition as u32, AuxDefinitionBits::RxTol as u8, 0x00, //rx_tol off
);
const NFCB_RX_106: [u8; 7] = mode_entry_1_reg(
    ANALOG_CONFIG_POLL | ANALOG_CONFIG_TECH_NFCB | ANALOG_CONFIG_BITRATE_106 | ANALOG_CONFIG_RX,
    Register::ReceiverConfiguration1 as u32, 0x7f, 0x00,
);
const NFCB_RX_212: [u8; 7] = mode_entry_1_reg(
    ANALOG_CONFIG_POLL | ANALOG_CONFIG_TECH_NFCB | ANALOG_CONFIG_BITRATE_212 | ANALOG_CONFIG_RX,
    Register::ReceiverConfiguration1 as u32, 0x7f, 0x04,
);
const NFCB_RX_424: [u8; 7] = mode_entry_1_reg(
    ANALOG_CONFIG_POLL | ANALOG_CONFIG_TECH_NFCB | ANALOG_CONFIG_BITRATE_424 | ANALOG_CONFIG_RX,
    Register::ReceiverConfiguration1 as u32, 0x7f, 0x22,
);
const NFCB_RX_848: [u8; 7] = mode_entry_1_reg(
    ANALOG_CONFIG_POLL | ANALOG_CONFIG_TECH_NFCB | ANALOG_CONFIG_BITRATE_848 | ANALOG_CONFIG_RX,
    Register::ReceiverConfiguration1 as u32, 0x7f, 0x22,
);

//****** Default Analog Configuration for Poll NFC-F Tx. ******/
const NFCF_TX_COMMON: [u8; 11] = mode_entry_2_reg(
    ANALOG_CONFIG_POLL | ANALOG_CONFIG_TECH_NFCF | ANALOG_CONFIG_BITRATE_COMMON | ANALOG_CONFIG_TX,
    Register::AuxDefinition as u32, AuxDefinitionBits::TrAm as u8, AuxDefinitionBits::TrAm as u8, // AM
    Register::RFOAMModulationLevelDefinition as u32, 0xff, AM_MOD_DRIVER_LEVEL_DEFAULT, //Fixed driver for AM level: -14%
);

//****** Default Analog Configuration for Poll NFC-F Rx. ******/
const NFCF_RX_COMMON: [u8; 15] = mode_entry_3_reg(
    ANALOG_CONFIG_POLL | ANALOG_CONFIG_TECH_NFCF | ANALOG_CONFIG_BITRATE_COMMON | ANALOG_CONFIG_RX,
    Register::ReceiverConfiguration3 as u32, 0xff, 0x18,
    Register::ReceiverConfiguration4 as u32, ReceiverConfiguration4Mask::MaskRg2Am as u8, 0x1 << ReceiverConfiguration4Mask::ShiftRg2Am as u8, //increase digitizer windows for AM
    Register::AuxDefinition as u32, AuxDefinitionBits::RxTol as u8, AuxDefinitionBits::RxTol as u8, //rx_tol On as default
);
const NFCF_RX_212: [u8; 7] = mode_entry_1_reg(
    ANALOG_CONFIG_POLL | ANALOG_CONFIG_TECH_NFCF | ANALOG_CONFIG_BITRATE_212 | ANALOG_CONFIG_RX,
    Register::ReceiverConfiguration1 as u32, 0x7f, 0x13, /* dev. from data sheet: lp 300kKz */
);
const NFCF_RX_424: [u8; 7] = mode_entry_1_reg(
    ANALOG_CONFIG_POLL | ANALOG_CONFIG_TECH_NFCF | ANALOG_CONFIG_BITRATE_424 | ANALOG_CONFIG_RX,
    Register::ReceiverConfiguration1 as u32, 0x7f, 0x0b, /* dev. from data sheet: lp 600kKz */
);

//****** Default Analog Configuration for Poll NFC-V Tx. ******/
const NFCV_TX_COMMON: [u8; 7] = mode_entry_1_reg(
    ANALOG_CONFIG_POLL | ANALOG_CONFIG_TECH_NFCV | ANALOG_CONFIG_BITRATE_COMMON | ANALOG_CONFIG_TX,
    Register::AuxDefinition as u32, AuxDefinitionBits::TrAm as u8, 0x00, // AM
);

//****** Default Analog Configuration for Poll NFC-V Rx. ******/
const NFCV_RX_COMMON: [u8; 19] = mode_entry_4_reg(
    ANALOG_CONFIG_POLL | ANALOG_CONFIG_TECH_NFCV | ANALOG_CONFIG_BITRATE_COMMON | ANALOG_CONFIG_RX,
    Register::ReceiverConfiguration1 as u32, 0x7f, 0x0c, /* use filter settings from table 9: "Recommended for 424/484 kHz sub-carrier" */
    Register::ReceiverConfiguration3 as u32, 0xff, 0x18,
    Register::ReceiverConfiguration4 as u32, ReceiverConfiguration4Mask::MaskRg2Am as u8, 0x1 << ReceiverConfiguration4Mask::ShiftRg2Am as u8, //increase digitizer windows for AM
    Register::AuxDefinition as u32, AuxDefinitionBits::RxTol as u8, AuxDefinitionBits::RxTol as u8, //rx_tol On as default
);

//****** Default Analog Configuration for Poll AP2P Tx. ******/
const AP2P_TX_COMMON: [u8; 7] = mode_entry_1_reg(
    ANALOG_CONFIG_POLL | ANALOG_CONFIG_TECH_AP2P | ANALOG_CONFIG_BITRATE_COMMON | ANALOG_CONFIG_TX,
    Register::RFOAMModulationLevelDefinition as u32, 0xff, AM_MOD_DRIVER_LEVEL_DEFAULT,
);
const AP2P_TX_106: [u8; 7] = mode_entry_1_reg(
    ANALOG_CONFIG_POLL | ANALOG_CONFIG_TECH_AP2P | ANALOG_CONFIG_BITRATE_106 | ANALOG_CONFIG_TX,
    Register::AuxDefinition as u32, AuxDefinitionBits::TrAm as u8, 0x00, // OOK
);
const AP2P_TX_212: [u8; 11] = mode_entry_2_reg(
    ANALOG_CONFIG_POLL | ANALOG_CONFIG_TECH_AP2P | ANALOG_CONFIG_BITRATE_212 | ANALOG_CONFIG_TX,
    Register::AuxDefinition as u32, AuxDefinitionBits::TrAm as u8, AuxDefinitionBits::TrAm as u8, // AM
    Register::RFOAMModulationLevelDefinition as u32, 0xff, AM_MOD_DRIVER_LEVEL_DEFAULT, //Fixed driver for AM level: -14%
);
const AP2P_TX_424: [u8; 11] = mode_entry_2_reg(
    ANALOG_CONFIG_POLL | ANALOG_CONFIG_TECH_AP2P | ANALOG_CONFIG_BITRATE_424 | ANALOG_CONFIG_TX,
    Register::AuxDefinition as u32, AuxDefinitionBits::TrAm as u8, AuxDefinitionBits::TrAm as u8, // AM
    Register::RFOAMModulationLevelDefinition as u32, 0xff, AM_MOD_DRIVER_LEVEL_DEFAULT, //Fixed driver for AM level: -14%
);

//****** Default Analog Configuration for Poll AP2P Rx. ******/
const AP2P_RX_TECH: [u8; 19] = mode_entry_4_reg(
    ANALOG_CONFIG_TECH_CHIP | ANALOG_CONFIG_CHIP_LISTEN_ON,
    Register::ReceiverConfiguration1 as u32, 0x7f, 0x45,
    Register::ReceiverConfiguration3 as u32, ReceiverConfiguration3Bits::Lim as u8 | ReceiverConfiguration3Bits::RgNfc as u8, ReceiverConfiguration3Bits::Lim as u8 | ReceiverConfiguration3Bits::RgNfc as u8,
    Register::AuxDefinition as u32, AuxDefinitionBits::RxTol as u8, AuxDefinitionBits::RxTol as u8, //rx_tol On as default
    Register::ReceiverConfiguration4 as u32, ReceiverConfiguration4Mask::MaskRg2Am as u8, 0x1 << ReceiverConfiguration4Mask::ShiftRg2Am as u8, //increase digitizer windows for AM
);
const AP2P_RX_COMMON: [u8; 19] = mode_entry_4_reg(
    ANALOG_CONFIG_POLL | ANALOG_CONFIG_TECH_AP2P | ANALOG_CONFIG_BITRATE_COMMON | ANALOG_CONFIG_RX,
    Register::ReceiverConfiguration1 as u32, 0x7f, 0x45,
    Register::ReceiverConfiguration3 as u32, ReceiverConfiguration3Bits::Lim as u8 | ReceiverConfiguration3Bits::RgNfc as u8, ReceiverConfiguration3Bits::Lim as u8 | ReceiverConfiguration3Bits::RgNfc as u8,
    Register::AuxDefinition as u32, AuxDefinitionBits::RxTol as u8, AuxDefinitionBits::RxTol as u8, //rx_tol On as default
    Register::ReceiverConfiguration4 as u32, ReceiverConfiguration4Mask::MaskRg2Am as u8, 0x1 << ReceiverConfiguration4Mask::ShiftRg2Am as u8, //increase digitizer windows for AM
);
const AP2P_RX_106: [u8; 7] = mode_entry_1_reg(
    ANALOG_CONFIG_POLL | ANALOG_CONFIG_TECH_AP2P | ANALOG_CONFIG_BITRATE_106 | ANALOG_CONFIG_RX,
    Register::ReceiverConfiguration3 as u32, ReceiverConfiguration3Mask::MaskRg1Am as u8, 0xc0,
);
const AP2P_RX_212: [u8; 7] = mode_entry_1_reg(
    ANALOG_CONFIG_POLL | ANALOG_CONFIG_TECH_AP2P | ANALOG_CONFIG_BITRATE_212 | ANALOG_CONFIG_RX,
    Register::ReceiverConfiguration3 as u32, ReceiverConfiguration3Mask::MaskRg1Am as u8, 0x00,
);
const AP2P_RX_424: [u8; 7] = mode_entry_1_reg(
    ANALOG_CONFIG_POLL | ANALOG_CONFIG_TECH_AP2P | ANALOG_CONFIG_BITRATE_424 | ANALOG_CONFIG_RX,
    Register::ReceiverConfiguration3 as u32, ReceiverConfiguration3Mask::MaskRg1Am as u8, 0x00,
);

//****** Default Analog Configuration for Listen AP2P Tx. ******/
const AP2P_LTX_COMMON: [u8; 7] = mode_entry_1_reg(
    ANALOG_CONFIG_LISTEN | ANALOG_CONFIG_TECH_AP2P | ANALOG_CONFIG_BITRATE_COMMON | ANALOG_CONFIG_TX,
    Register::RFOAMModulationLevelDefinition as u32, 0xff, AM_MOD_DRIVER_LEVEL_DEFAULT, //Fixed driver for AM level: -14%
);
const AP2P_LTX_106: [u8; 7] = mode_entry_1_reg(
    ANALOG_CONFIG_LISTEN | ANALOG_CONFIG_TECH_AP2P | ANALOG_CONFIG_BITRATE_106 | ANALOG_CONFIG_TX,
    Register::AuxDefinition as u32, AuxDefinitionBits::TrAm as u8, 0x00, // OOK
);
const AP2P_LTX_212: [u8; 7] = mode_entry_1_reg(
    ANALOG_CONFIG_LISTEN | ANALOG_CONFIG_TECH_AP2P | ANALOG_CONFIG_BITRATE_212 | ANALOG_CONFIG_TX,
    Register::AuxDefinition as u32, AuxDefinitionBits::TrAm as u8, AuxDefinitionBits::TrAm as u8, // AM
);
const AP2P_LTX_424: [u8; 7] = mode_entry_1_reg(
    ANALOG_CONFIG_LISTEN | ANALOG_CONFIG_TECH_AP2P | ANALOG_CONFIG_BITRATE_424 | ANALOG_CONFIG_TX,
    Register::AuxDefinition as u32, AuxDefinitionBits::TrAm as u8, AuxDefinitionBits::TrAm as u8, // AM
);

//****** Default Analog Configuration for Listen AP2P Rx. ******/
const AP2P_LRX_COMMON: [u8; 15] = mode_entry_3_reg(
    ANALOG_CONFIG_LISTEN | ANALOG_CONFIG_TECH_AP2P | ANALOG_CONFIG_BITRATE_COMMON | ANALOG_CONFIG_RX,
    Register::ReceiverConfiguration1 as u32, 0x7f, 0x45,
    Register::ReceiverConfiguration3 as u32, ReceiverConfiguration3Bits::Lim as u8 | ReceiverConfiguration3Bits::RgNfc as u8, ReceiverConfiguration3Bits::Lim as u8 | ReceiverConfiguration3Bits::RgNfc as u8,
    Register::ReceiverConfiguration4 as u32, ReceiverConfiguration4Mask::MaskRg2Am as u8, 0x1 << ReceiverConfiguration4Mask::ShiftRg2Am as u8, //increase digitizer windows for AM
);
const AP2P_LRX_106: [u8; 7] = mode_entry_1_reg(
    ANALOG_CONFIG_LISTEN | ANALOG_CONFIG_TECH_AP2P | ANALOG_CONFIG_BITRATE_106 | ANALOG_CONFIG_RX,
    Register::ReceiverConfiguration3 as u32, ReceiverConfiguration3Mask::MaskRg1Am as u8, 0xc0,
);
const AP2P_LRX_212: [u8; 7] = mode_entry_1_reg(
    ANALOG_CONFIG_LISTEN | ANALOG_CONFIG_TECH_AP2P | ANALOG_CONFIG_BITRATE_212 | ANALOG_CONFIG_RX,
    Register::ReceiverConfiguration3 as u32, ReceiverConfiguration3Mask::MaskRg1Am as u8, 0x00,
);
const AP2P_LRX_424: [u8; 7] = mode_entry_1_reg(
    ANALOG_CONFIG_LISTEN | ANALOG_CONFIG_TECH_AP2P | ANALOG_CONFIG_BITRATE_424 | ANALOG_CONFIG_RX,
    Register::ReceiverConfiguration3 as u32, ReceiverConfiguration3Mask::MaskRg1Am as u8, 0x00,
);

static DEFAULT_ANALOG_CONFIG: [u8; concat_arrays_size!(
    RESET_INIT,
    NFCA_TX_COMMON,
    NFCA_TX_106,
    NFCA_TX_212,
    NFCA_TX_424,
    NFCA_TX_848,
    NFCA_TX_848_AUX,
    NFCA_RX_COMMON,
    NFCA_RX_106,
    NFCA_RX_212,
    NFCA_RX_424,
    NFCA_RX_848,
    NFCB_TX_COMMON,
    NFCB_RX_COMMON,
    NFCB_RX_106,
    NFCB_RX_212,
    NFCB_RX_424,
    NFCB_RX_848,
    NFCF_TX_COMMON,
    NFCF_RX_COMMON,
    NFCF_RX_212,
    NFCF_RX_424,
    NFCV_TX_COMMON,
    NFCV_RX_COMMON,
    AP2P_TX_COMMON,
    AP2P_TX_106,
    AP2P_TX_212,
    AP2P_TX_424,
    AP2P_RX_TECH,
    AP2P_RX_COMMON,
    AP2P_RX_106,
    AP2P_RX_212,
    AP2P_RX_424,
    AP2P_LTX_COMMON,
    AP2P_LTX_106,
    AP2P_LTX_212,
    AP2P_LTX_424,
    AP2P_LRX_COMMON,
    AP2P_LRX_106,
    AP2P_LRX_212,
    AP2P_LRX_424
)] = concat_arrays!(
    RESET_INIT,
    NFCA_TX_COMMON,
    NFCA_TX_106,
    NFCA_TX_212,
    NFCA_TX_424,
    NFCA_TX_848,
    NFCA_TX_848_AUX,
    NFCA_RX_COMMON,
    NFCA_RX_106,
    NFCA_RX_212,
    NFCA_RX_424,
    NFCA_RX_848,
    NFCB_TX_COMMON,
    NFCB_RX_COMMON,
    NFCB_RX_106,
    NFCB_RX_212,
    NFCB_RX_424,
    NFCB_RX_848,
    NFCF_TX_COMMON,
    NFCF_RX_COMMON,
    NFCF_RX_212,
    NFCF_RX_424,
    NFCV_TX_COMMON,
    NFCV_RX_COMMON,
    AP2P_TX_COMMON,
    AP2P_TX_106,
    AP2P_TX_212,
    AP2P_TX_424,
    AP2P_RX_TECH,
    AP2P_RX_COMMON,
    AP2P_RX_106,
    AP2P_RX_212,
    AP2P_RX_424,
    AP2P_LTX_COMMON,
    AP2P_LTX_106,
    AP2P_LTX_212,
    AP2P_LTX_424,
    AP2P_LRX_COMMON,
    AP2P_LRX_106,
    AP2P_LRX_212,
    AP2P_LRX_424
);

pub(crate) struct AnalogConfigMgmt {
    config_tbl: Box<[u8]>,
}

impl AnalogConfigMgmt {
    pub fn new_default() -> Self {
        Self {
            config_tbl: Box::new(DEFAULT_ANALOG_CONFIG),
        }
    }
}