HWA
Bare metal programming with style
hwa/atmel/avr/examples/03-5-fade-counter-compare-output/main.c

Fade a LED connected to a counter compare output (method 1)

Note See method 2 in the next example.

/* This file is part of the HWA project.
* Copyright (c) 2012,2015 Christophe Duparquet.
* All rights reserved. Read LICENSE.TXT for details.
*/
/* Include the target board (and device) definitions
*/
#include BOARD_H
/* The counter
*/
#define COUNTER counter0
#define CLKDIV 64
#define COUNTMODE up_loop
#define COMPARE compare0
#define TOP 0xFF
/* Compare strings
*/
#define STRCMP(s1,s2) __builtin_strcmp(s1,s2)
/* Service the counter overflow IRQ:
* compute the next value of the compare unit
*
* Phase 0: increase duty cycle from 0 to 255
* Phase 1: decrease duty cycle from 255 to 0 (use ~duty)
* Phase 2: off
* Phase 3: off
*/
HW_ISR( (COUNTER,irq,overflow) )
{
static hw_uint_t(HW_BITS(COUNTER)) duty ;
static uint8_t phase ;
if ( phase == 0 )
hw( write, (COUNTER,COMPARE), duty );
else if ( phase == 1 )
hw( write, (COUNTER,COMPARE), ~duty );
duty++ ;
if ( (duty & TOP) == 0 ) {
phase = (phase + 1) & 3 ;
/* In 'up_loop' counting mode, we must disconnect/reconnect the output of
* the compare unit as it can not provide pulses of less than 1 cycle.
*
* Note that the configuration of the counter is not known here, so there
* is only loose checking against the arguments provided and the generated
* code will probably have to read the hardware to retrieve unknown bit
* values.
*/
if ( !STRCMP(HW_Q(COUNTMODE),"up_loop") ) {
if ( phase == 2 )
hw( configure, (COUNTER,COMPARE), output, disconnected );
else if ( phase == 0 )
hw( configure, (COUNTER,COMPARE), output, set_at_bottom_clear_after_match );
}
}
}
int main ( )
{
/* Create a HWA context to collect the hardware configuration
* Preload this context with RESET values
*/
hwa( begin, reset );
/* Have the CPU enter idle mode when the 'sleep' instruction is executed.
*/
hwa( configure, core0,
sleep, enabled,
sleep_mode, idle );
/* Configure the counter to count between 0 and TOP
*/
hwa( configure, COUNTER,
clock, ioclk / CLKDIV,
direction, COUNTMODE,
bottom, 0,
top, TOP );
if ( !STRCMP(HW_Q(COUNTMODE),"updown_loop") )
hwa( configure, (COUNTER,COMPARE),
output, clear_after_match_up_set_after_match_down );
else /* up_loop */
hwa( configure, (COUNTER,COMPARE),
output, set_at_bottom_clear_after_match );
/* Enable overflow IRQ
*/
hwa( enable, (COUNTER,irq,overflow) );
/* Write this configuration into the hardware
*/
hwa( commit );
hw( enable, interrupts );
for(;;)
hw( wait, irq );
}
HW_BITS
#define HW_BITS(...)
Definition: hwa_1.h:500
hwa
#define hwa(...)
hwa( action, object [,...] ) stores an action for an object into a HWA context.
Definition: hwa_macros.h:552
hw
#define hw(...)
hw( action, object [,...] ) executes an action immediately on an object.
Definition: hwa_macros.h:523
HW_Q
#define HW_Q(...)
Build a C string from a list of elements.
Definition: hwa_macros.h:448
hw_uint_t
#define hw_uint_t(n)
Declares an unsigned integer.
Definition: hwa_macros.h:729
HW_ISR
#define HW_ISR(...)
Definition: hwa_interrupts.h:80