4.1 Bare Metal Implementation
- The Clock peripheral must run at a
                frequency of 20 MHz. The default Clock speed is 3.33 MHz and has, by default, a
                prescaler division of six. This code example needs to disable the prescaler and use
                the clock to maximum speed.
                    
_PROTECTED_WRITE(CLKCTRL.MCLKCTRLB, CLKCTRL.MCLKCTRLB & ~CLKCTRL_PEN_bm);
Figure 4-1. MCLKCTRLB Register of CLKCTRL  - The TCE and WEX corresponding
                registers in the Port Multiplexer can route the module outputs to different ports.
                In this case, Port A is chosen, which is also the default
                    port.
PORTMUX.TCEROUTEA = 0x0;Figure 4-2. PORTMUX Control for TCE and WEX  - The CTRLB register of TCE contains
                the Enable bits of the compare channels and the bit field that determines the
                Waveform Generation mode. In this example channels 0, 1, 2, and 3 are used with a
                Single-Slope PWM
                    mode.
TCE0.CTRLB |= (TCE_CMP0EN_bm | TCE_CMP1EN_bm | TCE_CMP2EN_bm | TCE_CMP3EN_bm);
TCE0.CTRLB |= TCE_WGMODE_SINGLESLOPE_gc;
Figure 4-3. CTRLB Register of TCE  - Set the DIR bit of the CTRLECLR
                register of TCE to ‘
1’ to set the timer to count clock ticks down (decrementing). The default value of the DIR bit is ‘0’.TCE0.CTRLECLR = TCE_DIR_bm;
Figure 4-4. CTRLECLR Register of TCE  - PER is the buffer of the Period
                register of TCE and is used to set the frequency of the PWM signal using
                    EQ5.1:
Considering the targeted values for this example:
/* the PER register is always set with the desired value -1, 1000 - 1 = 999, the desired value for a 50us period */ TCE0.PER = 0x3E7; - The Compare registers are updated
                using its buffer capabilities to set the duty cycle. The values in the Compare
                registers can be set to have random duty cycles such as 20%, 40%, 60% and 80%.
                However, these values are overridden at run time by updating the CMP registers using
                their buffers after the first interrupt occurs. So, we can set these values at
                    ‘
0’.TCE0.CMP0 = 0x00;TCE0.CMP1 = 0x00;TCE0.CMP2 = 0x00;TCE0.CMP3 = 0x00; - After starting the timer, the duty
                cycles will increase every time a compare register’s value matches the counter
                value. The duty cycles’ range will be between 0-100%. During the ISR, this happens
                for every compare channel. ISR routine for Compare 0
                channel:
ISR(TCE0_CMP0_vect) { /* clear the interrupt flag */ TCE0.INTFLAGS = TCE_CMP0_bm; static uint16_t duty_cycle = 0; /* duty cycle update in interrupt */ duty_cycle += 5; if(duty_cycle >= MAX_DUTY_CYCLE) duty_cycle = 0; TCE0.CMP0BUF = duty_cycle; } - Enable interrupts on compare match
                for each of the compare registers of
                    TCE.
TCE0.INTCTRL = (TCE_CMP0_bm | TCE_CMP1_bm | TCE_CMP2_bm | TCE_CMP3_bm);
Figure 4-5. INTCTRL Register of TCE  - Set the initial value for the TCE
                counter to
                ‘
0’.TCE0.CNT = 0x00; - Set the prescaler to
                    ‘
1’ by changing the CLKSEL bit field in the CTRLA register. To start the counter, the user has to set the Enable bit in the same register.TCE0.CTRLA = TCE_CLKSEL_DIV1_gc;
The last step for configuring the TCE is to enable the module.TCE0.CTRLA |= TCE_ENABLE_bm;
Figure 4-6. CTRLA Register of TCE  - Set the output routing matrix for the
                WEX in the Direct mode and enable dead-time insertion for each pair of two
                complementary signals. After making these settings, the WEX uses the four generated
                PWM signals from TCE to generate eight complementary
                    signals.
WEX0.CTRLA = WEX_INMX_DIRECT_gc | WEX_DTI0EN_bm | WEX_DTI1EN_bm | WEX_DTI2EN_bm | WEX_DTI3EN_bm;Figure 4-7. CTRLA Register of WEX  - Set the desired values for dead-time
                using the dead-time registers. The dead-time is measured in peripheral clock ticks.
                The equation below explains how to calculate the
                    dead-time:
WEX0.DTLS = 0x03;WEX0.DTHS = 0x05;Figure 4-8. Dead-Time Registers of WEX: Dead-Time Low-Side, High-Side and Both Sides To achieve symmetrical dead time for the application, use the last register. In this example, the low-side and high-side dead-time registers are used independently to create asymmetrical dead-time.
Equations used to calculate the dead time:
EQ5.2
Converting clock ticks to nanoseconds, for example:
 - Set the Fault Restart mode condition
                and Fault signal driving pattern in the FAULTCTRL
                    register.
/* set fault restart mode to latched mode - fault is active as long as the fault condition is active */ /* to restart from fault in latched mode the user must use a software fault clear command */ WEX0.FAULTCTRL = WEX_FDMODE_LATCHED_gc;
/* drive all pins to low '0' logic when a fault is detected */ WEX0.FAULTCTRL |= WEX_FDACT_LOW_gc;
Figure 4-9. FAULTCTRL Register of WEX  - Enable the event input A of WEX using
                the EVCTRLA
                    register.
WEX0.EVCTRLA = WEX_FAULTEI_bm;
Figure 4-10. EVCTRLA Register of WEX  - Enable Fault interrupt (Fault
                detection) and clear the Fault flags during the WEX’s
                    ISR.
WEX0.INTCTRL = WEX_FAULTDET_bm;
/* WEX fault ISR */ ISR(WEX0_FDFEVA_vect) { /* clear the interrupt flag and fault event flag */ WEX0.INTFLAGS = WEX_FDFEVA_bm | WEX_FAULTDET_bm; }Figure 4-11. INTCTRL and INTFLAGS Registers of WEX  - Configure the EVENT SYSTEM (EVSYS)
                peripheral to generate events on Channel 0. Configure WEX to be the user of the
                event generator from Channel 0. Generate a Fault using a software event. To stop the
                Fault, turn off the Fault generator channel from EVSYS and clear the Fault state
                using a software
                command.
/* set the WEX0 peripheral as the user of the event generator from channel 0, which is a software event in this example*/ EVSYS.USERWEXA = EVSYS_USER_CHANNEL0_gc;
/* software fault creation, repeat in main loop to see it on LogicA. This is an event generated using a software command */ EVSYS.SWEVENTA = EVSYS_SWEVENTA_CH0_gc;
/* clear fault condition using a software command */ WEX0.CTRLC = WEX_CMD_FAULTCLR_gc;
 - Enable WEX’s outputs to generate the
                eight PWM signals using the OUTOVEN
                    register.
/* enables WEX's outputs */ WEX0.OUTOVEN = WEX_OUTOVEN0_bm | WEX_OUTOVEN1_bm | WEX_OUTOVEN2_bm | WEX_OUTOVEN3_bm | WEX_OUTOVEN4_bm | WEX_OUTOVEN5_bm | WEX_OUTOVEN6_bm | WEX_OUTOVEN7_bm;Figure 4-12. OUTOVEN Register of WEX  - Then, the Port A Pins 0-7 (PA0-7) are
                set as output by writing a ‘
1’ to the corresponding bit in the Direction register of the port.PORTA.DIRSET = PIN0_bm | PIN1_bm | PIN2_bm | PIN3_bm | PIN4_bm | PIN5_bm | PIN6_bm | PIN7_bm; - After all the modules are configured,
                enable global
                interrupts.
/* enable global interrupts */ sei(); 
