Last active
January 20, 2021 22:30
-
-
Save prosper00/f660fc299ad11a0ee02f94dce16487ae to your computer and use it in GitHub Desktop.
Port of https://github.com/cpldcpu/CandleLEDhack/ for STM8/SDCC (Requires STM8 SPL)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* CandeflickerLED.c | |
* | |
* Created: 01.20.2021 | |
* | |
* Emulates a Candleflicker-LED on an STM8 microcontroller. | |
* Please use SDCC to compile and update the defines below according to your controller. | |
* (Require the ST SPL library, patched for SDCC): https://github.com/gicking/STM8-SPL_SDCC_patch | |
* | |
* Original code and research here: | |
* https://github.com/cpldcpu/CandleLEDhack/ | |
* | |
* Ported to STM8 by Brad Roy | |
*/ | |
#define F_CPU 16000000 | |
#include <stm8s.h> | |
void delay_us(uint16_t microseconds) { | |
TIM4->PSCR = TIM4_PRESCALER_1; // Set prescaler | |
// Set count to approximately 1uS (clock/microseconds in 1 second) | |
// The -1 adjusts for other runtime costs of this function | |
TIM4->ARR = ((16000000L)/1000000) - 1; | |
TIM4->CR1 = TIM4_CR1_CEN; // Enable counter | |
for (; microseconds > 1; --microseconds) { | |
while ((TIM4->SR1 & TIM4_SR1_UIF) == 0); | |
// Clear overflow flag | |
TIM4->SR1 &= ~TIM4_SR1_UIF; | |
} | |
} | |
/* | |
32 Bit maximum length LFSR | |
see http://www.ece.cmu.edu/~koopman/lfsr/index.html | |
Using inverted values so the LFSR also works with zero initialisiation. | |
*/ | |
uint8_t Rand(void) { | |
static uint32_t Z; | |
if (Z & 1) { Z = (Z >> 1); } | |
else { Z = (Z >> 1) ^ 0x7FFFF159; } | |
return (uint8_t)Z; | |
} | |
// Led connected to PD4 | |
#define LEDPORT GPIOD | |
#define LEDPIN GPIO_PIN_4 | |
int main(void) | |
{ | |
CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1); //set CPU to 16MHz | |
uint8_t PWM_CTR=0; // 4 bit-Counter | |
uint8_t FRAME_CTR=0; // 5 bit-Counter | |
uint8_t PWM_VAL=0; // 4 bit-Register | |
uint8_t NEXTBRIGHT=0; // 4 bit-Register | |
uint8_t RAND=0; // 5 bit Signal | |
uint8_t randflag=0; // 1 bit Signal | |
GPIO_Init(LEDPORT,LEDPIN,GPIO_MODE_OUT_PP_LOW_SLOW); | |
while(1) | |
{ | |
delay_us(1e6/440/16); // Main clock=440*16 Hz | |
// PWM | |
PWM_CTR++; | |
PWM_CTR&=0xf; // only 4 bit | |
if (PWM_CTR<=PWM_VAL) {GPIO_WriteHigh(LEDPORT,LEDPIN);} else {GPIO_WriteReverse(LEDPORT,LEDPIN);} | |
// FRAME | |
if (PWM_CTR==0) | |
{ | |
FRAME_CTR++; | |
FRAME_CTR&=0x1f; | |
if ((FRAME_CTR&0x07)==0) // generate a new random number every 8 cycles. In reality this is most likely bit serial | |
{ | |
RAND=Rand()&0x1f; | |
if ((RAND&0x0c)!=0) randflag=1; else randflag=0;// only update if valid | |
} | |
// NEW FRAME | |
if (FRAME_CTR==0) | |
{ | |
PWM_VAL=NEXTBRIGHT; // reload PWM | |
randflag=1; // force update at beginning of frame | |
} | |
if (randflag) | |
{ | |
NEXTBRIGHT=RAND>15?15:RAND; | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment