Skip to content

Instantly share code, notes, and snippets.

@prosper00
Last active January 20, 2021 22:30
Show Gist options
  • Save prosper00/f660fc299ad11a0ee02f94dce16487ae to your computer and use it in GitHub Desktop.
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)
/*
* 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