4.3 Motor Start-Up and AC Calibration

To start the fan motor, utilize the function fan_start() given below. This function invokes a series of other functions which will be described chronologically.

void fan_start(void)
{
    ac_trig_event_disable();
    tcd_enable();
    ac_calibration();
    ac_trig_event_enable();

}

ac_trig_event_disable() disconnects the AC trigger event from the CCL RS-latch, disabling the current spike detector.

void ac_trig_event_disable(void)
{
    AC0.INTCTRL &= ~AC_CMP_bm;
    EVSYS.CHANNEL0=EVSYS_CHANNEL0_OFF_gc;
    EVSYS.USERTCD0INPUTA = EVSYS_USER_OFF_gc;
    EVSYS.USEREVSYSEVOUTD = EVSYS_USER_OFF_gc;
}

tcd_enable() then turns on the fan motor by enabling the TCD peripheral.

void tcd_enable(void)
{
    TCD0.CTRLA = TCD_ENABLE_bm;
    TCD0.CTRLE = TCD_RESTART_bm; 
}

ac_calibration() increases the triggering point of the AC in 50 mV increments until no trigger happens within 100 ms. This is done on every start-up to ensure optimal detection conditions and to avoid false positives. The current draw of some motors is affected by temperature and other physical conditions.

void ac_calibration(void)
{
    PORTB.DIRSET = PIN3_bm;
    PORTB.OUTCLR = PIN3_bm;
    uint8_t calibrating = 1;
    uint16_t ac_trigger_voltage_mv=AC_TRIGGER_VOLTAGE_MV_INIT;
    AC0.INTCTRL = AC_INTMODE_NORMAL_POSEDGE_gc;
    while (calibrating)
    {
        ac_trigger_voltage_mv += 50;
        AC0.DACREF = ac_calculate_trigger_voltage(ac_trigger_voltage_mv);
        _delay_ms(100);//Allow some time for the flag to be raised
        if (!(AC0.STATUS & AC_CMPIF_bm))
        {
            calibrating=0;
            PORTB.OUTSET =PIN3_bm;
        }
        AC0.STATUS=AC_CMPIF_bm;
    }
    
}

ac_trig_event_enable() reconnects the AC trigger event to the CCL, making the system ready to detect a current spike event.

void ac_trig_event_enable(void)
{
    AC0.INTCTRL = AC_INTMODE_NORMAL_POSEDGE_gc | AC_CMP_bm;
    EVSYS.SWEVENTA = EVSYS_SWEVENTA_CH1_gc;
    EVSYS.CHANNEL0=EVSYS_CHANNEL0_CCL_LUT0_gc; //Output from the RS latch as trigger
    EVSYS.USERTCD0INPUTA=EVSYS_USER_CHANNEL0_gc;
    EVSYS.USEREVSYSEVOUTD = EVSYS_USER_CHANNEL0_gc;
}