switch to setup for Arduino Boards Manager

This commit is contained in:
Erik Tylek Kettenburg
2015-06-23 12:42:35 -07:00
parent bc55c9bb45
commit 6ca6b114d5
3581 changed files with 93 additions and 51 deletions

View File

@@ -0,0 +1,39 @@
TinySoftPwm library
===================
**TinySoftPwm** is a library designed to generate PWM signals by software.
Some examples of use cases:
-------------------------
* **RGB strip LED Controller**
* **DC Motor controller**
* **Digital to Analog converter**
Supported Arduinos:
------------------
* **ATtiny85 (Standalone or Digispark)** (up to 6 software PWM supported)
* **ATtiny167 (Digispark pro)** (up to 13 software PWM supported)
API/methods:
-----------
* TinySoftPwm_begin()
* TinySoftPwm_analogWrite()
* TinySoftPwm_process()
Design considerations:
---------------------
In order to reduce **program** and **RAM** memories, PWM pins shall be declared in the **TinySoftPwm.h** file. All the required amount of **program** and **RAM** memories are allocated at compilation time.
The **TinySoftPwm_process()** method shall be called periodically:
* using micros() in the loop(): in this case, asynchronous programmation shall be used: no call to blocking functions such as delay() is permitted.
* or better using periodic interruption.
In order to reduce the memory footprint (programm and RAM), try to use the PWM on pins which are part of the same port: PORTA or PORTB.
Contact
-------
If you have some ideas of enhancement, please contact me by clicking on: [RC Navy](http://p.loussouarn.free.fr/contact.html).

View File

@@ -0,0 +1,299 @@
// 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-2015
// http://p.loussouarn.free.fr
// 11/01/2015: Multi port support added for ATtiny167
#include <TinySoftPwm.h>
#if (TINY_SOFT_PWM_CH_MAX == 0)
#error At least one PWM pin shall be declared in TinySoftPwm.h
#endif
#if defined(TINY_SOFT_PWM_DDR1) && defined(TINY_SOFT_PWM_DDR0)
#define TINY_SOFT_PWM_DECLARE_PIN(Pin) do{ \
if(digitalPinToPortIdx(Pin)) \
{ \
TINY_SOFT_PWM_DDR1 |= (1 << digitalPinToPortBit(Pin)); \
Port1_PwmMask |= (1 << digitalPinToPortBit(Pin)); \
} \
else \
{ \
TINY_SOFT_PWM_DDR0 |= (1 << digitalPinToPortBit(Pin)); \
Port0_PwmMask |= (1 << digitalPinToPortBit(Pin)); \
} \
}while(0)
#define TINY_SOFT_PWM_CLEAR_PIN(RamIdx) GET_PWM_PIN_PORT(RamIdx) \
? (Port1_PwmTo1 &= GET_PWM_INV_MSK(RamIdx)) \
: (Port0_PwmTo1 &= GET_PWM_INV_MSK(RamIdx))
#else
#if defined(TINY_SOFT_PWM_DDR1)
#define TINY_SOFT_PWM_DECLARE_PIN(Pin) TINY_SOFT_PWM_DDR1 |= (1 << digitalPinToPortBit(Pin)); Port1_PwmMask |= (1 << digitalPinToPortBit(Pin))
#define TINY_SOFT_PWM_CLEAR_PIN(RamIdx) Port1_PwmTo1 &= GET_PWM_INV_MSK(RamIdx)
#else
#define TINY_SOFT_PWM_DECLARE_PIN(Pin) TINY_SOFT_PWM_DDR0 |= (1 << digitalPinToPortBit(Pin)); Port0_PwmMask |= (1 << digitalPinToPortBit(Pin))
#define TINY_SOFT_PWM_CLEAR_PIN(RamIdx) Port0_PwmTo1 &= GET_PWM_INV_MSK(RamIdx)
#endif
#endif
#define GET_PWM_PIN_ID(RamIdx) ((uint8_t)pgm_read_byte(&PwmPin[(RamIdx)].Id))
#define GET_PWM_PIN_PORT(RamIdx) ((uint8_t)pgm_read_byte(&PwmPin[(RamIdx)].Port))
#define GET_PWM_INV_MSK(RamIdx) ((uint8_t)pgm_read_byte(&PwmPin[(RamIdx)].InvMsk))
typedef struct {
uint8_t Id;
uint8_t Port;
uint8_t InvMsk;
}SoftPwmPinSt_t;
const SoftPwmPinSt_t PwmPin[] PROGMEM ={
#if (TINY_SOFT_PWM_USES_PIN0 == 1)
{0, digitalPinToPortIdx(0), ~(1 << digitalPinToPortBit(0))},
#endif
#if (TINY_SOFT_PWM_USES_PIN1 == 1)
{1, digitalPinToPortIdx(1), ~(1 << digitalPinToPortBit(1))},
#endif
#if (TINY_SOFT_PWM_USES_PIN2 == 1)
{2, digitalPinToPortIdx(2), ~(1 << digitalPinToPortBit(2))},
#endif
#if (TINY_SOFT_PWM_USES_PIN3 == 1)
{3, digitalPinToPortIdx(3), ~(1 << digitalPinToPortBit(3))},
#endif
#if (TINY_SOFT_PWM_USES_PIN4 == 1)
{4, digitalPinToPortIdx(4), ~(1 << digitalPinToPortBit(4))},
#endif
#if (TINY_SOFT_PWM_USES_PIN5 == 1)
{5, digitalPinToPortIdx(5), ~(1 << digitalPinToPortBit(5))},
#endif
#if defined (__AVR_ATtiny167__)
#if (TINY_SOFT_PWM_USES_PIN6 == 1)
{6, digitalPinToPortIdx(6), ~(1 << digitalPinToPortBit(6))},
#endif
#if (TINY_SOFT_PWM_USES_PIN7 == 1)
{7, digitalPinToPortIdx(7), ~(1 << digitalPinToPortBit(7))},
#endif
#if (TINY_SOFT_PWM_USES_PIN8 == 1)
{8, digitalPinToPortIdx(8), ~(1 << digitalPinToPortBit(8))},
#endif
#if (TINY_SOFT_PWM_USES_PIN9 == 1)
{9, digitalPinToPortIdx(9), ~(1 << digitalPinToPortBit(9))},
#endif
#if (TINY_SOFT_PWM_USES_PIN10 == 1)
{10, digitalPinToPortIdx(10), ~(1 << digitalPinToPortBit(10))},
#endif
#if (TINY_SOFT_PWM_USES_PIN11 == 1)
{11, digitalPinToPortIdx(11), ~(1 << digitalPinToPortBit(11))},
#endif
#if (TINY_SOFT_PWM_USES_PIN12 == 1)
{12, digitalPinToPortIdx(12), ~(1 << digitalPinToPortBit(12))},
#endif
#endif
};
static uint8_t Compare[TINY_SOFT_PWM_CH_MAX];
volatile uint8_t PwmOrder[TINY_SOFT_PWM_CH_MAX];
#ifdef TINY_SOFT_PWM_PORT0
static uint8_t Port0_PwmMask = 0;
volatile uint8_t Port0_PwmTo1 = 0x00;
volatile uint8_t Port0_PwmTo0 = 0xFF;
#endif
#ifdef TINY_SOFT_PWM_PORT1
static uint8_t Port1_PwmMask = 0;
volatile uint8_t Port1_PwmTo1 = 0x00;
volatile uint8_t Port1_PwmTo0 = 0xFF;
#endif
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_PIN0 == 1)
TINY_SOFT_PWM_DECLARE_PIN(0);
#endif
#if (TINY_SOFT_PWM_USES_PIN1 == 1)
TINY_SOFT_PWM_DECLARE_PIN(1);
#endif
#if (TINY_SOFT_PWM_USES_PIN2 == 1)
TINY_SOFT_PWM_DECLARE_PIN(2);
#endif
#if (TINY_SOFT_PWM_USES_PIN3 == 1)
TINY_SOFT_PWM_DECLARE_PIN(3);
#endif
#if (TINY_SOFT_PWM_USES_PIN4 == 1)
TINY_SOFT_PWM_DECLARE_PIN(4);
#endif
#if (TINY_SOFT_PWM_USES_PIN5 == 1)
TINY_SOFT_PWM_DECLARE_PIN(5);
#endif
#if (TINY_SOFT_PWM_USES_PIN6 == 1)
TINY_SOFT_PWM_DECLARE_PIN(6);
#endif
#if (TINY_SOFT_PWM_USES_PIN7 == 1)
TINY_SOFT_PWM_DECLARE_PIN(7);
#endif
#if (TINY_SOFT_PWM_USES_PIN8 == 1)
TINY_SOFT_PWM_DECLARE_PIN(8);
#endif
#if (TINY_SOFT_PWM_USES_PIN9 == 1)
TINY_SOFT_PWM_DECLARE_PIN(9);
#endif
#if (TINY_SOFT_PWM_USES_PIN10 == 1)
TINY_SOFT_PWM_DECLARE_PIN(10);
#endif
#if (TINY_SOFT_PWM_USES_PIN11 == 1)
TINY_SOFT_PWM_DECLARE_PIN(11);
#endif
#if (TINY_SOFT_PWM_USES_PIN12 == 1)
TINY_SOFT_PWM_DECLARE_PIN(12);
#endif
_TickMax = TickMax;
#ifdef TINY_SOFT_PWM_PORT0
Port0_PwmTo1 = Port0_PwmMask;
#endif
#ifdef TINY_SOFT_PWM_PORT1
Port1_PwmTo1 = Port1_PwmMask;
#endif
// 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 Pin, uint8_t Pwm)
{
uint8_t RamIdx;
for(RamIdx = 0; RamIdx < TINY_SOFT_PWM_CH_MAX; RamIdx++)
{
if(GET_PWM_PIN_ID(RamIdx) == Pin) break;
}
if(RamIdx < TINY_SOFT_PWM_CH_MAX)
{
PwmOrder[RamIdx] = PwmToPwmMax(Pwm);
}
}
static uint8_t PwmToPwmMax(uint8_t Pwm)
{
uint16_t Pwm16;
Pwm16 = map(Pwm, 0, 255, 0, _TickMax);
Pwm16 = constrain(Pwm16, 0, _TickMax);
return((uint8_t)Pwm16);
}
void TinySoftPwm_process(void)
{
static uint8_t OvfCount=0xFF;
#ifdef TINY_SOFT_PWM_PORT0
Port0_PwmTo0 = (~Port0_PwmTo1) ^ Port0_PwmMask;
TINY_SOFT_PWM_PORT0 |= Port0_PwmTo1; // update ONLY used outputs to 1 without disturbing the others
TINY_SOFT_PWM_PORT0 &= Port0_PwmTo0; // update ONLY used outputs to 0 without disturbing the others
#endif
#ifdef TINY_SOFT_PWM_PORT1
Port1_PwmTo0 = (~Port1_PwmTo1) ^ Port1_PwmMask;
TINY_SOFT_PWM_PORT1 |= Port1_PwmTo1; // update ONLY used outputs to 1 without disturbing the others
TINY_SOFT_PWM_PORT1 &= Port1_PwmTo0; // update ONLY used outputs to 0 without disturbing the others
#endif
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
#if (TINY_SOFT_PWM_CH_MAX >= 7)
Compare[6] = PwmOrder[6]; // verbose code for speed
#endif
#if (TINY_SOFT_PWM_CH_MAX >= 8)
Compare[7] = PwmOrder[7];
#endif
#if (TINY_SOFT_PWM_CH_MAX >= 9)
Compare[8] = PwmOrder[8];
#endif
#if (TINY_SOFT_PWM_CH_MAX >= 10)
Compare[9] = PwmOrder[9];
#endif
#if (TINY_SOFT_PWM_CH_MAX >= 11)
Compare[10] = PwmOrder[10];
#endif
#if (TINY_SOFT_PWM_CH_MAX >= 12)
Compare[11] = PwmOrder[11];
#endif
#if (TINY_SOFT_PWM_CH_MAX >= 13)
Compare[12] = PwmOrder[12];
#endif
#ifdef TINY_SOFT_PWM_PORT0
Port0_PwmTo1 = Port0_PwmMask; // set all port used pins high
#endif
#ifdef TINY_SOFT_PWM_PORT1
Port1_PwmTo1 = Port1_PwmMask; // set all port used pins high
#endif
}
// 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
#if (TINY_SOFT_PWM_CH_MAX >= 7)
if(Compare[6] == OvfCount) TINY_SOFT_PWM_CLEAR_PIN(6);
#endif
#if (TINY_SOFT_PWM_CH_MAX >= 8)
if(Compare[7] == OvfCount) TINY_SOFT_PWM_CLEAR_PIN(7);
#endif
#if (TINY_SOFT_PWM_CH_MAX >= 9)
if(Compare[8] == OvfCount) TINY_SOFT_PWM_CLEAR_PIN(8);
#endif
#if (TINY_SOFT_PWM_CH_MAX >= 10)
if(Compare[9] == OvfCount) TINY_SOFT_PWM_CLEAR_PIN(9);
#endif
#if (TINY_SOFT_PWM_CH_MAX >= 11)
if(Compare[10] == OvfCount) TINY_SOFT_PWM_CLEAR_PIN(10);
#endif
#if (TINY_SOFT_PWM_CH_MAX >= 12)
if(Compare[11] == OvfCount) TINY_SOFT_PWM_CLEAR_PIN(11);
#endif
#if (TINY_SOFT_PWM_CH_MAX >= 13)
if(Compare[12] == OvfCount) TINY_SOFT_PWM_CLEAR_PIN(12);
#endif
}

View File

@@ -0,0 +1,192 @@
#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-2015
// http://p.loussouarn.free.fr
// 11/01/2015: Automated multi port support (at compilation time) added for ATtiny167
#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_PIN0
#define TINY_SOFT_PWM_USES_PIN1
#define TINY_SOFT_PWM_USES_PIN2
#define TINY_SOFT_PWM_USES_PIN3 /* /!\ used for USB on DigiSpark (pro): do not use it for PWM if DigiUSB or SerialCDC are also used /!\ */
#define TINY_SOFT_PWM_USES_PIN4 /* /!\ used for USB on DigiSpark (pro): do not use it for PWM if DigiUSB or SerialCDC are also used /!\ */
#define TINY_SOFT_PWM_USES_PIN5
#define TINY_SOFT_PWM_USES_PIN6
#define TINY_SOFT_PWM_USES_PIN7
#define TINY_SOFT_PWM_USES_PIN8
#define TINY_SOFT_PWM_USES_PIN9
#define TINY_SOFT_PWM_USES_PIN10
#define TINY_SOFT_PWM_USES_PIN11
#define TINY_SOFT_PWM_USES_PIN12
/*******************************************************************/
/* Do NOT modify below: it's used to optimize RAM and Program size */
/*******************************************************************/
#if defined (__AVR_ATtiny85__)
#undef TINY_SOFT_PWM_USES_PIN6
#undef TINY_SOFT_PWM_USES_PIN7
#undef TINY_SOFT_PWM_USES_PIN8
#undef TINY_SOFT_PWM_USES_PIN9
#undef TINY_SOFT_PWM_USES_PIN10
#undef TINY_SOFT_PWM_USES_PIN11
#undef TINY_SOFT_PWM_USES_PIN12
#endif
#ifdef TINY_SOFT_PWM_USES_PIN0
#undef TINY_SOFT_PWM_USES_PIN0
#define TINY_SOFT_PWM_USES_PIN0 1
#else
#define TINY_SOFT_PWM_USES_PIN0 0
#endif
#ifdef TINY_SOFT_PWM_USES_PIN1
#undef TINY_SOFT_PWM_USES_PIN1
#define TINY_SOFT_PWM_USES_PIN1 1
#else
#define TINY_SOFT_PWM_USES_PIN1 0
#endif
#ifdef TINY_SOFT_PWM_USES_PIN2
#undef TINY_SOFT_PWM_USES_PIN2
#define TINY_SOFT_PWM_USES_PIN2 1
#else
#define TINY_SOFT_PWM_USES_PIN2 0
#endif
#ifdef TINY_SOFT_PWM_USES_PIN3
#undef TINY_SOFT_PWM_USES_PIN3
#define TINY_SOFT_PWM_USES_PIN3 1
#else
#define TINY_SOFT_PWM_USES_PIN3 0
#endif
#ifdef TINY_SOFT_PWM_USES_PIN4
#undef TINY_SOFT_PWM_USES_PIN4
#define TINY_SOFT_PWM_USES_PIN4 1
#else
#define TINY_SOFT_PWM_USES_PIN4 0
#endif
#ifdef TINY_SOFT_PWM_USES_PIN5
#undef TINY_SOFT_PWM_USES_PIN5
#define TINY_SOFT_PWM_USES_PIN5 1
#else
#define TINY_SOFT_PWM_USES_PIN5 0
#endif
#ifdef TINY_SOFT_PWM_USES_PIN6
#undef TINY_SOFT_PWM_USES_PIN6
#define TINY_SOFT_PWM_USES_PIN6 1
#else
#define TINY_SOFT_PWM_USES_PIN6 0
#endif
#ifdef TINY_SOFT_PWM_USES_PIN7
#undef TINY_SOFT_PWM_USES_PIN7
#define TINY_SOFT_PWM_USES_PIN7 1
#else
#define TINY_SOFT_PWM_USES_PIN7 0
#endif
#ifdef TINY_SOFT_PWM_USES_PIN8
#undef TINY_SOFT_PWM_USES_PIN8
#define TINY_SOFT_PWM_USES_PIN8 1
#else
#define TINY_SOFT_PWM_USES_PIN8 0
#endif
#ifdef TINY_SOFT_PWM_USES_PIN9
#undef TINY_SOFT_PWM_USES_PIN9
#define TINY_SOFT_PWM_USES_PIN9 1
#else
#define TINY_SOFT_PWM_USES_PIN9 0
#endif
#ifdef TINY_SOFT_PWM_USES_PIN10
#undef TINY_SOFT_PWM_USES_PIN10
#define TINY_SOFT_PWM_USES_PIN10 1
#else
#define TINY_SOFT_PWM_USES_PIN10 0
#endif
#ifdef TINY_SOFT_PWM_USES_PIN11
#undef TINY_SOFT_PWM_USES_PIN11
#define TINY_SOFT_PWM_USES_PIN11 1
#else
#define TINY_SOFT_PWM_USES_PIN11 0
#endif
#ifdef TINY_SOFT_PWM_USES_PIN12
#undef TINY_SOFT_PWM_USES_PIN12
#define TINY_SOFT_PWM_USES_PIN12 1
#else
#define TINY_SOFT_PWM_USES_PIN12 0
#endif
#define TINY_SOFT_PWM_CH_MAX (TINY_SOFT_PWM_USES_PIN0 + TINY_SOFT_PWM_USES_PIN1 + TINY_SOFT_PWM_USES_PIN2 + \
TINY_SOFT_PWM_USES_PIN3 + TINY_SOFT_PWM_USES_PIN4 + TINY_SOFT_PWM_USES_PIN5 + \
TINY_SOFT_PWM_USES_PIN6 + TINY_SOFT_PWM_USES_PIN7 + TINY_SOFT_PWM_USES_PIN8 + \
TINY_SOFT_PWM_USES_PIN9 + TINY_SOFT_PWM_USES_PIN10+ TINY_SOFT_PWM_USES_PIN11+ \
TINY_SOFT_PWM_USES_PIN12)
#if defined (__AVR_ATtiny85__)
#define TINY_SOFT_PWM_USES_PORT0 0
#define TINY_SOFT_PWM_USES_PORT1 1
#ifndef digitalPinToPortIdx
#define digitalPinToPortIdx(p) 1
#endif
#else
#if defined (__AVR_ATtiny167__)
#define TINY_SOFT_PWM_USES_PORT0 (TINY_SOFT_PWM_USES_PIN5 || TINY_SOFT_PWM_USES_PIN6 || TINY_SOFT_PWM_USES_PIN7 || \
TINY_SOFT_PWM_USES_PIN8 || TINY_SOFT_PWM_USES_PIN9 || TINY_SOFT_PWM_USES_PIN10 || \
TINY_SOFT_PWM_USES_PIN11 || TINY_SOFT_PWM_USES_PIN12)
#define TINY_SOFT_PWM_USES_PORT1 (TINY_SOFT_PWM_USES_PIN0 || TINY_SOFT_PWM_USES_PIN1 || TINY_SOFT_PWM_USES_PIN2 || \
TINY_SOFT_PWM_USES_PIN3 || TINY_SOFT_PWM_USES_PIN4)
#ifndef digitalPinToPortIdx
#define digitalPinToPortIdx(p) (((p) >= 5 && (p) <= 12) ? (0) : (1))
#endif
#endif
#endif
#if (TINY_SOFT_PWM_USES_PORT0 == 1)
#undef TINY_SOFT_PWM_USES_PORT0
#define TINY_SOFT_PWM_PORT0 PORTA
#define TINY_SOFT_PWM_DDR0 DDRA
#endif
#if (TINY_SOFT_PWM_USES_PORT1 == 1)
#undef TINY_SOFT_PWM_USES_PORT1
#define TINY_SOFT_PWM_PORT1 PORTB
#define TINY_SOFT_PWM_DDR1 DDRB
#endif
#ifndef digitalPinToPortBit
#define digitalPinToPortBit(p) digitalPinToPCMSKbit(p)
#endif
/* Public Function Prototypes */
void TinySoftPwm_begin(uint8_t TickMax, uint8_t PwmInit);
void TinySoftPwm_analogWrite(uint8_t Pin, uint8_t Pwm);
void TinySoftPwm_process(void);
#endif

View File

@@ -0,0 +1,75 @@
#include <TinySoftPwm.h>
/*
_____ ____ __ _ ____ _ _ _ _
| __ \ / __ \ | \ | | / __ \ | | | | | | | |
| |__| | | / \_| | . \ | | / / \ \ | | | | \ \ / /
| _ / | | _ | |\ \| | | |__| | | | | | \ ' /
| | \ \ | \__/ | | | \ ' | | __ | \ \/ / | |
|_| \_\ \____/ |_| \__| |_| |_| \__/ |_| 2015
http://p.loussouarn.free.fr
****************************************
* <TinySoftPwm> library Demo *
****************************************
This sketch generates simultaneously PWM signals on 13 pins (Pin 0 to pin 12 of the Digispark pro).
It also increases the luminosity of the built-in LED of the Digispark whilst the duty cycle remains constant for all other pins.
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_PINO to TINY_SOFT_PWM_USES_PIN12 must be enabled (not commented) since it uses the first 13 pins of the DigiSpark pro.
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(255, 0); /* 255 x TinySoftPwm_process() calls before overlap (Frequency tuning), 0 = PWM init for all declared pins */
for(uint8_t PinIdx = 0; PinIdx <= 12; PinIdx++)
{
TinySoftPwm_analogWrite(PinIdx, (PinIdx + 1) * 19); /* Low to high duty cycle for pin 0 to 12 */
}
}
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 40 us */
/* The PWM frequency = 255 x 40 # 10.2 ms -> F # 100Hz */
/* 255 is the first argument passed to TinySoftPwm_begin() */
/***********************************************************/
if((micros() - StartUs) >= 40)
{
/* We arrived here every 40 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 */
}
}

View File

@@ -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 */
}
}

View File

@@ -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)
#######################################