/led-test.c
#include <stdint.h>
#define CKCU_BASE 0x40088000
#define AHBCCR 0x24
#define GPIOB_BASE 0x400b2000
#define DIRCR 0x000 // Port A Data Direction Control Register
#define INER 0x004 // Port A Input Function Enable Control Register
#define PUR 0x008 // Port A Pull-Up Selection Register
#define PDR 0x00C // Port A Pull-Down Selection Register
#define ODR 0x010 // Port A Open Drain Selection Register
#define DRVR 0x014 // Port A Drive Current Selection Register
#define LOCKR 0x018 // Port A Lock Register
#define DINR 0x01C // Port A Data Input Register
#define DOUTR 0x020 // Port A Data Output Register
#define SRR 0x024 // Port A Output Set and Reset Control Register
#define RR 0x028 // Port A Output Reset Control Register
#define LED_D_OFF (*(uint32_t*)(GPIOB_BASE + SRR) = 1)
#define LED_D_ON (*(uint32_t*)(GPIOB_BASE + SRR) = 1 << 16)
void sendword(uint32_t w);
void delay(int n) {
n <<= 4;
for (int i = 0; i < n; i++) {
__asm__("nop");
}
}
void reset() {
LED_D_OFF;
delay(100);
}
// a * (c / 255) + b * ((255 - c) / 255)
uint32_t lerp(uint32_t a, uint32_t b, uint8_t c) {
uint8_t* aa = (uint8_t*)&a;
uint8_t* bb = (uint8_t*)&b;
uint32_t r;
uint8_t* rr = (uint8_t*)&r;
for (int i = 0; i < 3; i++) {
uint32_t ac = ((uint32_t)aa[i] * c) / 255;
uint32_t bc = ((uint64_t)bb[i] * (255 - c)) / 255;
rr[i] = (uint8_t)ac + bc;
}
return r;
}
void main() {
// Enable GPIOB peripheral
*(uint32_t*)(CKCU_BASE + AHBCCR) |= 0x00020000;
// Enable output direction on B0
*(uint32_t*)(GPIOB_BASE + DIRCR) = 1;
uint8_t j = 0;
uint32_t values[15];
while (1) {
for (int i = 0; i < 15; i++) {
//values[i] = lerp(0x002020, 0x400000, (j + i * 10) % 255);
values[i] = (i % 2) ^ (j < 128) ? (j < 128 ? 0x000f0f : 0x1e0000) : 0x000000;
}
for (int i = 0; i < 15; i++) {
sendword(values[i]);
}
delay(1000);
j += 5;
}
}