/*
 * init_TM4C123GH6PZ_100pin.c
 *
 *  Created on: Feb 22, 2024 (copied from Thomz personal project, prelim eval for Irene's hardware.   Code is shared to MBARI and governed by the Good Person license v1.0)
 *      Author: thomm
 */

#include "main.h"
#include "system.h"
#include "board_util.h"
#include "init.h"

#include "microsd.h"
#include "uartstdio.h"  // User local version with larger RX buffer
#include "sleep.h"
#include "i2c_fram.h"

// TODO, use #include for these...
extern void profile2_toggle(int target);
extern void ADS1248_gpio_init(void);
extern void AUX1_init(void);
extern void optode_init(void);
extern void led_init(void);


// GPIO and onchip peripheral init for the 100 pin parts (code pulled in from personal project)
// assumes MAP_FPUxxx and MAP_SysCtlClockSet called before calling this function
void init_TM4C123GH6PZ_100pin(void)
{
#ifdef NOCODE
    // Enable lazy stacking for interrupt handlers.  This allows floating-point
    // instructions to be used within interrupt handlers, but at the expense of2
    // extra stack usage.
    MAP_FPULazyStackingEnable();

    //enable floats
    MAP_FPUEnable();

    //set the system clock...Using 400MHz PLL and DIV_4 yields 100MHz (comment says 50MHZ ?)
    MAP_SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_XTAL_16MHZ | SYSCTL_OSC_MAIN);
#endif

    //TM4C123GH6PGE = 100     (105 GPIO)
    //PA0 - PA7       8
    //PB0 - PB5       6
    //PC0 - PC7       8
    //PD0 - PD7       8
    //PE0 - PE7       8
    //PF0 - PF7       8
    //PG0 - PG7       8
    //PH0 - PH7       8
    //PJ0 - PJ2       3
    //PK0 - PK3       4
    //PL              0
    //PM              0
    //PN              0
    //PP              0

    //MAP_SysCtlDelay(MILLISECOND*100);       //THOM MFET is not usable after experimenting with delay

    /*** Enable the GPIO ports used ***/
    MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
    MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);
    MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
    MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);
    MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
    MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOG);
    MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOH);
    MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOJ);
    MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOK);


    /*** Initialize Green and Red LED ***/
    // This is done early in init to enable oscope timing
    led_init();  //PG7=RED, PG6=GRN
    led_power_on();
#if BOARD_MFET == 2
    // Set PA1 high to avoid RS232 glitch, later in init(), this will be setup as console serial port  (Looks like CONSOLE SHUTDOWN is all that is req'd)
    MAP_GPIOPinTypeGPIOOutput(GPIO_PORTA_BASE, GPIO_PIN_1); // PA1 is console TX
    MAP_GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_1, 0xFF);        // was 0xff  // BUG Fix 19 May 2022 (PORTP to PORTA)

    MAP_GPIOPinTypeGPIOOutput(GPIO_PORTL_BASE, GPIO_PIN_1); // PL0, pin 107             // CONSOLE SHUTDOWN # (active low)
    MAP_GPIOPinWrite(GPIO_PORTL_BASE, GPIO_PIN_1, 0x00);    // Keep max3232 in shutdown until after console uart is config'd
#endif
#if BOARD_TESTFIT >= 1
    // Thomz board uses MAX3223 with autoshutdown
#endif
    MAP_SysCtlDelay(MILLISECOND*2);       // THOM, fast startup

    // Temporarily Setup unused ports as GPIO (change this when I2C, SSI2, etc are used)

    // According to the TM4c123g tech ref manual, GPIO are set as inputs after power on reset
    // The init policy will be to only setup GPIO as output for those that are used on a particular board (minimize power consumption)
    // Also, UARTs, SPI, and I2C peripherals will be configured in a peripheral specific init function just ahead of use.

    //*********** Initialize unused pins ****************
    // NOTE: unused pins are configured as inputs at processor reset, precursor to init() being called, lowest power

    // ***    PortA    ****
    // PA0 = U0RX, PA1 = U0TX
    // PA2 = SSIOCLK, PA3 = SSI0FSS, PA4 = SSI0RX, PA5 = SSI0TX
    // PA6 = I2C1CLK, PA7 = I2C1SDA
#if BOARD_TESTFIT >= 1
    MAP_GPIOPinTypeGPIOOutput(GPIO_PORTB_BASE, GPIO_PIN_2); // PB2, pin 72  SCL i2c for FRAM, BME280, DS3231, etc
    MAP_GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_2, 0xFF);    // Set (R62 pull up)

    MAP_GPIOPinTypeGPIOOutput(GPIO_PORTB_BASE, GPIO_PIN_3); // PB3, pin 73, SDA for FRAM, BME280, DS3231, etc
    MAP_GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_3, 0xFF);    // Set (R63 pull up)
#endif

    // ***    PortB    ****
    // PB0 = U1RX, PB1 = U1TX
    // PB2 = I2C0SCL, PB3 = I2C0SDA
    // PB4 = AIN10, PB5 = AIN11
    MAP_GPIOPinTypeGPIOOutput(GPIO_PORTB_BASE, GPIO_PIN_2); // PB2, pin 72  SCL i2c for FRAM, BME280, DS3231, etc
    MAP_GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_2, 0xFF);    // Set (R62 pull up)

    MAP_GPIOPinTypeGPIOOutput(GPIO_PORTB_BASE, GPIO_PIN_3); // PB3, pin 73, SDA for FRAM, BME280, DS3231, etc
    MAP_GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_3, 0xFF);    // Set (R63 pull up)

    // ***    PortC    ****
    // PC0 = SWCLK, PC1 = SWDIO, PC2 = TDI, PC3 = TDO
    // PC4 = U4RX, PC5 = U4TX
    // PC6 = U3RX, PC7 = U3TX


    // ***     PortD    ****
    // PD0 = AIN15, PD1 = AIN14, PD2 = AIN13, PD3 = AIN12
    // PD4 = U4RX, PD5 = U4TX
    // PD6 = AIN5, PD7 = AIN4



    // ***     PortE    ****
    // PE0 = U7RX, PE1 = U7TX
    // PE2 = AIN1, PE3 = AIN0, PE4 = AIN9
    // PE5 = U5TX  (Why didn't PE6 get used for U5RX?)
    // PE6 = AIN21
    // PE7 = AIN20


    // ***     PortF    ****
    // PF0 = SSI1RX, PF1 = SSI1TX, PF2 = SSI1CLK, PF3 = SSI1FSS
    // PF4 = GPIO56 (USB0EPEN), PF5 = uSD_DETECT (USB0PFLT)
    // PF6 = SPI0_CS2, PF7 = WD_CLR#


    // ***     PortG    ****
    // PG0 = GP_LogPwr_EN, PG1 = GP_isoSPI_EN, PG2 = WD_PET, PG3 = WD_MON
    // PG4 = U2RX, PG5 = U2TX
    // PG6 = LED_GRN, PG7 = LED_RED


    // ***     PortH    ****
    // PH0 = GPIO_47, PH1 = GPIO_81, PH2 = GPIO_50, PH3 = GPIO_83
    // PH4 = SSI2CLK, PH5 = SSI2FSS, PH6 = SSI2RX, PH7 = SSI2TX
    MAP_GPIOPinTypeGPIOOutput(GPIO_PORTH_BASE, GPIO_PIN_4);     // SSI2CLK
    MAP_GPIOPinWrite(GPIO_PORTH_BASE, GPIO_PIN_4, 0x00);

    MAP_GPIOPinTypeGPIOOutput(GPIO_PORTH_BASE, GPIO_PIN_5);     // SSI2FSS
    MAP_GPIOPinWrite(GPIO_PORTH_BASE, GPIO_PIN_5, 0x00);

    MAP_GPIOPinTypeGPIOInput(GPIO_PORTH_BASE, GPIO_PIN_6);      // SSI2Rx

    MAP_GPIOPinTypeGPIOOutput(GPIO_PORTH_BASE, GPIO_PIN_7);     // SSI2Tx
    MAP_GPIOPinWrite(GPIO_PORTH_BASE, GPIO_PIN_7, 0x00);

    // ***     PortJ    ****
    // PJ0 = USB0DM, PJ1 = USB0DP
    // PJ2 = U5RX


    // ***     PortK    ****
    // PK0 = SSI3CLK, PK1 = SSI3FSS, PK2 = SSI3RX, PK3 = SSI3TX

    /*** Initialize isolated ADS1248 pins as GPIO to reduce power consumption, this will be init'd later as SPI ***/
    MAP_GPIOPinTypeGPIOOutput(GPIO_PORTK_BASE, GPIO_PIN_0);     // SSI3CLK
    MAP_GPIOPinWrite(GPIO_PORTK_BASE, GPIO_PIN_0, 0x00);

    MAP_GPIOPinTypeGPIOOutput(GPIO_PORTK_BASE, GPIO_PIN_1);     // SSI3Fss
    MAP_GPIOPinWrite(GPIO_PORTK_BASE, GPIO_PIN_1, 0x00);

    MAP_GPIOPinTypeGPIOInput(GPIO_PORTK_BASE, GPIO_PIN_2);      // SSI3Rx

    MAP_GPIOPinTypeGPIOOutput(GPIO_PORTK_BASE, GPIO_PIN_3);     // SSI3Tx
    MAP_GPIOPinWrite(GPIO_PORTK_BASE, GPIO_PIN_3, 0x00);





    //*********************** Onchip special function peripheral setup ***************************************


    /*** Initialize the uart0, h2m (console) ***/
    MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
    MAP_GPIOPinConfigure(GPIO_PA0_U0RX);
    MAP_GPIOPinConfigure(GPIO_PA1_U0TX);
    MAP_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
    UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC);
    UARTStdioConfig(0, 115200, 16000000);       // 115200 bits per second
    UARTEchoSet(true);  // Enable console echo

    //enable the EEPROM
    MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_EEPROM0);
    while( ! MAP_SysCtlPeripheralReady(SYSCTL_PERIPH_EEPROM0) ) { }

#ifdef NOCODE
    /*** Initialize uart1, m2m ***/
    MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART1);
    MAP_GPIOPinConfigure(GPIO_PB0_U1RX);
    MAP_GPIOPinConfigure(GPIO_PB1_U1TX);
    MAP_GPIOPinTypeUART(GPIO_PORTB_BASE, GPIO_PIN_0 | GPIO_PIN_1);
    UARTClockSourceSet(UART1_BASE, UART_CLOCK_PIOSC);
#endif


    //**** onchip ADC Setup
#ifdef NOCODE
    MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);
    MAP_SysCtlDelay(3);

    //Reset the ADC peripherals
    MAP_SysCtlPeripheralReset(SYSCTL_PERIPH_ADC0);
    //Wait "READY"
    while(!MAP_SysCtlPeripheralReady(SYSCTL_PERIPH_ADC0));

    // Select the external reference for greatest accuracy.
    //MAP_ADCReferenceSet(ADC0_BASE, ADC_REF_EXT_3V);

    //MAP_ADCClockConfigSet(ADC_CLOCK_RATE_HALF);     // 500K rather than default 1M
#endif

    //enable the EEPROM
    MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_EEPROM0);
    while( ! MAP_SysCtlPeripheralReady(SYSCTL_PERIPH_EEPROM0) ) { }



}
