Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: fix: brightness depends on number of active leds in the column #56

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 38 additions & 21 deletions src/leddrv.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,27 @@ typedef enum {
typedef struct {
uint32_t *port_buf;
uint32_t *cfg_buf;
uint32_t *drv_buf;
uint32_t pin;
} pinctrl_t;

static void gpio_buf_set(pinctrl_t pinctl, tristate_t state)
static void gpio_buf_set(pinctrl_t pinctl, tristate_t state, int strength_20mA)
{
if (state == FLOATING) {
*(pinctl.cfg_buf) &= ~pinctl.pin;
// *(pinctl.drv_buf) &= ~pinctl.pin;
// *(pinctl.port_buf) &= ~pinctl.pin;
} else {
if (state == HIGH)
*(pinctl.port_buf) |= pinctl.pin;
else
*(pinctl.port_buf) &= ~pinctl.pin;

if (strength_20mA)
*(pinctl.drv_buf) |= pinctl.pin;
else
*(pinctl.drv_buf) &= ~pinctl.pin;

*(pinctl.cfg_buf) |= pinctl.pin;
}
}
Expand All @@ -37,35 +45,40 @@ void led_setDriveStrength(int is_20mA)

static void gpio_buf_apply(
volatile uint8_t *gpio_base,
uint32_t *port, uint32_t *cfg,
uint32_t *port, uint32_t *cfg, uint32_t *drv,
uint32_t *mask)
{
if (drive_strength) {
uint32_t *drv = (uint32_t *)(gpio_base + GPIO_PD_DRV);
*drv = (*drv & ~*mask) | (*cfg & *mask);
}
uint32_t *dir = (uint32_t *)(gpio_base + GPIO_DIR);
*dir = (*dir & ~*mask) | (*cfg & *mask);
uint32_t *drvr = (uint32_t *)(gpio_base + GPIO_PD_DRV);
*drvr = (*drvr & ~*mask) | (*drv & *mask);

// uint32_t *pu = (uint32_t *)(gpio_base + GPIO_PU);
// *pu = (*pu & ~*mask) | (*mask);

uint32_t *out = (uint32_t *)(gpio_base + GPIO_OUT);
*out = (*out & ~*mask) | (*port & *mask);
uint32_t *outr = (uint32_t *)(gpio_base + GPIO_OUT);
*outr = (*outr & ~*mask) | (*port & *mask);

uint32_t *dirr = (uint32_t *)(gpio_base + GPIO_DIR);
*dirr = (*dirr & ~*mask) | (*cfg & *mask);
}

static uint32_t PA_buf;
static uint32_t PB_buf;
static uint32_t PAcfg_buf;
static uint32_t PBcfg_buf;
static uint32_t PAdrv_buf;
static uint32_t PBdrv_buf;
static uint32_t PA_mask;
static uint32_t PB_mask;

#define GPIO_APPLY_ALL() \
gpio_buf_apply(BA_PA, &PA_buf, &PAcfg_buf, &PA_mask); \
gpio_buf_apply(BA_PB, &PB_buf, &PBcfg_buf, &PB_mask)
gpio_buf_apply(BA_PA, &PA_buf, &PAcfg_buf, &PAdrv_buf, &PA_mask); \
gpio_buf_apply(BA_PB, &PB_buf, &PBcfg_buf, &PBdrv_buf, &PB_mask)

#define PINCTRL(x, pin) { \
&P##x##_buf, \
&P##x##cfg_buf, \
GPIO_Pin_##pin \
&P##x##drv_buf, \
GPIO_Pin_##pin \
}

static const pinctrl_t led_pins[LED_PINCOUNT] = {
Expand Down Expand Up @@ -108,19 +121,22 @@ void led_init()
}
}

void leds_releaseall() {
for (int i=0; i<LED_PINCOUNT; i++)
gpio_buf_set(led_pins[i], FLOATING);
GPIO_APPLY_ALL();
void leds_releaseall()
{
uint32_t *dirr = (uint32_t *)(BA_PA + GPIO_DIR);
*dirr = (*dirr & ~PA_mask);
dirr = (uint32_t *)(BA_PB + GPIO_DIR);
*dirr = (*dirr & ~PB_mask);
}

static void led_write2dcol_raw(int dcol, uint32_t val)
{
// TODO: assert params
gpio_buf_set(led_pins[dcol], HIGH);
gpio_buf_set(led_pins[dcol], HIGH, 1);
for (int i=0; i<LED_PINCOUNT; i++) {
if (i == dcol) continue;
gpio_buf_set(led_pins[i], (val & 0x01) ? LOW : FLOATING); // danger: floating=0 (led off) or low=1 (led on)
gpio_buf_set(led_pins[i], (val & 0x01) ? LOW : FLOATING,
drive_strength); // danger: floating=0 (led off) or low=1 (led on)
val >>= 1;
}
GPIO_APPLY_ALL();
Expand Down Expand Up @@ -158,10 +174,11 @@ void led_write2row_raw(int row, int which_half, uint32_t val)
{
row = row*2 + (which_half != 0);

gpio_buf_set(led_pins[row], LOW);
gpio_buf_set(led_pins[row], LOW, 1);
for (int i=0; i<LED_PINCOUNT; i++) {
if (i == row) continue;
gpio_buf_set(led_pins[i], (val & 0x01) ? HIGH : FLOATING);
gpio_buf_set(led_pins[i], (val & 0x01) ? HIGH : FLOATING,
drive_strength);
val >>= 1;
}
GPIO_APPLY_ALL();
Expand Down
Loading