// File: mrlordkaj[P]i2cdevlib-pi/MPR121/MPR121.cpp
// Function: MPR121::initialize()
void MPR121::initialize()
{
  // These are the configuration values recommended by app note AN3944
  // along with the description in the app note.

  // Section A
  // Description:
  //   This group of settings controls the filtering of the system
  //   when the data is greater than the baseline.  The setting used 
  //   allows the filter to act quickly and adjust for environmental changes. 
  //   Additionally, if calibration happens to take place while a touch occurs,
  //   the value will self adjust very quickly.  This auto-recovery or snap back
  //   provides repeated false negative for a touch detection. 
  // Variation:
  //   As the filter is sensitive to setting changes, it is recommended
  //   that users read AN3891 before changing the values. 
  //   In most cases these default values will work.
  I2Cdev::writeByte(m_devAddr, MHD_RISING,        0x01);
  I2Cdev::writeByte(m_devAddr, NHD_AMOUNT_RISING, 0x01);
  I2Cdev::writeByte(m_devAddr, NCL_RISING,        0x00);
  I2Cdev::writeByte(m_devAddr, FDL_RISING,        0x00);

  // Section B
  // Description:
  //   This group of settings controls the filtering of the system 
  //   when the data is less than the baseline.  The settings slow down 
  //   the filter as the negative charge is in the same direction 
  //   as a touch.  By slowing down the filter, touch signals 
  //   are "rejected" by the baseline filter.  While at the same time
  //   long term environmental changes that occur slower than
  //   at a touch are accepted.  This low pass filter both allows 
  //   for touches to be detected properly while preventing false 
  //   positives by passing environmental changes through the filter.
  // Variation:
  //   As the filter is sensitive to setting changes, it is recommended 
  //   that users read AN3891 before changing the values.  
  //   In most cases these default values will work.
  I2Cdev::writeByte(m_devAddr, MHD_FALLING,        0x01);
  I2Cdev::writeByte(m_devAddr, NHD_AMOUNT_FALLING, 0x01);
  I2Cdev::writeByte(m_devAddr, NCL_FALLING,        0xFF);
  I2Cdev::writeByte(m_devAddr, FDL_FALLING,        0x02);

  // Section C
  // Description:
  //   The touch threshold registers set the minimum delta from the baseline
  //   when a touch is detected.  The value 0x0F (or 15 in decimal) is
  //   an estimate of the minimum value for touch.  Most electrodes will 
  //   work with this value even if they vary greatly in size and shape.  
  //   The value of 0x0A or 10 in the release threshold register allowed 
  //   for hysteresis in the touch detection.
  // Variation: 
  //   For very small electrodes, smaller values can be used and for 
  //   very large electrodes the reverse is true.  One easy method is 
  //   to view the deltas actually seen in a system and set the touch 
  //   at 80% and release at 70% of delta for good performance.
  I2Cdev::writeByte(m_devAddr, ELE0_TOUCH_THRESHOLD,   TOUCH_THRESHOLD);
  I2Cdev::writeByte(m_devAddr, ELE0_RELEASE_THRESHOLD, RELEASE_THRESHOLD);
  I2Cdev::writeByte(m_devAddr, ELE1_TOUCH_THRESHOLD,   TOUCH_THRESHOLD);
  I2Cdev::writeByte(m_devAddr, ELE1_RELEASE_THRESHOLD, RELEASE_THRESHOLD);
  I2Cdev::writeByte(m_devAddr, ELE2_TOUCH_THRESHOLD,   TOUCH_THRESHOLD);
  I2Cdev::writeByte(m_devAddr, ELE2_RELEASE_THRESHOLD, RELEASE_THRESHOLD);
  I2Cdev::writeByte(m_devAddr, ELE3_TOUCH_THRESHOLD,   TOUCH_THRESHOLD);
  I2Cdev::writeByte(m_devAddr, ELE3_RELEASE_THRESHOLD, RELEASE_THRESHOLD);

  // TODO: enable setting these channels to capsense or GPIO
  // for now they are all capsense
  I2Cdev::writeByte(m_devAddr, ELE4_TOUCH_THRESHOLD,    TOUCH_THRESHOLD);
  I2Cdev::writeByte(m_devAddr, ELE4_RELEASE_THRESHOLD,  RELEASE_THRESHOLD);
  I2Cdev::writeByte(m_devAddr, ELE5_TOUCH_THRESHOLD,    TOUCH_THRESHOLD);
  I2Cdev::writeByte(m_devAddr, ELE5_RELEASE_THRESHOLD,  RELEASE_THRESHOLD);
  I2Cdev::writeByte(m_devAddr, ELE6_TOUCH_THRESHOLD,    TOUCH_THRESHOLD);
  I2Cdev::writeByte(m_devAddr, ELE6_RELEASE_THRESHOLD,  RELEASE_THRESHOLD);
  I2Cdev::writeByte(m_devAddr, ELE7_TOUCH_THRESHOLD,    TOUCH_THRESHOLD);
  I2Cdev::writeByte(m_devAddr, ELE7_RELEASE_THRESHOLD,  RELEASE_THRESHOLD);
  I2Cdev::writeByte(m_devAddr, ELE8_TOUCH_THRESHOLD,    TOUCH_THRESHOLD);
  I2Cdev::writeByte(m_devAddr, ELE8_RELEASE_THRESHOLD,  RELEASE_THRESHOLD);
  I2Cdev::writeByte(m_devAddr, ELE9_TOUCH_THRESHOLD,    TOUCH_THRESHOLD);
  I2Cdev::writeByte(m_devAddr, ELE9_RELEASE_THRESHOLD,  RELEASE_THRESHOLD);
  I2Cdev::writeByte(m_devAddr, ELE10_TOUCH_THRESHOLD,   TOUCH_THRESHOLD);
  I2Cdev::writeByte(m_devAddr, ELE10_RELEASE_THRESHOLD, RELEASE_THRESHOLD);
  I2Cdev::writeByte(m_devAddr, ELE11_TOUCH_THRESHOLD,   TOUCH_THRESHOLD);
  I2Cdev::writeByte(m_devAddr, ELE11_RELEASE_THRESHOLD, RELEASE_THRESHOLD);

  // Section D
  // Description:
  //   There are three settings embedded in this register so it is 
  //   only necessary to pay attention to one.  The ESI controls 
  //   the sample rate of the device.  In the default, the setting
  //   used is 0x00 for 1ms sample rate.  Since the SFI is set to 00,
  //   resulting in 4 samples averaged, the response time will be 4 ms.
  // Variation:
  //   To save power, the 1 ms can be increased to 128 ms by increasing
  //   the setting to 0x07.  The values are base 2 exponential, thus 
  //   0x01 = 2ms, 0x02 = 4 ms; and so on to 0x07 = 128 ms.  Most of 
  //   the time, 0x04 results in the best compromise between power 
  //   consumption and response time.
  I2Cdev::writeByte(m_devAddr, FILTER_CONFIG, 0x04);

  // Section E
  // Description:
  //   This register controls the number of electrodes being enabled
  //   and the mode the device is in.  There are only two modes, 
  //   Standby (when the value is 0x00) and Run (when the value of 
  //   the lower bit is non-zero).  The default value shown enables 
  //   all 12 electrodes by writing decimal 12 or hex 0x0C to the register. 
  //   Typically other registers cannot be changed while the part is running, 
  //   so this register should always be written last.
  // Variation:
  //   During debug of a system, this register will change between 
  //   the number of electrodes and 0x00 every time a register needs 
  //   to change.  In a production system, this register will only need 
  //   to be written when the mode is changed from Standby to Run or vice versa.
  I2Cdev::writeByte(m_devAddr, ELECTRODE_CONFIG, 0x0C); 

  // Section F
  // Description:
  //   These are the settings used for the Auto Configuration.  They enable 
  //   AUTO-CONFIG and AUTO_RECONFIG.  In addition, they set the target
  //   rate for the baseline.  The upper limit is set to 190, the target 
  //   is set to 180 and the lower limit is set to 140.
  // Variation:
  //   In most cases these values will never need to be changed, but if
  //   a case arises, a full description is found in application note AN3889.
  //I2Cdev::writeByte(m_devAddr, AUTO_CONFIG_CONTROL_0,    0x0B);
  //I2Cdev::writeByte(m_devAddr, AUTO_CONFIG_USL,          0x9C);
  //I2Cdev::writeByte(m_devAddr, AUTO_CONFIG_LSL,          0x65);
  //I2Cdev::writeByte(m_devAddr, AUTO_CONFIG_TARGET_LEVEL, 0x8C);
          
}

// Assembly:
subq $0x18, %rsp
movq %rdi, 0x10(%rsp)
movq 0x10(%rsp), %rax
movq %rax, 0x8(%rsp)
movl $0x2b, %esi
movl $0x1, %edx
movzbl (%rax), %edi
callq 0x22ad0
movq 0x8(%rsp), %rax
movl $0x2c, %esi
movl $0x1, %edx
movzbl (%rax), %edi
callq 0x22ad0
movq 0x8(%rsp), %rax
movl $0x2d, %esi
xorl %edx, %edx
movzbl (%rax), %edi
callq 0x22ad0
movq 0x8(%rsp), %rax
movl $0x2e, %esi
xorl %edx, %edx
movzbl (%rax), %edi
callq 0x22ad0
movq 0x8(%rsp), %rax
movl $0x2f, %esi
movl $0x1, %edx
movzbl (%rax), %edi
callq 0x22ad0
movq 0x8(%rsp), %rax
movl $0x30, %esi
movl $0x1, %edx
movzbl (%rax), %edi
callq 0x22ad0
movq 0x8(%rsp), %rax
movl $0x31, %esi
movl $0xff, %edx
movzbl (%rax), %edi
callq 0x22ad0
movq 0x8(%rsp), %rax
movl $0x32, %esi
movl $0x2, %edx
movzbl (%rax), %edi
callq 0x22ad0
movq 0x8(%rsp), %rax
movl $0x41, %esi
movl $0xf, %edx
movzbl (%rax), %edi
callq 0x22ad0
movq 0x8(%rsp), %rax
movl $0x42, %esi
movl $0xa, %edx
movzbl (%rax), %edi
callq 0x22ad0
movq 0x8(%rsp), %rax
movl $0x43, %esi
movl $0xf, %edx
movzbl (%rax), %edi
callq 0x22ad0
movq 0x8(%rsp), %rax
movl $0x44, %esi
movl $0xa, %edx
movzbl (%rax), %edi
callq 0x22ad0
movq 0x8(%rsp), %rax
movl $0x45, %esi
movl $0xf, %edx
movzbl (%rax), %edi
callq 0x22ad0
movq 0x8(%rsp), %rax
movl $0x46, %esi
movl $0xa, %edx
movzbl (%rax), %edi
callq 0x22ad0
movq 0x8(%rsp), %rax
movl $0x47, %esi
movl $0xf, %edx
movzbl (%rax), %edi
callq 0x22ad0
movq 0x8(%rsp), %rax
movl $0x48, %esi
movl $0xa, %edx
movzbl (%rax), %edi
callq 0x22ad0
movq 0x8(%rsp), %rax
movl $0x49, %esi
movl $0xf, %edx
movzbl (%rax), %edi
callq 0x22ad0
movq 0x8(%rsp), %rax
movl $0x4a, %esi
movl $0xa, %edx
movzbl (%rax), %edi
callq 0x22ad0
movq 0x8(%rsp), %rax
movl $0x4b, %esi
movl $0xf, %edx
movzbl (%rax), %edi
callq 0x22ad0
movq 0x8(%rsp), %rax
movl $0x4c, %esi
movl $0xa, %edx
movzbl (%rax), %edi
callq 0x22ad0
movq 0x8(%rsp), %rax
movl $0x4d, %esi
movl $0xf, %edx
movzbl (%rax), %edi
callq 0x22ad0
movq 0x8(%rsp), %rax
movl $0x4e, %esi
movl $0xa, %edx
movzbl (%rax), %edi
callq 0x22ad0
movq 0x8(%rsp), %rax
movl $0x4f, %esi
movl $0xf, %edx
movzbl (%rax), %edi
callq 0x22ad0
movq 0x8(%rsp), %rax
movl $0x50, %esi
movl $0xa, %edx
movzbl (%rax), %edi
callq 0x22ad0
movq 0x8(%rsp), %rax
movl $0x51, %esi
movl $0xf, %edx
movzbl (%rax), %edi
callq 0x22ad0
movq 0x8(%rsp), %rax
movl $0x52, %esi
movl $0xa, %edx
movzbl (%rax), %edi
callq 0x22ad0
movq 0x8(%rsp), %rax
movl $0x53, %esi
movl $0xf, %edx
movzbl (%rax), %edi
callq 0x22ad0
movq 0x8(%rsp), %rax
movl $0x54, %esi
movl $0xa, %edx
movzbl (%rax), %edi
callq 0x22ad0
movq 0x8(%rsp), %rax
movl $0x55, %esi
movl $0xf, %edx
movzbl (%rax), %edi
callq 0x22ad0
movq 0x8(%rsp), %rax
movl $0x56, %esi
movl $0xa, %edx
movzbl (%rax), %edi
callq 0x22ad0
movq 0x8(%rsp), %rax
movl $0x57, %esi
movl $0xf, %edx
movzbl (%rax), %edi
callq 0x22ad0
movq 0x8(%rsp), %rax
movl $0x58, %esi
movl $0xa, %edx
movzbl (%rax), %edi
callq 0x22ad0
movq 0x8(%rsp), %rax
movl $0x5d, %esi
movl $0x4, %edx
movzbl (%rax), %edi
callq 0x22ad0
movq 0x8(%rsp), %rax
movl $0x5e, %esi
movl $0xc, %edx
movzbl (%rax), %edi
callq 0x22ad0
addq $0x18, %rsp
retq
nopl (%rax,%rax)