/*
Copyright 2018 Massdrop Inc.

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef _D51_UTIL_H_
#define _D51_UTIL_H_

#include "samd51j18a.h"

//TODO: PS: Should bring these ports out to keyboard level configuration

//Debug LED PA27
#define led_ena REG_PORT_DIRSET0 = 0x08000000 //PA27 Output
#define led_on  REG_PORT_OUTSET0 = 0x08000000 //PA27 High
#define led_off REG_PORT_OUTCLR0 = 0x08000000 //PA27 Low

//Debug Port PB30
#define m15_ena REG_PORT_DIRSET1 = 0x40000000 //PB30 Output
#define m15_on  REG_PORT_OUTSET1 = 0x40000000 //PB30 High
#define m15_off REG_PORT_OUTCLR1 = 0x40000000 //PB30 Low

//Debug Port PB23
#define m27_ena REG_PORT_DIRSET1 = 0x800000 //PB23 Output
#define m27_on  REG_PORT_OUTSET1 = 0x800000 //PB23 High
#define m27_off REG_PORT_OUTCLR1 = 0x800000 //PB23 Low

//Debug Port PB31
#define m28_ena REG_PORT_DIRSET1 = 0x80000000 //PB31 Output
#define m28_on  REG_PORT_OUTSET1 = 0x80000000 //PB31 High
#define m28_off REG_PORT_OUTCLR1 = 0x80000000 //PB31 Low

#define m15_loop(M15X) {uint8_t M15L=M15X; while(M15L--){m15_on;CLK_delay_us(1);m15_off;}}

void m15_print(uint32_t x);
void dled_print(uint32_t x, uint8_t long_pause);

void debug_code_init(void);
void debug_code_disable(void);

#ifdef DEBUG_BOOT_TRACING

#define DBGC(n) debug_code = n

extern volatile uint32_t debug_code;

enum debug_code_list {
    DC_UNSET = 0,
    DC_CLK_INIT_BEGIN,
    DC_CLK_INIT_COMPLETE,
    DC_CLK_SET_I2C1_FREQ_BEGIN,
    DC_CLK_SET_I2C1_FREQ_COMPLETE,
    DC_CLK_SET_I2C0_FREQ_BEGIN,
    DC_CLK_SET_I2C0_FREQ_COMPLETE,
    DC_CLK_SET_SPI_FREQ_BEGIN,
    DC_CLK_SET_SPI_FREQ_COMPLETE,
    DC_CLK_ENABLE_TIMEBASE_BEGIN,
    DC_CLK_ENABLE_TIMEBASE_SYNC_ENABLE,
    DC_CLK_ENABLE_TIMEBASE_SYNC_SWRST_1,
    DC_CLK_ENABLE_TIMEBASE_SYNC_SWRST_2,
    DC_CLK_ENABLE_TIMEBASE_TC4_BEGIN,
    DC_CLK_ENABLE_TIMEBASE_TC4_SYNC_DISABLE,
    DC_CLK_ENABLE_TIMEBASE_TC4_SYNC_SWRST_1,
    DC_CLK_ENABLE_TIMEBASE_TC4_SYNC_SWRST_2,
    DC_CLK_ENABLE_TIMEBASE_TC4_SYNC_CLTRB,
    DC_CLK_ENABLE_TIMEBASE_TC4_SYNC_CC0,
    DC_CLK_ENABLE_TIMEBASE_TC4_COMPLETE,
    DC_CLK_ENABLE_TIMEBASE_TC5_BEGIN,
    DC_CLK_ENABLE_TIMEBASE_TC5_SYNC_DISABLE,
    DC_CLK_ENABLE_TIMEBASE_TC5_SYNC_SWRST_1,
    DC_CLK_ENABLE_TIMEBASE_TC5_SYNC_SWRST_2,
    DC_CLK_ENABLE_TIMEBASE_TC5_SYNC_CLTRB,
    DC_CLK_ENABLE_TIMEBASE_TC5_COMPLETE,
    DC_CLK_ENABLE_TIMEBASE_TC0_BEGIN,
    DC_CLK_ENABLE_TIMEBASE_TC0_SYNC_DISABLE,
    DC_CLK_ENABLE_TIMEBASE_TC0_SYNC_SWRST_1,
    DC_CLK_ENABLE_TIMEBASE_TC0_SYNC_SWRST_2,
    DC_CLK_ENABLE_TIMEBASE_TC0_COMPLETE,
    DC_CLK_ENABLE_TIMEBASE_EVSYS_BEGIN,
    DC_CLK_ENABLE_TIMEBASE_EVSYS_COMPLETE,
    DC_CLK_ENABLE_TIMEBASE_COMPLETE,
    DC_CLK_SET_GCLK_FREQ_BEGIN,
    DC_CLK_SET_GCLK_FREQ_SYNC_1,
    DC_CLK_SET_GCLK_FREQ_SYNC_2,
    DC_CLK_SET_GCLK_FREQ_SYNC_3,
    DC_CLK_SET_GCLK_FREQ_SYNC_4,
    DC_CLK_SET_GCLK_FREQ_SYNC_5,
    DC_CLK_SET_GCLK_FREQ_COMPLETE,
    DC_CLK_INIT_OSC_BEGIN,
    DC_CLK_INIT_OSC_SYNC_1,
    DC_CLK_INIT_OSC_SYNC_2,
    DC_CLK_INIT_OSC_SYNC_3,
    DC_CLK_INIT_OSC_SYNC_4,
    DC_CLK_INIT_OSC_SYNC_5,
    DC_CLK_INIT_OSC_COMPLETE,
    DC_CLK_RESET_TIME_BEGIN,
    DC_CLK_RESET_TIME_COMPLETE,
    DC_CLK_OSC_INIT_BEGIN,
    DC_CLK_OSC_INIT_XOSC0_SYNC,
    DC_CLK_OSC_INIT_DPLL_SYNC_DISABLE,
    DC_CLK_OSC_INIT_DPLL_SYNC_RATIO,
    DC_CLK_OSC_INIT_DPLL_SYNC_ENABLE,
    DC_CLK_OSC_INIT_DPLL_WAIT_LOCK,
    DC_CLK_OSC_INIT_DPLL_WAIT_CLKRDY,
    DC_CLK_OSC_INIT_GCLK_SYNC_GENCTRL0,
    DC_CLK_OSC_INIT_COMPLETE,
    DC_SPI_INIT_BEGIN,
    DC_SPI_WRITE_DRE,
    DC_SPI_WRITE_TXC_1,
    DC_SPI_WRITE_TXC_2,
    DC_SPI_SYNC_ENABLING,
    DC_SPI_INIT_COMPLETE,
    DC_PORT_DETECT_INIT_BEGIN,
    DC_PORT_DETECT_INIT_FAILED,
    DC_PORT_DETECT_INIT_COMPLETE,
    DC_USB_RESET_BEGIN,
    DC_USB_RESET_COMPLETE,
    DC_USB_SET_HOST_BY_VOLTAGE_BEGIN,
    DC_USB_SET_HOST_5V_LOW_WAITING,
    DC_USB_SET_HOST_BY_VOLTAGE_COMPLETE,
    DC_USB_CONFIGURE_BEGIN,
    DC_USB_CONFIGURE_GET_SERIAL,
    DC_USB_CONFIGURE_COMPLETE,
    DC_USB_WRITE2422_BLOCK_BEGIN,
    DC_USB_WRITE2422_BLOCK_SYNC_SYSOP,
    DC_USB_WRITE2422_BLOCK_COMPLETE,
    DC_ADC0_CLOCK_INIT_BEGIN,
    DC_ADC0_CLOCK_INIT_COMPLETE,
    DC_ADC0_INIT_BEGIN,
    DC_ADC0_SWRST_SYNCING_1,
    DC_ADC0_SWRST_SYNCING_2,
    DC_ADC0_AVGCTRL_SYNCING_1,
    DC_ADC0_AVGCTRL_SYNCING_2,
    DC_ADC0_SAMPCTRL_SYNCING_1,
    DC_ADC0_ENABLE_SYNCING_1,
    DC_ADC0_INIT_COMPLETE,
    DC_I2C0_INIT_BEGIN,
    DC_I2C0_INIT_SYNC_ENABLING,
    DC_I2C0_INIT_SYNC_SYSOP,
    DC_I2C0_INIT_WAIT_IDLE,
    DC_I2C0_INIT_COMPLETE,
    DC_I2C1_INIT_BEGIN,
    DC_I2C1_INIT_SYNC_ENABLING,
    DC_I2C1_INIT_SYNC_SYSOP,
    DC_I2C1_INIT_WAIT_IDLE,
    DC_I2C1_INIT_COMPLETE,
    DC_I2C3733_INIT_CONTROL_BEGIN,
    DC_I2C3733_INIT_CONTROL_COMPLETE,
    DC_I2C3733_INIT_DRIVERS_BEGIN,
    DC_I2C3733_INIT_DRIVERS_COMPLETE,
    DC_I2C_DMAC_LED_INIT_BEGIN,
    DC_I2C_DMAC_LED_INIT_COMPLETE,
    DC_I2C3733_CONTROL_SET_BEGIN,
    DC_I2C3733_CONTROL_SET_COMPLETE,
    DC_LED_MATRIX_INIT_BEGIN,
    DC_LED_MATRIX_INIT_COMPLETE,
    DC_USB2422_INIT_BEGIN,
    DC_USB2422_INIT_WAIT_5V_LOW,
    DC_USB2422_INIT_OSC_SYNC_DISABLING,
    DC_USB2422_INIT_OSC_SYNC_DFLLCTRLB_1,
    DC_USB2422_INIT_OSC_SYNC_DFLLCTRLB_2,
    DC_USB2422_INIT_OSC_SYNC_DFLLCTRLB_3,
    DC_USB2422_INIT_OSC_SYNC_DFLLCTRLB_4,
    DC_USB2422_INIT_OSC_SYNC_DFLLMUL,
    DC_USB2422_INIT_OSC_SYNC_ENABLING,
    DC_USB2422_INIT_USB_SYNC_SWRST,
    DC_USB2422_INIT_USB_WAIT_SWRST,
    DC_USB2422_INIT_USB_SYNC_ENABLING,
    DC_USB2422_INIT_COMPLETE,
    DC_MAIN_UDC_START_BEGIN,
    DC_MAIN_UDC_START_COMPLETE,
    DC_MAIN_CDC_INIT_BEGIN,
    DC_MAIN_CDC_INIT_COMPLETE,
    /* Never change the order of error codes! Only add codes to end! */
};

#else

#define DBGC(n) {}

#endif //DEBUG_BOOT_TRACING

#endif //_D51_UTIL_H_
