mirror of
https://github.com/digistump/DigistumpArduino.git
synced 2025-09-17 17:32:25 -07:00
added updated tinypinchange and associated libraries to support PRO
This commit is contained in:
@@ -0,0 +1,151 @@
|
||||
// a Tiny optimized Software PWM Manager (all pins must be part of the same port)
|
||||
// Only resources RAM/Program Memory of used pins are declared in the code at compilation time.
|
||||
// based largely on Atmel's AVR136: Low-Jitter Multi-Channel Software PWM Application Note:
|
||||
// http://www.atmel.com/dyn/resources/prod_documents/doc8020.pdf
|
||||
// RC Navy 2013
|
||||
// http://p.loussouarn.free.fr
|
||||
|
||||
#include <TinySoftPwm.h>
|
||||
|
||||
#define TINY_SOFT_PWM_PORT PORTB
|
||||
#define TINY_SOFT_PWM_DDR DDRB
|
||||
|
||||
#define TINY_SOFT_PWM_CLEAR_PIN(RamIdx) (PortPwmTo1 &= GET_INV_PIN_MSK(RamIdx))
|
||||
|
||||
#define TINY_SOFT_PWM_DECLARE_PIN(Px) TINY_SOFT_PWM_DDR |= (1<<(Px)); PortPwmMask |= (1<<(Px))
|
||||
|
||||
#define GET_INV_PIN_MSK(RamIdx) ((uint8_t)pgm_read_byte(&RamIdxToInvPinMsk[(RamIdx)]))
|
||||
|
||||
uint8_t RamIdxToInvPinMsk[] PROGMEM ={
|
||||
#if (TINY_SOFT_PWM_USES_P0 == 1)
|
||||
~(1<<0),
|
||||
#endif
|
||||
#if (TINY_SOFT_PWM_USES_P1 == 1)
|
||||
~(1<<1),
|
||||
#endif
|
||||
#if (TINY_SOFT_PWM_USES_P2 == 1)
|
||||
~(1<<2),
|
||||
#endif
|
||||
#if (TINY_SOFT_PWM_USES_P3 == 1)
|
||||
~(1<<3),
|
||||
#endif
|
||||
#if (TINY_SOFT_PWM_USES_P4 == 1)
|
||||
~(1<<4),
|
||||
#endif
|
||||
#if (TINY_SOFT_PWM_USES_P5 == 1)
|
||||
~(1<<5),
|
||||
#endif
|
||||
};
|
||||
static uint8_t Compare[TINY_SOFT_PWM_CH_MAX];
|
||||
volatile uint8_t PwmOrder[TINY_SOFT_PWM_CH_MAX];
|
||||
static uint8_t PortPwmMask=0;
|
||||
volatile uint8_t PortPwmTo1=0x00;
|
||||
volatile uint8_t PortPwmTo0=0xFF;
|
||||
static uint8_t _TickMax=255;
|
||||
|
||||
static uint8_t PwmToPwmMax(uint8_t Pwm);
|
||||
|
||||
void TinySoftPwm_begin(uint8_t TickMax, uint8_t PwmInit)
|
||||
{
|
||||
uint8_t oldSREG = SREG;
|
||||
cli();
|
||||
// set the direction of the used ports and update PortPwmMask
|
||||
#if (TINY_SOFT_PWM_USES_P0 == 1)
|
||||
TINY_SOFT_PWM_DECLARE_PIN(PB0);
|
||||
#endif
|
||||
#if (TINY_SOFT_PWM_USES_P1 == 1)
|
||||
TINY_SOFT_PWM_DECLARE_PIN(PB1);
|
||||
#endif
|
||||
#if (TINY_SOFT_PWM_USES_P2 == 1)
|
||||
TINY_SOFT_PWM_DECLARE_PIN(PB2);
|
||||
#endif
|
||||
#if (TINY_SOFT_PWM_USES_P3 == 1)
|
||||
TINY_SOFT_PWM_DECLARE_PIN(PB3);
|
||||
#endif
|
||||
#if (TINY_SOFT_PWM_USES_P4 == 1)
|
||||
TINY_SOFT_PWM_DECLARE_PIN(PB4);
|
||||
#endif
|
||||
#if (TINY_SOFT_PWM_USES_P5 == 1)
|
||||
TINY_SOFT_PWM_DECLARE_PIN(PB5);
|
||||
#endif
|
||||
_TickMax=TickMax;
|
||||
PortPwmTo1=PortPwmMask;
|
||||
// initialise all channels
|
||||
for(uint8_t i=0 ; i<TINY_SOFT_PWM_CH_MAX ; i++)
|
||||
{
|
||||
Compare[i] = PwmToPwmMax(PwmInit); // set default PWM values
|
||||
PwmOrder[i] = Compare[i]; // set default PWM values
|
||||
}
|
||||
SREG = oldSREG;
|
||||
}
|
||||
|
||||
void TinySoftPwm_analogWrite(uint8_t PinIdx, uint8_t Pwm)
|
||||
{
|
||||
uint8_t RamIdx;
|
||||
|
||||
for(RamIdx=0;RamIdx<TINY_SOFT_PWM_CH_MAX;RamIdx++)
|
||||
{
|
||||
if(GET_INV_PIN_MSK(RamIdx)==((1<<PinIdx)^0xFF)) break;
|
||||
}
|
||||
if(RamIdx<TINY_SOFT_PWM_CH_MAX)
|
||||
{
|
||||
PwmOrder[RamIdx] = PwmToPwmMax(Pwm);
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t PwmToPwmMax(uint8_t Pwm)
|
||||
{
|
||||
return(map(Pwm, 0, 255, 0, _TickMax));
|
||||
}
|
||||
|
||||
void TinySoftPwm_process(void)
|
||||
{
|
||||
static uint8_t OvfCount=0xFF;
|
||||
|
||||
PortPwmTo0 = (~PortPwmTo1)^PortPwmMask;
|
||||
TINY_SOFT_PWM_PORT |= PortPwmTo1; // update ONLY used outputs to 1 without disturbing the others
|
||||
TINY_SOFT_PWM_PORT &= PortPwmTo0; // update ONLY used outputs to 0 without disturbing the others
|
||||
if(++OvfCount == _TickMax)
|
||||
{ // increment modulo 256 counter and update
|
||||
// the compare values only when counter = 0.
|
||||
OvfCount=0;
|
||||
#if (TINY_SOFT_PWM_CH_MAX >= 1)
|
||||
Compare[0] = PwmOrder[0]; // verbose code for speed
|
||||
#endif
|
||||
#if (TINY_SOFT_PWM_CH_MAX >= 2)
|
||||
Compare[1] = PwmOrder[1];
|
||||
#endif
|
||||
#if (TINY_SOFT_PWM_CH_MAX >= 3)
|
||||
Compare[2] = PwmOrder[2];
|
||||
#endif
|
||||
#if (TINY_SOFT_PWM_CH_MAX >= 4)
|
||||
Compare[3] = PwmOrder[3];
|
||||
#endif
|
||||
#if (TINY_SOFT_PWM_CH_MAX >= 5)
|
||||
Compare[4] = PwmOrder[4];
|
||||
#endif
|
||||
#if (TINY_SOFT_PWM_CH_MAX >= 6)
|
||||
Compare[5] = PwmOrder[5];
|
||||
#endif
|
||||
PortPwmTo1 = PortPwmMask; // set all port used pins high
|
||||
}
|
||||
// clear port pin on compare match (executed on next interrupt)
|
||||
#if (TINY_SOFT_PWM_CH_MAX >= 1)
|
||||
if(Compare[0] == OvfCount) TINY_SOFT_PWM_CLEAR_PIN(0);
|
||||
#endif
|
||||
#if (TINY_SOFT_PWM_CH_MAX >= 2)
|
||||
if(Compare[1] == OvfCount) TINY_SOFT_PWM_CLEAR_PIN(1);
|
||||
#endif
|
||||
#if (TINY_SOFT_PWM_CH_MAX >= 3)
|
||||
if(Compare[2] == OvfCount) TINY_SOFT_PWM_CLEAR_PIN(2);
|
||||
#endif
|
||||
#if (TINY_SOFT_PWM_CH_MAX >= 4)
|
||||
if(Compare[3] == OvfCount) TINY_SOFT_PWM_CLEAR_PIN(3);
|
||||
#endif
|
||||
#if (TINY_SOFT_PWM_CH_MAX >= 5)
|
||||
if(Compare[4] == OvfCount) TINY_SOFT_PWM_CLEAR_PIN(4);
|
||||
#endif
|
||||
#if (TINY_SOFT_PWM_CH_MAX >= 6)
|
||||
if(Compare[5] == OvfCount) TINY_SOFT_PWM_CLEAR_PIN(5);
|
||||
#endif
|
||||
}
|
@@ -0,0 +1,86 @@
|
||||
#ifndef TinySoftPwm_h
|
||||
#define TinySoftPwm_h
|
||||
|
||||
// a Tiny optimized Software PWM Manager (all pins must be part of the same port)
|
||||
// Only resources RAM/Program Memory of used pins are declared in the code at compilation time.
|
||||
// based largely on Atmel's AVR136: Low-Jitter Multi-Channel Software PWM Application Note:
|
||||
// http://www.atmel.com/dyn/resources/prod_documents/doc8020.pdf
|
||||
// RC Navy 2013
|
||||
// http://p.loussouarn.free.fr
|
||||
|
||||
#if defined(ARDUINO) && ARDUINO >= 100
|
||||
#include "Arduino.h"
|
||||
#else
|
||||
#include "WProgram.h"
|
||||
#endif
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
/*************************************************/
|
||||
/* Define here the PIN to use with Tiny Soft PWM */
|
||||
/* Unused Pin(s) SHALL be commented */
|
||||
/*************************************************/
|
||||
#define TINY_SOFT_PWM_USES_P0
|
||||
#define TINY_SOFT_PWM_USES_P1
|
||||
#define TINY_SOFT_PWM_USES_P2
|
||||
//#define TINY_SOFT_PWM_USES_P3 /* /!\ used for USB on DigiSpark: do not use it for PWM if DigiUSB is also used /!\ */
|
||||
//#define TINY_SOFT_PWM_USES_P4 /* /!\ used for USB on DigiSpark: do not use it for PWM if DigiUSB is also used /!\ */
|
||||
//#define TINY_SOFT_PWM_USES_P5
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*******************************************************************/
|
||||
/* Do NOT modify below: it's used to optimize RAM and Program size */
|
||||
/*******************************************************************/
|
||||
#ifdef TINY_SOFT_PWM_USES_P0
|
||||
#undef TINY_SOFT_PWM_USES_P0
|
||||
#define TINY_SOFT_PWM_USES_P0 1
|
||||
#else
|
||||
#define TINY_SOFT_PWM_USES_P0 0
|
||||
#endif
|
||||
|
||||
#ifdef TINY_SOFT_PWM_USES_P1
|
||||
#undef TINY_SOFT_PWM_USES_P1
|
||||
#define TINY_SOFT_PWM_USES_P1 1
|
||||
#else
|
||||
#define TINY_SOFT_PWM_USES_P1 0
|
||||
#endif
|
||||
|
||||
#ifdef TINY_SOFT_PWM_USES_P2
|
||||
#undef TINY_SOFT_PWM_USES_P2
|
||||
#define TINY_SOFT_PWM_USES_P2 1
|
||||
#else
|
||||
#define TINY_SOFT_PWM_USES_P2 0
|
||||
#endif
|
||||
|
||||
#ifdef TINY_SOFT_PWM_USES_P3
|
||||
#undef TINY_SOFT_PWM_USES_P3
|
||||
#define TINY_SOFT_PWM_USES_P3 1
|
||||
#else
|
||||
#define TINY_SOFT_PWM_USES_P3 0
|
||||
#endif
|
||||
|
||||
#ifdef TINY_SOFT_PWM_USES_P4
|
||||
#undef TINY_SOFT_PWM_USES_P4
|
||||
#define TINY_SOFT_PWM_USES_P4 1
|
||||
#else
|
||||
#define TINY_SOFT_PWM_USES_P4 0
|
||||
#endif
|
||||
|
||||
#ifdef TINY_SOFT_PWM_USES_P5
|
||||
#undef TINY_SOFT_PWM_USES_P5
|
||||
#define TINY_SOFT_PWM_USES_P5 1
|
||||
#else
|
||||
#define TINY_SOFT_PWM_USES_P5 0
|
||||
#endif
|
||||
|
||||
#define TINY_SOFT_PWM_CH_MAX (TINY_SOFT_PWM_USES_P0 + TINY_SOFT_PWM_USES_P1 + TINY_SOFT_PWM_USES_P2 + TINY_SOFT_PWM_USES_P3 + TINY_SOFT_PWM_USES_P4 + TINY_SOFT_PWM_USES_P5)
|
||||
|
||||
|
||||
void TinySoftPwm_begin(uint8_t TickMax, uint8_t PwmInit);
|
||||
void TinySoftPwm_analogWrite(uint8_t PinIdx, uint8_t Pwm);
|
||||
void TinySoftPwm_process(void);
|
||||
|
||||
#endif
|
@@ -0,0 +1,71 @@
|
||||
#include <TinySoftPwm.h>
|
||||
|
||||
/*
|
||||
_____ ____ __ _ ____ _ _ _ _
|
||||
| __ \ / __ \ | \ | | / __ \ | | | | | | | |
|
||||
| |__| | | / \_| | . \ | | / / \ \ | | | | \ \ / /
|
||||
| _ / | | _ | |\ \| | | |__| | | | | | \ ' /
|
||||
| | \ \ | \__/ | | | \ ' | | __ | \ \/ / | |
|
||||
|_| \_\ \____/ |_| \__| |_| |_| \__/ |_| 2013
|
||||
|
||||
http://p.loussouarn.free.fr
|
||||
|
||||
****************************************
|
||||
* <TinySoftPwm> library Demo *
|
||||
****************************************
|
||||
|
||||
This sketch increases the luminosity of the built-in LED of the Digispark.
|
||||
When the luminosity reaches its maximum, the luminosity decreases.
|
||||
When the luminosity reaches its minimum, the luminosity increases, and so on...
|
||||
|
||||
Note:
|
||||
====
|
||||
Declare the Pin(s) used in "librarie/TinySoftPwm/TinySoftPwm.h"
|
||||
In this sketch, #define TINY_SOFT_PWM_USES_P1 must be enabled (not commented) since it uses the DigiSpark built-in LED wired on P1.
|
||||
|
||||
In this basic example, TinySoftPwm_process() is called periodically using micros(), but it is recommanded to call it from a timer ISR
|
||||
to ensure a better periodicity.
|
||||
|
||||
*/
|
||||
|
||||
#define BUILT_IN_LED_PIN 1 /* Digispark Model A (Rev2) built-in LED pin number (Change it to 2 for Model B) */
|
||||
|
||||
void setup()
|
||||
{
|
||||
TinySoftPwm_begin(128, 0); /* 128 x TinySoftPwm_process() calls before overlap (Frequency tuning), 0 = PWM init for all declared pins */
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
static uint32_t StartUs=micros();
|
||||
static uint32_t StartMs=millis();
|
||||
static uint8_t Pwm=0;
|
||||
static int8_t Dir=1;
|
||||
|
||||
/***********************************************************/
|
||||
/* Call TinySoftPwm_process() with a period of 60 us */
|
||||
/* The PWM frequency = 128 x 60 # 7.7 ms -> F # 130Hz */
|
||||
/* 128 is the first argument passed to TinySoftPwm_begin() */
|
||||
/***********************************************************/
|
||||
if((micros() - StartUs) >= 60)
|
||||
{
|
||||
/* We arrived here every 60 microseconds */
|
||||
StartUs=micros();
|
||||
TinySoftPwm_process(); /* This function shall be called periodically (like here, based on micros(), or in a timer ISR) */
|
||||
}
|
||||
|
||||
/*************************************************************/
|
||||
/* Increment/decrement PWM on LED Pin with a period of 10 ms */
|
||||
/*************************************************************/
|
||||
if((millis()-StartMs) >= 10)
|
||||
{
|
||||
/* We arrived here every 10 milliseconds */
|
||||
StartMs=millis();
|
||||
Pwm+=Dir; /* increment or decrement PWM depending of sign of Dir */
|
||||
TinySoftPwm_analogWrite(BUILT_IN_LED_PIN, Pwm); /* Update built-in LED for Digispark */
|
||||
if(Pwm==255) Dir=-1; /* if PWM reaches the maximum: change direction */
|
||||
if(Pwm==0) Dir=+1; /* if PWM reaches the minimum: change direction */
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -0,0 +1,19 @@
|
||||
#######################################
|
||||
# Syntax Coloring Map TinySoftPwm
|
||||
#######################################
|
||||
|
||||
#######################################
|
||||
# Datatypes (KEYWORD1)
|
||||
#######################################
|
||||
TinySoftPwm KEYWORD1
|
||||
|
||||
#######################################
|
||||
# Methods and Functions (KEYWORD2)
|
||||
#######################################
|
||||
TinySoftPwm_begin KEYWORD2
|
||||
TinySoftPwm_analogWrite KEYWORD2
|
||||
TinySoftPwm_process KEYWORD2
|
||||
|
||||
#######################################
|
||||
# Constants (LITERAL1)
|
||||
#######################################
|
Reference in New Issue
Block a user