/*
 * Copyright (c) 2020 Texas Instruments Incorporated - http://www.ti.com
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * *  Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * *  Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * *  Neither the name of Texas Instruments Incorporated nor the names of
 *    its contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

#include "board.h"

//*****************************************************************************
//
// Board Configurations
// Initializes the rest of the modules. 
// Call this function in your application if you wish to do all module 
// initialization.
// If you wish to not use some of the initializations, instead of the 
// Board_init use the individual Module_inits
//
//*****************************************************************************
void Board_init()
{
	EALLOW;

	SYNC_init();
	CAN_init();
	EPWM_init();
	IPC_SYSCFG_init();
	INTERRUPT_init();

	EDIS;
}


//*****************************************************************************
//
// CAN Configurations
//
//*****************************************************************************
void CAN_init(){
	CANB_DEBUG_init();
	CANA_APP_init();
}

void CANB_DEBUG_init(){
	CAN_initModule(CANB_DEBUG_BASE);
	//
	// Refer to the Driver Library User Guide for information on how to set
	// tighter timing control. Additionally, consult the device data sheet
	// for more information about the CAN module clocking.
	//
	CAN_setBitTiming(CANB_DEBUG_BASE, 15, 0, 15, 7, 3);
	//
	// Enable CAN Interrupts
	//
	CAN_enableInterrupt(CANB_DEBUG_BASE, CAN_INT_IE0|CAN_INT_IE1);
	CAN_enableGlobalInterrupt(CANB_DEBUG_BASE, CAN_GLOBAL_INT_CANINT0);
	CAN_enableGlobalInterrupt(CANB_DEBUG_BASE, CAN_GLOBAL_INT_CANINT1);
	//
	// Initialize the transmit message object used for sending CAN messages.
	// Message Object Parameters:
	//      Message Object ID Number: 1
	//      Message Identifier: 256
	//      Message Frame: CAN_MSG_FRAME_EXT
	//      Message Type: CAN_MSG_OBJ_TYPE_TX
	//      Message ID Mask: 0
	//      Message Object Flags: CAN_MSG_OBJ_TX_INT_ENABLE
	//      Message Data Length: 8 Bytes
	//
	CAN_setupMessageObject(CANB_DEBUG_BASE, 1, CANB_DEBUG_MessageObj1_ID, CAN_MSG_FRAME_EXT,CAN_MSG_OBJ_TYPE_TX, 0, CAN_MSG_OBJ_TX_INT_ENABLE,8);
	//
	// Initialize the transmit message object used for sending CAN messages.
	// Message Object Parameters:
	//      Message Object ID Number: 2
	//      Message Identifier: 768
	//      Message Frame: CAN_MSG_FRAME_EXT
	//      Message Type: CAN_MSG_OBJ_TYPE_TX
	//      Message ID Mask: 0
	//      Message Object Flags: CAN_MSG_OBJ_TX_INT_ENABLE
	//      Message Data Length: 8 Bytes
	//
	CAN_setupMessageObject(CANB_DEBUG_BASE, 2, CANB_DEBUG_MessageObj2_ID, CAN_MSG_FRAME_EXT,CAN_MSG_OBJ_TYPE_TX, 0, CAN_MSG_OBJ_TX_INT_ENABLE,8);
	//
	// Initialize the transmit message object used for sending CAN messages.
	// Message Object Parameters:
	//      Message Object ID Number: 11
	//      Message Identifier: 512
	//      Message Frame: CAN_MSG_FRAME_EXT
	//      Message Type: CAN_MSG_OBJ_TYPE_RX
	//      Message ID Mask: 0
	//      Message Object Flags: CAN_MSG_OBJ_RX_INT_ENABLE
	//      Message Data Length: 0 Bytes
	//
	CAN_setupMessageObject(CANB_DEBUG_BASE, 11, CANB_DEBUG_MessageObj11_ID, CAN_MSG_FRAME_EXT,CAN_MSG_OBJ_TYPE_RX, 0, CAN_MSG_OBJ_RX_INT_ENABLE,0);
	CAN_setInterruptMux(CANB_DEBUG_BASE, 6);
	//
	// Start CAN module operations
	//
	CAN_startModule(CANB_DEBUG_BASE);
}
void CANA_APP_init(){
	CAN_initModule(CANA_APP_BASE);
	//
	// Refer to the Driver Library User Guide for information on how to set
	// tighter timing control. Additionally, consult the device data sheet
	// for more information about the CAN module clocking.
	//
	CAN_setBitTiming(CANA_APP_BASE, 15, 0, 15, 7, 3);
	//
	// Enable CAN Interrupts
	//
	CAN_enableInterrupt(CANA_APP_BASE, CAN_INT_IE0|CAN_INT_IE1);
	CAN_enableGlobalInterrupt(CANA_APP_BASE, CAN_GLOBAL_INT_CANINT0);
	CAN_enableGlobalInterrupt(CANA_APP_BASE, CAN_GLOBAL_INT_CANINT1);
	//
	// Initialize the transmit message object used for sending CAN messages.
	// Message Object Parameters:
	//      Message Object ID Number: 1
	//      Message Identifier: 256
	//      Message Frame: CAN_MSG_FRAME_STD
	//      Message Type: CAN_MSG_OBJ_TYPE_TX
	//      Message ID Mask: 0
	//      Message Object Flags: 
	//      Message Data Length: 8 Bytes
	//
	CAN_setupMessageObject(CANA_APP_BASE, 1, CANA_APP_MessageObj1_ID, CAN_MSG_FRAME_STD,CAN_MSG_OBJ_TYPE_TX, 0, 0,8);
	//
	// Initialize the transmit message object used for sending CAN messages.
	// Message Object Parameters:
	//      Message Object ID Number: 11
	//      Message Identifier: 775
	//      Message Frame: CAN_MSG_FRAME_STD
	//      Message Type: CAN_MSG_OBJ_TYPE_RX
	//      Message ID Mask: 0
	//      Message Object Flags: CAN_MSG_OBJ_RX_INT_ENABLE
	//      Message Data Length: 0 Bytes
	//
	CAN_setupMessageObject(CANA_APP_BASE, 11, CANA_APP_MessageObj11_ID, CAN_MSG_FRAME_STD,CAN_MSG_OBJ_TYPE_RX, 0, CAN_MSG_OBJ_RX_INT_ENABLE,0);
	//
	// Initialize the transmit message object used for sending CAN messages.
	// Message Object Parameters:
	//      Message Object ID Number: 12
	//      Message Identifier: 519
	//      Message Frame: CAN_MSG_FRAME_STD
	//      Message Type: CAN_MSG_OBJ_TYPE_RX
	//      Message ID Mask: 0
	//      Message Object Flags: CAN_MSG_OBJ_RX_INT_ENABLE
	//      Message Data Length: 0 Bytes
	//
	CAN_setupMessageObject(CANA_APP_BASE, 12, CANA_APP_MessageObj12_ID, CAN_MSG_FRAME_STD,CAN_MSG_OBJ_TYPE_RX, 0, CAN_MSG_OBJ_RX_INT_ENABLE,0);
	CAN_setInterruptMux(CANA_APP_BASE, 2);
	//
	// Start CAN module operations
	//
	CAN_startModule(CANA_APP_BASE);
}

//*****************************************************************************
//
// EPWM Configurations
//
//*****************************************************************************
void EPWM_init(){
    EPWM_setClockPrescaler(EMPW_Timer1_CANTX_BASE, EPWM_CLOCK_DIVIDER_64, EPWM_HSCLOCK_DIVIDER_14);	
    EPWM_setTimeBasePeriod(EMPW_Timer1_CANTX_BASE, 11161);	
    EPWM_setTimeBaseCounter(EMPW_Timer1_CANTX_BASE, 0);	
    EPWM_setTimeBaseCounterMode(EMPW_Timer1_CANTX_BASE, EPWM_COUNTER_MODE_UP);	
    EPWM_disablePhaseShiftLoad(EMPW_Timer1_CANTX_BASE);	
    EPWM_setPhaseShift(EMPW_Timer1_CANTX_BASE, 0);	
    EPWM_setCounterCompareValue(EMPW_Timer1_CANTX_BASE, EPWM_COUNTER_COMPARE_A, 0);	
    EPWM_setCounterCompareShadowLoadMode(EMPW_Timer1_CANTX_BASE, EPWM_COUNTER_COMPARE_A, EPWM_COMP_LOAD_ON_CNTR_ZERO);	
    EPWM_setCounterCompareValue(EMPW_Timer1_CANTX_BASE, EPWM_COUNTER_COMPARE_B, 0);	
    EPWM_setCounterCompareShadowLoadMode(EMPW_Timer1_CANTX_BASE, EPWM_COUNTER_COMPARE_B, EPWM_COMP_LOAD_ON_CNTR_ZERO);	
    EPWM_setActionQualifierAction(EMPW_Timer1_CANTX_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);	
    EPWM_setActionQualifierAction(EMPW_Timer1_CANTX_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_PERIOD);	
    EPWM_setActionQualifierAction(EMPW_Timer1_CANTX_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);	
    EPWM_setActionQualifierAction(EMPW_Timer1_CANTX_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPA);	
    EPWM_setActionQualifierAction(EMPW_Timer1_CANTX_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPB);	
    EPWM_setActionQualifierAction(EMPW_Timer1_CANTX_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPB);	
    EPWM_setActionQualifierAction(EMPW_Timer1_CANTX_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);	
    EPWM_setActionQualifierAction(EMPW_Timer1_CANTX_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_PERIOD);	
    EPWM_setActionQualifierAction(EMPW_Timer1_CANTX_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);	
    EPWM_setActionQualifierAction(EMPW_Timer1_CANTX_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPA);	
    EPWM_setActionQualifierAction(EMPW_Timer1_CANTX_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPB);	
    EPWM_setActionQualifierAction(EMPW_Timer1_CANTX_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPB);	
    EPWM_setRisingEdgeDelayCountShadowLoadMode(EMPW_Timer1_CANTX_BASE, EPWM_RED_LOAD_ON_CNTR_ZERO);	
    EPWM_disableRisingEdgeDelayCountShadowLoadMode(EMPW_Timer1_CANTX_BASE);	
    EPWM_setFallingEdgeDelayCountShadowLoadMode(EMPW_Timer1_CANTX_BASE, EPWM_FED_LOAD_ON_CNTR_ZERO);	
    EPWM_disableFallingEdgeDelayCountShadowLoadMode(EMPW_Timer1_CANTX_BASE);	
    EPWM_enableInterrupt(EMPW_Timer1_CANTX_BASE);	
    EPWM_setInterruptSource(EMPW_Timer1_CANTX_BASE, EPWM_INT_TBCTR_PERIOD);	
    EPWM_setInterruptEventCount(EMPW_Timer1_CANTX_BASE, 1);	
    EPWM_setClockPrescaler(EMPW_Timer2_CANTX_BASE, EPWM_CLOCK_DIVIDER_64, EPWM_HSCLOCK_DIVIDER_14);	
    EPWM_setTimeBasePeriod(EMPW_Timer2_CANTX_BASE, 11161);	
    EPWM_setTimeBaseCounter(EMPW_Timer2_CANTX_BASE, 0);	
    EPWM_setTimeBaseCounterMode(EMPW_Timer2_CANTX_BASE, EPWM_COUNTER_MODE_UP);	
    EPWM_disablePhaseShiftLoad(EMPW_Timer2_CANTX_BASE);	
    EPWM_setPhaseShift(EMPW_Timer2_CANTX_BASE, 0);	
    EPWM_setCounterCompareValue(EMPW_Timer2_CANTX_BASE, EPWM_COUNTER_COMPARE_A, 0);	
    EPWM_setCounterCompareShadowLoadMode(EMPW_Timer2_CANTX_BASE, EPWM_COUNTER_COMPARE_A, EPWM_COMP_LOAD_ON_CNTR_ZERO);	
    EPWM_setCounterCompareValue(EMPW_Timer2_CANTX_BASE, EPWM_COUNTER_COMPARE_B, 0);	
    EPWM_setCounterCompareShadowLoadMode(EMPW_Timer2_CANTX_BASE, EPWM_COUNTER_COMPARE_B, EPWM_COMP_LOAD_ON_CNTR_ZERO);	
    EPWM_setActionQualifierAction(EMPW_Timer2_CANTX_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);	
    EPWM_setActionQualifierAction(EMPW_Timer2_CANTX_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_PERIOD);	
    EPWM_setActionQualifierAction(EMPW_Timer2_CANTX_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);	
    EPWM_setActionQualifierAction(EMPW_Timer2_CANTX_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPA);	
    EPWM_setActionQualifierAction(EMPW_Timer2_CANTX_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPB);	
    EPWM_setActionQualifierAction(EMPW_Timer2_CANTX_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPB);	
    EPWM_setActionQualifierAction(EMPW_Timer2_CANTX_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);	
    EPWM_setActionQualifierAction(EMPW_Timer2_CANTX_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_PERIOD);	
    EPWM_setActionQualifierAction(EMPW_Timer2_CANTX_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);	
    EPWM_setActionQualifierAction(EMPW_Timer2_CANTX_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPA);	
    EPWM_setActionQualifierAction(EMPW_Timer2_CANTX_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPB);	
    EPWM_setActionQualifierAction(EMPW_Timer2_CANTX_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPB);	
    EPWM_setRisingEdgeDelayCountShadowLoadMode(EMPW_Timer2_CANTX_BASE, EPWM_RED_LOAD_ON_CNTR_ZERO);	
    EPWM_disableRisingEdgeDelayCountShadowLoadMode(EMPW_Timer2_CANTX_BASE);	
    EPWM_setFallingEdgeDelayCountShadowLoadMode(EMPW_Timer2_CANTX_BASE, EPWM_FED_LOAD_ON_CNTR_ZERO);	
    EPWM_disableFallingEdgeDelayCountShadowLoadMode(EMPW_Timer2_CANTX_BASE);	
    EPWM_enableInterrupt(EMPW_Timer2_CANTX_BASE);	
    EPWM_setInterruptSource(EMPW_Timer2_CANTX_BASE, EPWM_INT_TBCTR_PERIOD);	
    EPWM_setInterruptEventCount(EMPW_Timer2_CANTX_BASE, 1);	
}

//*****************************************************************************
//
// INTERRUPT Configurations
//
//*****************************************************************************
void INTERRUPT_init(){
	
	// Interrupt Settings for INT_CANB_DEBUG_0
	Interrupt_register(INT_CANB_DEBUG_0, &INT_CANB_DEBUG_0_ISR);
	Interrupt_enable(INT_CANB_DEBUG_0);
	
	// Interrupt Settings for INT_CANB_DEBUG_1
	Interrupt_register(INT_CANB_DEBUG_1, &INT_CANB_DEBUG_1_ISR);
	Interrupt_enable(INT_CANB_DEBUG_1);
	
	// Interrupt Settings for INT_CANA_APP_0
	Interrupt_register(INT_CANA_APP_0, &INT_CANA_APP_0_ISR);
	Interrupt_enable(INT_CANA_APP_0);
	
	// Interrupt Settings for INT_CANA_APP_1
	Interrupt_register(INT_CANA_APP_1, &INT_CANA_APP_1_ISR);
	Interrupt_enable(INT_CANA_APP_1);
	
	// Interrupt Settings for INT_EMPW_Timer1_CANTX
	Interrupt_register(INT_EMPW_Timer1_CANTX, &INT_EMPW_Timer1_CANTX_ISR);
	Interrupt_enable(INT_EMPW_Timer1_CANTX);
	
	// Interrupt Settings for INT_EMPW_Timer2_CANTX
	Interrupt_register(INT_EMPW_Timer2_CANTX, &INT_EMPW_Timer2_CANTX_ISR);
	Interrupt_enable(INT_EMPW_Timer2_CANTX);
	
	// Interrupt Settings for IPC_0
	Interrupt_register(IPC_0, &IPC_0_ISR);
	Interrupt_enable(IPC_0);
	
	// Interrupt Settings for IPC_2
	Interrupt_register(IPC_2, &IPC_2_ISR);
	Interrupt_enable(IPC_2);
}
//*****************************************************************************
//
// IPC Configurations
//
//*****************************************************************************
void IPC_SYSCFG_init(){
}
//*****************************************************************************
//
// SYNC Scheme Configurations
//
//*****************************************************************************
void SYNC_init(){
	SysCtl_setSyncOutputConfig(SYSCTL_SYNC_OUT_SRC_EPWM1SYNCOUT);
	//
	// For EPWM1, the sync input is: SYSCTL_SYNC_IN_SRC_EXTSYNCIN1
	//
	SysCtl_setSyncInputConfig(SYSCTL_SYNC_IN_EPWM4, SYSCTL_SYNC_IN_SRC_EPWM1SYNCOUT);
	SysCtl_setSyncInputConfig(SYSCTL_SYNC_IN_EPWM7, SYSCTL_SYNC_IN_SRC_EPWM1SYNCOUT);
	SysCtl_setSyncInputConfig(SYSCTL_SYNC_IN_EPWM10, SYSCTL_SYNC_IN_SRC_EPWM1SYNCOUT);
	SysCtl_setSyncInputConfig(SYSCTL_SYNC_IN_ECAP1, SYSCTL_SYNC_IN_SRC_EPWM1SYNCOUT);
	SysCtl_setSyncInputConfig(SYSCTL_SYNC_IN_ECAP4, SYSCTL_SYNC_IN_SRC_EPWM1SYNCOUT);
	//
	// SOCA
	//
	SysCtl_enableExtADCSOCSource(0);
	//
	// SOCB
	//
	SysCtl_enableExtADCSOCSource(0);
}
