#define LRA_SLAVE_ADDR 0x5A
#define LRA_DEFAULT_TIMEOUT ((uint32_t)2u)
 
#define LRA_RATED_VOLTAGE (uint8_t)0x16
#define LRA_OD_CLAMP_VOLTAGE (uint8_t)0x17
#define LRA_FEEDBACK_CONTROL (uint8_t)0x1A
#define LRA_AUTO_CAL_COMPENSATION_RESULTS (uint8_t)0x18
#define LRA_AUTO_CAL_BACK_EMF_RESULTS (uint8_t)0x19
#define LRA_CONTROL1 (uint8_t)0x1B
#define LRA_CONTROL2 (uint8_t)0x1C
#define LRA_CONTROL3 (uint8_t)0x1D
#define LRA_LIB_SEL (uint8_t)0x03
#define LRA_MODE (uint8_t)0x01
 
#define LRA_WAVE_FORM (uint8_t)0x04
#define LRA_WAVE_FORM_VALUE (uint8_t)0x01
#define LRA_GO (uint8_t)0x0C
#define LRA_GO_VALUE (uint8_t)0x01
 
#define LRA_RTP_FORM_VALUE (uint8_t)0x02
 
// Vpeak = 2.2 x Vrms, Vrms = 1.8v, f(lra) = 235Hz SampleTime = 300us
#define LRA_RATED_VOLTAGE_VALUE (uint8_t)0x46
#define LRA_OD_CLAMP_VOLTAGE_VALUE (uint8_t)0xBA
#define LRA_FEEDBACK_CONTROL_VALUE (uint8_t)0xB6
#define LRA_CONTROL1_VALUE (uint8_t)0x13
#define LRA_CONTROL2_VALUE (uint8_t)0xF5
#define LRA_CONTROL3_VALUE (uint8_t)0x80
#define LRA_LIB_SEL_VALUE (uint8_t)0x6
#define LRA_MODE_VALUE (uint8_t)0x0
#define RTP_MODE_VALUE (uint8_t)0x5
//auto-calibration
#define LRA_AUTO_CALI_MEM_INTERFACE (uint8_t)0x1E
 
#define LRA_CONTROL1_CALI_VALUE (uint8_t)0x93
#define LRA_MODE_CALI_VALUE (uint8_t)0x07
#define LRA_AUTO_CALI_MEM_VALUE (uint8_t)0x20
 
#define LRA_CONTROL5 (uint8_t)0x1F
#define LRA_CONTROL5_VALUE (uint8_t)0x90
 
#define LRA_STARTUP_SEQUENCE_DURATION (uint16_t)250
 
 
static void lra_auto_calibration(void)
{
    uint16_t ret;
    LRA_ENABLE_SetHigh();
    DELAY_microseconds(LRA_STARTUP_SEQUENCE_DURATION);
    lra_write(LRA_RATED_VOLTAGE, LRA_RATED_VOLTAGE_VALUE);
    lra_write(LRA_OD_CLAMP_VOLTAGE, LRA_OD_CLAMP_VOLTAGE_VALUE);
    lra_write(LRA_FEEDBACK_CONTROL, LRA_FEEDBACK_CONTROL_VALUE);
    lra_write(LRA_CONTROL1, LRA_CONTROL1_VALUE);
    lra_write(LRA_CONTROL2, LRA_CONTROL2_VALUE);
    lra_write(LRA_CONTROL3, LRA_CONTROL3_VALUE);
    lra_write(LRA_LIB_SEL, LRA_LIB_SEL_VALUE);
    lra_write(LRA_MODE, LRA_MODE_CALI_VALUE);  
    lra_write(LRA_AUTO_CALI_MEM_INTERFACE, LRA_AUTO_CALI_MEM_VALUE);  
    lra_write(LRA_GO, LRA_GO_VALUE);
    do
    {
        lra_write_reg(LRA_GO);
        lra_read(&ret);
    } while (ret != 0);
    LRA_ENABLE_SetLow();
}
 
void lra_init(void)
{
    LRA.Initialize();
    lra_auto_calibration();
    LRA_ENABLE_SetHigh();
    DELAY_microseconds(LRA_STARTUP_SEQUENCE_DURATION);
    lra_write(LRA_RATED_VOLTAGE, LRA_RATED_VOLTAGE_VALUE);
    lra_write(LRA_OD_CLAMP_VOLTAGE, LRA_OD_CLAMP_VOLTAGE_VALUE);
    lra_write(LRA_FEEDBACK_CONTROL, LRA_FEEDBACK_CONTROL_VALUE);
    lra_write(LRA_CONTROL1, LRA_CONTROL1_CALI_VALUE);
    lra_write(LRA_CONTROL2, LRA_CONTROL2_VALUE);
    lra_write(LRA_CONTROL3, LRA_CONTROL3_VALUE);
    lra_write(LRA_AUTO_CALI_MEM_INTERFACE, LRA_AUTO_CALI_MEM_VALUE);
    lra_write(LRA_MODE, RTP_MODE_VALUE);
    LRA_ENABLE_SetLow();
}
 
void lra_play_rtp_waveform_ex(uint8_t address)
{
    LRA_ENABLE_SetHigh();
    DELAY_microseconds(LRA_STARTUP_SEQUENCE_DURATION);
    for(int i = 0;i < 1;i++)
    {
        lra_write(address, 0x7F);
        DELAY_microseconds(2000);  
 
        lra_write(address, 0x73);
        DELAY_microseconds(1000);  
 
        lra_write(address, 0x5C);
        DELAY_microseconds(1000);  
 
        lra_write(address, 0x43);
        DELAY_microseconds(1000);  
 
        lra_write(address, 0x2D);
        DELAY_microseconds(1000);  
 
        lra_write(address, 0x1B);
        DELAY_microseconds(1000);
 
        lra_write(address, 0x0C);
        DELAY_microseconds(1000);
 
        lra_write(address, 0x00);
        DELAY_microseconds(1000);
    }  
    LRA_ENABLE_SetLow();
}
 
void lra_play_rtp_waveform(void)
{
    lra_play_rtp_waveform_ex(LRA_RTP_FORM_VALUE);
}