470 lines
15 KiB
C
470 lines
15 KiB
C
//###########################################################################
|
|
//
|
|
// FILE: F2837xD_Ipc_Driver_Util.c
|
|
//
|
|
// TITLE: F2837xD Inter-Processor Communication (IPC) API Driver Utility
|
|
// Functions
|
|
//
|
|
// DESCRIPTION:
|
|
// API functions for inter-processor communications between the
|
|
// Local and Remote CPU system.
|
|
// The driver functions in this file are available only as
|
|
// sample functions for application development. Due to the generic
|
|
// nature of these functions and the cycle overhead inherent to a
|
|
// function call, the code is not intended to be used in cases where
|
|
// maximum efficiency is required in a system.
|
|
//
|
|
// NOTE: This source code is used by both CPUs. That is both CPU1 and CPU2
|
|
// cores use this code.
|
|
// The active debug CPU will be referred to as Local CPU and the other
|
|
// CPU will be referred to as Remote CPU.
|
|
// When using this source code in CPU1, the term "local"
|
|
// will mean CPU1 and the term "remote" CPU will be mean CPU2.
|
|
// When using this source code in CPU2, the term "local"
|
|
// will mean CPU2 and the term "remote" CPU will be mean CPU1.
|
|
//
|
|
// The abbreviations LtoR and RtoL within the function names mean
|
|
// Local to Remote and Remote to Local respectively.
|
|
//
|
|
//###########################################################################
|
|
// $TI Release: F2837xD Support Library v3.05.00.00 $
|
|
// $Release Date: Tue Jun 26 03:15:23 CDT 2018 $
|
|
// $Copyright:
|
|
// Copyright (C) 2013-2018 Texas Instruments Incorporated - http://www.ti.com/
|
|
//
|
|
// 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.
|
|
// $
|
|
//###########################################################################
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! \addtogroup ipc_util_api
|
|
//! @{
|
|
//
|
|
//*****************************************************************************
|
|
#include "F2837xD_device.h"
|
|
#include "F2837xD_GlobalPrototypes.h"
|
|
#include "F2837xD_Gpio_defines.h"
|
|
#include "F2837xD_Ipc_drivers.h"
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! Local CPU Acknowledges Remote to Local IPC Flag.
|
|
//!
|
|
//! \param ulFlags specifies the IPC flag mask for flags being acknowledged.
|
|
//!
|
|
//! This function will allow the Local CPU system to acknowledge/clear the IPC
|
|
//! flag set by the Remote CPU system. The \e ulFlags parameter can be any of
|
|
//! the IPC flag values: \b IPC_FLAG0 - \b IPC_FLAG31.
|
|
//!
|
|
//! \return None.
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
IPCRtoLFlagAcknowledge (uint32_t ulFlags)
|
|
{
|
|
IpcRegs.IPCACK.all |= ulFlags;
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! Determines whether the given Remote to Local IPC flags are busy or not.
|
|
//!
|
|
//! \param ulFlags specifies Remote to Local IPC Flag number masks to check the
|
|
//! status of.
|
|
//!
|
|
//! Allows the caller to determine whether the designated IPC flags are
|
|
//! pending. The \e ulFlags parameter can be any of the IPC flag
|
|
//! values: \b IPC_FLAG0 - \b IPC_FLAG31.
|
|
//!
|
|
//! \return Returns \b 1 if the IPC flags are busy or \b 0 if designated
|
|
//! IPC flags are free.
|
|
//
|
|
//*****************************************************************************
|
|
Uint16
|
|
IPCRtoLFlagBusy (uint32_t ulFlags)
|
|
{
|
|
Uint16 returnStatus;
|
|
|
|
if ((IpcRegs.IPCSTS.all & ulFlags) == 0)
|
|
{
|
|
returnStatus = 0;
|
|
}
|
|
else
|
|
{
|
|
returnStatus = 1;
|
|
}
|
|
|
|
return returnStatus;
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! Determines whether the given IPC flags are busy or not.
|
|
//!
|
|
//! \param ulFlags specifies Local to Remote IPC Flag number masks to check the
|
|
//! status of.
|
|
//!
|
|
//! Allows the caller to determine whether the designated IPC flags are
|
|
//! available for further control to master system communication. If \b 0 is
|
|
//! returned, then all designated tasks have completed and are available.
|
|
//! The \e ulFlags parameter can be any of the IPC flag
|
|
//! values: \b IPC_FLAG0 - \b IPC_FLAG31.
|
|
//!
|
|
//! \return Returns \b 1 if the IPC flags are busy or \b 0 if designated
|
|
//! IPC flags are free.
|
|
//
|
|
//*****************************************************************************
|
|
Uint16
|
|
IPCLtoRFlagBusy (uint32_t ulFlags)
|
|
{
|
|
Uint16 returnStatus;
|
|
|
|
if ((IpcRegs.IPCFLG.all & ulFlags) == 0)
|
|
{
|
|
returnStatus = 0;
|
|
}
|
|
else
|
|
{
|
|
returnStatus = 1;
|
|
}
|
|
|
|
return returnStatus;
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! Local CPU Sets Local to Remote IPC Flag
|
|
//!
|
|
//! \param ulFlags specifies the IPC flag mask for flags being set.
|
|
//!
|
|
//! This function will allow the Local CPU system to set the designated IPC
|
|
//! flags to send to the Remote CPU system. The \e ulFlags parameter can be any
|
|
//! of the IPC flag values: \b IPC_FLAG0 - \b IPC_FLAG31.
|
|
//!
|
|
//! \return None.
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
IPCLtoRFlagSet (uint32_t ulFlags)
|
|
{
|
|
IpcRegs.IPCSET.all |= ulFlags;
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! Local CPU Clears Local to Remote IPC Flag
|
|
//!
|
|
//! \param ulFlags specifies the IPC flag mask for flags being set.
|
|
//!
|
|
//! This function will allow the Local CPU system to set the designated IPC
|
|
//! flags to send to the Remote CPU system. The \e ulFlags parameter can be any
|
|
//! of the IPC flag values: \b IPC_FLAG0 - \b IPC_FLAG31.
|
|
//!
|
|
//! \return None.
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
IPCLtoRFlagClear (uint32_t ulFlags)
|
|
{
|
|
IpcRegs.IPCCLR.all |= ulFlags;
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! Local Return CPU02 BOOT status
|
|
//!
|
|
//! This function returns the value at IPCBOOTSTS register.
|
|
//!
|
|
//! \return Boot status.
|
|
//
|
|
//*****************************************************************************
|
|
uint32_t
|
|
IPCGetBootStatus (void)
|
|
{
|
|
return(IpcRegs.IPCBOOTSTS);
|
|
}
|
|
|
|
#if defined (CPU1)
|
|
//*****************************************************************************
|
|
//! Executes a CPU02 control system bootloader.
|
|
//!
|
|
//! \param ulBootMode specifies which CPU02 control system boot mode to execute.
|
|
//!
|
|
//! This function will allow the CPU01 master system to boot the CPU02 control
|
|
//! system via the following modes: Boot to RAM, Boot to Flash, Boot via SPI,
|
|
//! SCI, I2C, or parallel I/O. Unlike other IPCLite driver functions, this
|
|
//! function blocks and waits until the control system boot ROM is configured
|
|
//! and ready to receive CPU01 to CPU02 IPC INT0 interrupts. It then blocks and
|
|
//! waits until IPC INT0 and IPC FLAG31 are available in the CPU02 boot ROM
|
|
//! prior to sending the command to execute the selected bootloader. The \e
|
|
//! ulBootMode parameter accepts one of the following values: \b
|
|
//! C1C2_BROM_BOOTMODE_BOOT_FROM_PARALLEL, \b
|
|
//! C1C2_BROM_BOOTMODE_BOOT_FROM_SCI, \b
|
|
//! C1C2_BROM_BOOTMODE_BOOT_FROM_SPI, \b
|
|
//! C1C2_BROM_BOOTMODE_BOOT_FROM_I2C, \b C1C2_BROM_BOOTMODE_BOOT_FROM_CAN,
|
|
//! \b C1C2_BROM_BOOTMODE_BOOT_FROM_RAM, \b
|
|
//! C1C2_BROM_BOOTMODE_BOOT_FROM_FLASH.
|
|
//!
|
|
//! \return 0 (success) if command is sent, or 1 (failure) if boot mode is
|
|
//! invalid and command was not sent.
|
|
//
|
|
//*****************************************************************************
|
|
uint16_t
|
|
IPCBootCPU2(uint32_t ulBootMode)
|
|
{
|
|
uint32_t bootStatus;
|
|
uint16_t pin;
|
|
uint16_t returnStatus = STATUS_PASS;
|
|
|
|
//
|
|
// If CPU2 has already booted, return a fail to let the application
|
|
// know that something is out of the ordinary.
|
|
//
|
|
bootStatus = IPCGetBootStatus() & 0x0000000F;
|
|
|
|
if(bootStatus == C2_BOOTROM_BOOTSTS_C2TOC1_BOOT_CMD_ACK)
|
|
{
|
|
//
|
|
// Check if MSB is set as well
|
|
//
|
|
bootStatus = ((uint32_t)(IPCGetBootStatus() & 0x80000000)) >> 31U;
|
|
|
|
if(bootStatus != 0)
|
|
{
|
|
returnStatus = STATUS_FAIL;
|
|
|
|
return returnStatus;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Wait until CPU02 control system boot ROM is ready to receive
|
|
// CPU01 to CPU02 INT1 interrupts.
|
|
//
|
|
do
|
|
{
|
|
bootStatus = IPCGetBootStatus() & C2_BOOTROM_BOOTSTS_SYSTEM_READY;
|
|
} while ((bootStatus != C2_BOOTROM_BOOTSTS_SYSTEM_READY));
|
|
|
|
//
|
|
// Loop until CPU02 control system IPC flags 1 and 32 are available
|
|
//
|
|
while ((IPCLtoRFlagBusy(IPC_FLAG0) == 1) ||
|
|
(IPCLtoRFlagBusy(IPC_FLAG31) == 1))
|
|
{
|
|
|
|
}
|
|
|
|
if (ulBootMode >= C1C2_BROM_BOOTMODE_BOOT_COMMAND_MAX_SUPPORT_VALUE)
|
|
{
|
|
returnStatus = STATUS_FAIL;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Based on boot mode, enable pull-ups on peripheral pins and
|
|
// give GPIO pin control to CPU02 control system.
|
|
//
|
|
switch (ulBootMode)
|
|
{
|
|
case C1C2_BROM_BOOTMODE_BOOT_FROM_SCI:
|
|
|
|
EALLOW;
|
|
|
|
//
|
|
//SCIA connected to CPU02
|
|
//
|
|
DevCfgRegs.CPUSEL5.bit.SCI_A = 1;
|
|
|
|
//
|
|
//Allows CPU02 bootrom to take control of clock
|
|
//configuration registers
|
|
//
|
|
ClkCfgRegs.CLKSEM.all = 0xA5A50000;
|
|
|
|
ClkCfgRegs.LOSPCP.all = 0x0002;
|
|
EDIS;
|
|
|
|
GPIO_SetupPinOptions(29, GPIO_OUTPUT, GPIO_ASYNC);
|
|
GPIO_SetupPinMux(29,GPIO_MUX_CPU2,1);
|
|
|
|
GPIO_SetupPinOptions(28, GPIO_INPUT, GPIO_ASYNC);
|
|
GPIO_SetupPinMux(28,GPIO_MUX_CPU2,1);
|
|
|
|
break;
|
|
|
|
case C1C2_BROM_BOOTMODE_BOOT_FROM_SPI:
|
|
EALLOW;
|
|
|
|
//
|
|
//SPI-A connected to CPU02
|
|
//
|
|
DevCfgRegs.CPUSEL6.bit.SPI_A = 1;
|
|
|
|
//
|
|
//Allows CPU02 bootrom to take control of clock configuration
|
|
// registers
|
|
//
|
|
ClkCfgRegs.CLKSEM.all = 0xA5A50000;
|
|
EDIS;
|
|
|
|
GPIO_SetupPinOptions(16, GPIO_INPUT, GPIO_ASYNC);
|
|
GPIO_SetupPinMux(16,GPIO_MUX_CPU2,1);
|
|
|
|
GPIO_SetupPinOptions(17, GPIO_INPUT, GPIO_ASYNC);
|
|
GPIO_SetupPinMux(17,GPIO_MUX_CPU2,1);
|
|
|
|
GPIO_SetupPinOptions(18, GPIO_INPUT, GPIO_ASYNC);
|
|
GPIO_SetupPinMux(18,GPIO_MUX_CPU2,1);
|
|
|
|
GPIO_SetupPinOptions(19, GPIO_OUTPUT, GPIO_ASYNC);
|
|
GPIO_SetupPinMux(19,GPIO_MUX_CPU2,0);
|
|
|
|
break;
|
|
|
|
case C1C2_BROM_BOOTMODE_BOOT_FROM_I2C:
|
|
EALLOW;
|
|
|
|
//
|
|
//I2CA connected to CPU02
|
|
//
|
|
DevCfgRegs.CPUSEL7.bit.I2C_A = 1;
|
|
|
|
//
|
|
//Allows CPU2 bootrom to take control of clock
|
|
//configuration registers
|
|
//
|
|
ClkCfgRegs.CLKSEM.all = 0xA5A50000;
|
|
ClkCfgRegs.LOSPCP.all = 0x0002;
|
|
EDIS;
|
|
GPIO_SetupPinOptions(32, GPIO_INPUT, GPIO_ASYNC);
|
|
GPIO_SetupPinMux(32,GPIO_MUX_CPU2,1);
|
|
|
|
GPIO_SetupPinOptions(33, GPIO_INPUT, GPIO_ASYNC);
|
|
GPIO_SetupPinMux(33,GPIO_MUX_CPU2,1);
|
|
|
|
break;
|
|
case C1C2_BROM_BOOTMODE_BOOT_FROM_PARALLEL:
|
|
|
|
for(pin=58;pin<=65;pin++)
|
|
{
|
|
GPIO_SetupPinOptions(pin, GPIO_INPUT, GPIO_ASYNC);
|
|
GPIO_SetupPinMux(pin,GPIO_MUX_CPU2,0);
|
|
}
|
|
|
|
GPIO_SetupPinOptions(69, GPIO_OUTPUT, GPIO_ASYNC);
|
|
GPIO_SetupPinMux(69,GPIO_MUX_CPU2,0);
|
|
|
|
GPIO_SetupPinOptions(70, GPIO_INPUT, GPIO_ASYNC);
|
|
GPIO_SetupPinMux(70,GPIO_MUX_CPU2,0);
|
|
break;
|
|
|
|
|
|
case C1C2_BROM_BOOTMODE_BOOT_FROM_CAN:
|
|
//
|
|
//Set up the GPIO mux to bring out CANATX on GPIO71
|
|
//and CANARX on GPIO70
|
|
//
|
|
EALLOW;
|
|
GpioCtrlRegs.GPCLOCK.all = 0x00000000; //Unlock GPIOs 64-95
|
|
|
|
//
|
|
//Give CPU2 control just in case
|
|
//
|
|
GpioCtrlRegs.GPCCSEL1.bit.GPIO71 = GPIO_MUX_CPU2;
|
|
|
|
//
|
|
//Set the extended mux to 0x5
|
|
//
|
|
GpioCtrlRegs.GPCGMUX1.bit.GPIO71 = 0x1;
|
|
GpioCtrlRegs.GPCMUX1.bit.GPIO71 = 0x1;
|
|
|
|
//
|
|
//Set qualification to async just in case
|
|
//
|
|
GpioCtrlRegs.GPCQSEL1.bit.GPIO71 = 0x3;
|
|
|
|
GpioCtrlRegs.GPCLOCK.all = 0x00000000; //Unlock GPIOs 64-95
|
|
|
|
//
|
|
//Give CPU2 control just in case
|
|
//
|
|
GpioCtrlRegs.GPCCSEL1.bit.GPIO70 = GPIO_MUX_CPU2;
|
|
|
|
//
|
|
//Set the extended mux to bring out CANATX
|
|
//
|
|
GpioCtrlRegs.GPCGMUX1.bit.GPIO70 = 0x1;
|
|
GpioCtrlRegs.GPCMUX1.bit.GPIO70 = 0x1;
|
|
|
|
//
|
|
//Set qualification to async just in case
|
|
//
|
|
GpioCtrlRegs.GPCQSEL1.bit.GPIO70 = 0x3;
|
|
GpioCtrlRegs.GPCLOCK.all = 0xFFFFFFFF; //Lock GPIOs 64-95
|
|
ClkCfgRegs.CLKSRCCTL2.bit.CANABCLKSEL = 0x0;
|
|
CpuSysRegs.PCLKCR10.bit.CAN_A = 1;
|
|
EDIS;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
//
|
|
//CPU01 to CPU02 IPC Boot Mode Register
|
|
//
|
|
IpcRegs.IPCBOOTMODE = ulBootMode;
|
|
|
|
//
|
|
// CPU01 To CPU02 IPC Command Register
|
|
//
|
|
IpcRegs.IPCSENDCOM = BROM_IPC_EXECUTE_BOOTMODE_CMD;
|
|
|
|
//
|
|
// CPU01 to CPU02 IPC flag register
|
|
//
|
|
IpcRegs.IPCSET.all = 0x80000001;
|
|
|
|
}
|
|
|
|
|
|
|
|
return returnStatus;
|
|
}
|
|
|
|
|
|
#endif
|
|
//*****************************************************************************
|
|
// Close the Doxygen group.
|
|
//! @}
|
|
//*****************************************************************************
|
|
|
|
|