Skip to content

Commit

Permalink
sample/doze: profile task scheduler power consumption
Browse files Browse the repository at this point in the history
  • Loading branch information
chrisstjohn committed Nov 15, 2023
1 parent 2eaa1da commit d4d119b
Show file tree
Hide file tree
Showing 8 changed files with 165 additions and 12 deletions.
2 changes: 1 addition & 1 deletion soft/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ rebuild: clean build
$(OUTPUT_DIR)/%.o: %.c
@echo $<
mkdir -p $(dir $@)
$(CC) -iquote inc -iquote $(APPLICATION) \
$(CC) -iquote inc -iquote $(APPLICATION) -iquote etc \
-x c -funsigned-char -funsigned-bitfields \
-DTARGET_MCU=$(TARGET_MCU) -DF_CPU=$(CLOCK_FREQUENCY)UL \
-ffunction-sections -fdata-sections -fpack-struct -fshort-enums -Wall -mmcu=$(TARGET_MCU) \
Expand Down
27 changes: 27 additions & 0 deletions soft/etc/pwm.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*! \file pwm.config
*
* \brief Software Pulse Width Modulation configuration template
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

/*
* This macro defines the GPIOs configured to be used as PWM outputs.
*
* A selector macro is passed which will choose a parameter from the
* configuration. For example, if you want to set PB5 and PB2 to be
* PWM channels 0 and 1 respectively use the macro like this
*
* @code
* #define PWM_GPIOS(_) _(B, 5) _(B, 2)
* @endcode
*/
33 changes: 33 additions & 0 deletions soft/etc/twinkle.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*! \file twinkle.config
*
* \brief Coordinated LED brightness configuration template
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

/*
* This macro defines the positions and PWM channels of each participating LED.
*
* The twinkle engine calculates a PWM setting in the range 0..255 according
* to the master light position vs the individual LED position:
* - if the LED is further away from master than "brightness" then the LED is OFF
* - if the LED is within half of "brightness" from master then the LED is ON
* - otherwise a linear gradient PWM is applied according to the distance
*
* A selector macro is passed which will choose a parameter from the
* configuration. For example, if you want to set channel 1 position 85 and
* channel 0 position 170 use the macro like this
*
* @code
* #define TWINKLE_PWMS(_) _(1, 85) _(0, 170)
* @endcode
*/
45 changes: 45 additions & 0 deletions soft/inc/gpio.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*! \file gpio.h
*
* \brief General Purpose I/O API
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include <avr/io.h>

/**
* @brief Configure a port+pin as a driven digital output
* @param port_ port letter e.g. B
* @paran pin_ pin number e.g. 2
*/
#define GPIO_CONFIGURE_DIGITAL_OUTPUT(port_, pin_) { DDR##port_ |= (1<<(pin_)); }

/**
* @brief Configure a port+pin as unused
* @param port_ port letter e.g. B
* @paran pin_ pin number e.g. 2
*/
#define GPIO_CONFIGURE_UNUSED(port_, pin_) { DDR##port_ &= ~(1<<(pin_)); }

/**
* @brief Drive a port+pin output to Vcc
* @param port_ port letter e.g. B
* @paran pin_ pin number e.g. 2
*/
#define GPIO_OUTPUT_Vcc(port_, pin_) { PORT##port_ |= (1<<(pin_)); }

/**
* @brief Drive a port+pin output to GND
* @param port_ port letter e.g. B
* @paran pin_ pin number e.g. 2
*/
#define GPIO_OUTPUT_GND(port_, pin_) { PORT##port_ &= ~(1<<(pin_)); }
19 changes: 9 additions & 10 deletions soft/lib/pwm.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,9 @@
*/

#include "pwm.h"
#include "gpio.h"
#include "task.h"

#include <avr/io.h>

/* Select configuration */
#ifndef PWM_COMFIG
# define PWM_CONFIG "pwm.config"
Expand All @@ -35,6 +34,8 @@
*/
#include PWM_CONFIG

#if defined(PWM_GPIOS)

/**
* Array of duty factors, initialised to the number of PWM GPIOs configured
*/
Expand Down Expand Up @@ -65,16 +66,12 @@ static uint8_t pwm_task(uint8_t ms_later)
case TASK_STARTUP:
tick = ~0;
/* Enable outputs */
#define PWM_GPIO_DDR_OUT(port_,pin_) DDR##port_ |= (1<<(pin_));
PWM_GPIOS(PWM_GPIO_DDR_OUT)
#undef PWM_GPIO_DDR_OUT
PWM_GPIOS(GPIO_CONFIGURE_DIGITAL_OUTPUT);
return 1;

case TASK_SHUTDOWN:
/* Disable outputs */
#define PWM_GPIO_DDR_HIZ(port_,pin_) DDR##port_ &= ~(1<<(pin_));
PWM_GPIOS(PWM_GPIO_DDR_HIZ)
#undef PWM_GPIO_DDR_HIZ
PWM_GPIOS(GPIO_CONFIGURE_UNUSED);
return 1;

default:
Expand All @@ -97,12 +94,12 @@ PWM_GPIOS(PWM_GPIO_DDR_HIZ)
#define PWM_GPIO_PORT_SWITCH(port_,pin_) \
if (pwm_duty[channel] > duty) \
{ \
PORT##port_ |= (1<<(pin_)); /* ON */ \
GPIO_OUTPUT_Vcc(port_, pin_); /* ON */ \
if (pwm_duty[channel] < next_duty) \
next_duty = pwm_duty[channel]; \
} \
else \
PORT##port_ &= ~(1<<(pin_)); /* OFF */ \
GPIO_OUTPUT_GND(port_, pin_); /* OFF */ \
channel++;
PWM_GPIOS(PWM_GPIO_PORT_SWITCH)
#undef PWM_GPIO_PORT_SWITCH
Expand All @@ -116,3 +113,5 @@ PWM_GPIOS(PWM_GPIO_PORT_SWITCH)
}

TASK_DECLARE(pwm_task);

#endif /* defined(PWM_GPIOS) */
15 changes: 14 additions & 1 deletion soft/lib/task.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,13 @@

#include "task.h"

#if !defined(TEST) && 0
# include "../inc/gpio.h"
# define CPU_PROFILE_GPIO(_) _(B,0) /**< Profile CPU activity on pin B0 */
#else
# define CPU_PROFILE_GPIO(_) /* do nothing */
#endif

#include <stdint.h>
#include <avr/pgmspace.h>
#include <avr/interrupt.h>
Expand Down Expand Up @@ -52,7 +59,9 @@ static void task_delay(uint8_t milliseconds)
{
while (task_ticks < milliseconds)
{
CPU_PROFILE_GPIO(GPIO_OUTPUT_GND);
sleep_cpu();
CPU_PROFILE_GPIO(GPIO_OUTPUT_Vcc);
}

/* Reset timer on exit so next delay is aligned to this time */
Expand Down Expand Up @@ -103,7 +112,7 @@ void task_main(void)

/* Reset counter and set ~1ms compare */
TCNT0 = 0;
OCR0A = (uint8_t)(TIMER_SYSCLK_256_2ms/2);
OCR0A = (uint8_t)(TIMER_SYSCLK_256_2ms/2)-1;

/* Raise interrupt on Compare Match A */
TIMSK = 0x10; /* OCIE0A */
Expand All @@ -128,6 +137,10 @@ void task_main(void)
#ifndef TEST
int main(void)
{
CPU_PROFILE_GPIO(GPIO_CONFIGURE_DIGITAL_OUTPUT);
CPU_PROFILE_GPIO(GPIO_OUTPUT_Vcc);
task_main();
CPU_PROFILE_GPIO(GPIO_OUTPUT_GND);
CPU_PROFILE_GPIO(GPIO_CONFIGURE_UNUSED);
}
#endif
4 changes: 4 additions & 0 deletions soft/lib/twinkle.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
*/
#include TWINKLE_CONFIG

#if defined(TWINKLE_PWMS)

static uint8_t twinkle_position; /**< current position of light source, wraps around 255-0 */
static uint8_t twinkle_brightness; /**< current brightness of light source: 0 = All OFF, 255 = All ON */

Expand Down Expand Up @@ -79,3 +81,5 @@ uint8_t twinkle_get_brightness(void)
{
return twinkle_brightness;
}

#endif /* defined(TWINKLE_PWMS) */
32 changes: 32 additions & 0 deletions soft/sample/doze/doze.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*! \file doze.c
*
* \brief Task sleep profiler
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include "task.h"

/**
* @brief This task just sleeps, but it is useful
* - when CPU_PROFILE_GPIO set in task.c
* - for measuring sleep current consumption
* @param ignored
* @return 250ms sleep
*/
static uint8_t doze_task(uint8_t ignored)
{
/* Sleep for 250ms */
return 250;
}

TASK_DECLARE(doze_task);

0 comments on commit d4d119b

Please sign in to comment.