Friday, December 24, 2021

0000 0000 1000 0001

ffiXmas lights (part two)

It seems like the annual December project is to muck around with some festive LEDs, and what better way to finally introduce the famous 3 cent PMS150C than upgrading the previous ATTiny13 lights to the frightfully shy Padauk alternative.



Elements of this insanity over the last two years have been:

1. Scouring the forum for the latest information in the process of reverse engineering the chips and the programmer.

2. Making several versions of the programmer, until finally one works

3. Learning about how to program the PFS154 (MTP) so that I can try the PMS150 (OTP)

4. Use my usual insane Trial and Error and Error and Error Method™️ of programming until the resultant code works.


So here is the code that worked for me:

#include <pdk/device.h>
#include <delay.h>
#include <stdint.h>
#include "auto_sysclock.h"

int GLED = 3;
int RLED = 4;

#define turnGLedOn()         PA &= ~(1 << GLED)
#define turnGLedOff()        PA |= (1 << GLED)
#define turnRLedOn()         PA &= ~(1 << RLED)
#define turnRLedOff()        PA |= (1 << RLED)

unsigned char _sdcc_external_startup(void) {

  CLKMD = CLKMD_ILRC | CLKMD_ENABLE_ILRC | CLKMD_ENABLE_IHRC;
  CLKMD = CLKMD_ILRC | CLKMD_ENABLE_ILRC;

  return 0;.
}

void ledsoff() {
  turnGLedOff();
  turnRLedOff();
}

void greenon() {
  turnGLedOn();
  turnRLedOff();
}

void redon() {
  turnGLedOff();
  turnRLedOn();
}

void sleepfast() {

  TM2S  = TM2S_PRESCALE_NONE | TM2S_SCALE_DIV2;
  __stopexe();
}

void sleepslow() {

  TM2S  = TM2S_PRESCALE_DIV16 | TM2S_SCALE_DIV10;
  __stopexe();

}

void main(void) {

  PADIER = 0;
  INTEN = 0;
  INTRQ = 0;
  MISC = MISC_FAST_WAKEUP_ENABLE;
  TM2C  = TM2C_CLK_ILRC | TM2C_MODE_PWM;
  TM2CT = 0;
  TM2B  = 1;
  PAC |= (1 << GLED);
  PAC |= (1 << RLED);
  PAPH = 0;

  for (;;) {

    ledsoff();
    sleepslow();

    greenon();
    sleepfast();

    ledsoff();
    sleepslow();

    redon();
    sleepfast();
  }
}

The crucial timing code is this snippet:


void sleepfast() {

  TM2S  = TM2S_PRESCALE_NONE | TM2S_SCALE_DIV2;
  __stopexe();
}

void sleepslow() {

  TM2S  = TM2S_PRESCALE_DIV16 | TM2S_SCALE_DIV10;
  __stopexe();
}

...and by playing with the DIV## numbers I was able to get a flashing sequence pretty much on par with the old ATTiny13 version. A future video might involve hooking up my pathetic DSO138 oscilloscope to investigate that timing a little more closely.

Another "evolution" this year has been the LED size, down from 1206 to 0805. I'm not sure why, but I am assuming the smaller ones use less current? They certainly still light up a dark room though!

Finally it transpires that the GPIO maximum current in the PMS150C is puny at around 5mA - so I ditched the current limiting resistor and placed the LEDs in a charlieplexing arrangement from Pin5 to Pin6.

Works a treat as you can see below, and in tests it has shown more longevity in flashing away long after last year's version has expired. Good one! Has the ATTiny13 been de-throned as Champion of both austerity and efficiency?





No comments:

Post a Comment