/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

#include <assert.h>
#include <string.h>
#include <stdio.h>
#include "sysinit/sysinit.h"
#include "os/os.h"
#include "bsp/bsp.h"
#include "pwm/pwm.h"
#include "nrfx.h"
#include "nrfx_pwm.h"
#include "ws2812.h"

#define BITS_PER_SEQ    (24)
#define BIT0            (0x8000 | 6)
#define BIT1            (0x8000 | 11)

static const nrfx_pwm_t pwm = NRFX_PWM_INSTANCE(WS2812_PWM);

static const nrfx_pwm_config_t pwm_config = {
    .output_pins = { WS2812_GPIO, NRFX_PWM_PIN_NOT_USED, NRFX_PWM_PIN_NOT_USED, NRFX_PWM_PIN_NOT_USED },
    .irq_priority = 3,
    .base_clock = NRF_PWM_CLK_16MHz,
    .count_mode = NRF_PWM_MODE_UP,
    .top_value = 20,
    .load_mode = NRF_PWM_LOAD_COMMON,
    .step_mode = NRF_PWM_STEP_AUTO,
};

static uint16_t pwm_seq_values[2][BITS_PER_SEQ];

static const nrf_pwm_sequence_t pwm_seq[2] = {
        {
            .values.p_raw = pwm_seq_values[0],
            .length = BITS_PER_SEQ,
            .repeats = 0,
            .end_delay = 0,
        }, {
            .values.p_raw = pwm_seq_values[1],
            .length = BITS_PER_SEQ,
            .repeats = 0,
            .end_delay = 0,
        },
};

static uint32_t led_color[WS2812_NUM_LED];
static int led_idx;

static void
load_pixel(void)
{
    uint16_t *seq_values;
    uint32_t grb;
    int i;

    seq_values = pwm_seq_values[led_idx & 1];
    grb = led_color[led_idx];

    for (i = 0; i < BITS_PER_SEQ; i++) {
        *seq_values = grb & 0x800000 ? BIT1 : BIT0;
        grb <<= 1;
        seq_values++;
    }

    led_idx++;
}

static void
pwm_handler_func(nrfx_pwm_evt_type_t event_type)
{
    switch (event_type) {
    case NRFX_PWM_EVT_END_SEQ0:
    case NRFX_PWM_EVT_END_SEQ1:
        load_pixel();
        break;
    default:
        break;
    }
}

int
ws2812_init(void)
{
    nrfx_err_t err;

    err = nrfx_pwm_init(&pwm, &pwm_config, pwm_handler_func);

    return err != NRFX_SUCCESS;
}

int
ws2812_write(const uint32_t *rgb)
{
    uint32_t grb;
    int i;

    for (i = 0; i < WS2812_NUM_LED; i++) {
        grb = 0;
        grb |= (rgb[i] & 0x00FF00) << 8;
        grb |= (rgb[i] & 0xFF0000) >> 8;
        grb |= (rgb[i] & 0x0000FF);

        led_color[i] = grb;
    }

    led_idx = 0;

    load_pixel();
    load_pixel();
    nrfx_pwm_complex_playback(&pwm, &pwm_seq[0], &pwm_seq[1], WS2812_NUM_LED,
                              NRFX_PWM_FLAG_SIGNAL_END_SEQ0 |
                              NRFX_PWM_FLAG_SIGNAL_END_SEQ1 |
                              NRFX_PWM_FLAG_STOP);

    return 0;
}
