879 lines
32 KiB
C
879 lines
32 KiB
C
|
//###########################################################################
|
||
|
//
|
||
|
// FILE: ipc.h
|
||
|
//
|
||
|
// TITLE: C28x IPC driver.
|
||
|
//
|
||
|
//###########################################################################
|
||
|
// $Copyright:
|
||
|
// Copyright (C) 2022 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.
|
||
|
// $
|
||
|
//###########################################################################
|
||
|
|
||
|
#ifndef IPC_H
|
||
|
#define IPC_H
|
||
|
|
||
|
//*****************************************************************************
|
||
|
//
|
||
|
// If building with a C++ compiler, make all of the definitions in this header
|
||
|
// have a C binding.
|
||
|
//
|
||
|
//*****************************************************************************
|
||
|
#ifdef __cplusplus
|
||
|
extern "C"
|
||
|
{
|
||
|
#endif
|
||
|
|
||
|
//*****************************************************************************
|
||
|
//
|
||
|
//! \addtogroup ipc_api IPC
|
||
|
//! \brief This module is used for inter-processor communications.
|
||
|
//! @{
|
||
|
//
|
||
|
//*****************************************************************************
|
||
|
|
||
|
#include <stdbool.h>
|
||
|
#include <stdint.h>
|
||
|
#include "debug.h"
|
||
|
#include "inc/hw_memmap.h"
|
||
|
#include "inc/hw_types.h"
|
||
|
#include "inc/hw_ipc.h"
|
||
|
#include "inc/hw_ints.h"
|
||
|
#include "interrupt.h"
|
||
|
|
||
|
//*****************************************************************************
|
||
|
//
|
||
|
// Defines for the APIs
|
||
|
//
|
||
|
//*****************************************************************************
|
||
|
//*****************************************************************************
|
||
|
//
|
||
|
// Driver configuration macros
|
||
|
//
|
||
|
//*****************************************************************************
|
||
|
#define IPC_MSGQ_SUPPORT 1U
|
||
|
|
||
|
//
|
||
|
// Number of IPC messages in circular buffer (must be interval of 2)
|
||
|
//
|
||
|
#define IPC_BUFFER_SIZE 4U
|
||
|
|
||
|
//
|
||
|
// Number of IPC interrupts using circular buffer (must be same number on both
|
||
|
// CPUs)
|
||
|
//
|
||
|
#define IPC_NUM_OF_INTERRUPTS 4U
|
||
|
|
||
|
//*****************************************************************************
|
||
|
//
|
||
|
// Values that can be passed as parameter flags in all the IPC API functions.
|
||
|
//
|
||
|
//*****************************************************************************
|
||
|
#ifndef IPC_FLAGS_DEFINED
|
||
|
#define IPC_FLAGS_DEFINED
|
||
|
#define IPC_NO_FLAG 0x00000000U //!< NO FLAG
|
||
|
#define IPC_FLAG0 0x00000001U //!< IPC FLAG 0
|
||
|
#define IPC_FLAG1 0x00000002U //!< IPC FLAG 1
|
||
|
#define IPC_FLAG2 0x00000004U //!< IPC FLAG 2
|
||
|
#define IPC_FLAG3 0x00000008U //!< IPC FLAG 3
|
||
|
#define IPC_FLAG4 0x00000010U //!< IPC FLAG 4
|
||
|
#define IPC_FLAG5 0x00000020U //!< IPC FLAG 5
|
||
|
#define IPC_FLAG6 0x00000040U //!< IPC FLAG 6
|
||
|
#define IPC_FLAG7 0x00000080U //!< IPC FLAG 7
|
||
|
#define IPC_FLAG8 0x00000100U //!< IPC FLAG 8
|
||
|
#define IPC_FLAG9 0x00000200U //!< IPC FLAG 9
|
||
|
#define IPC_FLAG10 0x00000400U //!< IPC FLAG 10
|
||
|
#define IPC_FLAG11 0x00000800U //!< IPC FLAG 11
|
||
|
#define IPC_FLAG12 0x00001000U //!< IPC FLAG 12
|
||
|
#define IPC_FLAG13 0x00002000U //!< IPC FLAG 13
|
||
|
#define IPC_FLAG14 0x00004000U //!< IPC FLAG 14
|
||
|
#define IPC_FLAG15 0x00008000U //!< IPC FLAG 15
|
||
|
#define IPC_FLAG16 0x00010000U //!< IPC FLAG 16
|
||
|
#define IPC_FLAG17 0x00020000U //!< IPC FLAG 17
|
||
|
#define IPC_FLAG18 0x00040000U //!< IPC FLAG 18
|
||
|
#define IPC_FLAG19 0x00080000U //!< IPC FLAG 19
|
||
|
#define IPC_FLAG20 0x00100000U //!< IPC FLAG 20
|
||
|
#define IPC_FLAG21 0x00200000U //!< IPC FLAG 21
|
||
|
#define IPC_FLAG22 0x00400000U //!< IPC FLAG 22
|
||
|
#define IPC_FLAG23 0x00800000U //!< IPC FLAG 23
|
||
|
#define IPC_FLAG24 0x01000000U //!< IPC FLAG 24
|
||
|
#define IPC_FLAG25 0x02000000U //!< IPC FLAG 25
|
||
|
#define IPC_FLAG26 0x04000000U //!< IPC FLAG 26
|
||
|
#define IPC_FLAG27 0x08000000U //!< IPC FLAG 27
|
||
|
#define IPC_FLAG28 0x10000000U //!< IPC FLAG 28
|
||
|
#define IPC_FLAG29 0x20000000U //!< IPC FLAG 29
|
||
|
#define IPC_FLAG30 0x40000000U //!< IPC FLAG 30
|
||
|
#define IPC_FLAG31 0x80000000U //!< IPC FLAG 31
|
||
|
#define IPC_FLAG_ALL 0xFFFFFFFFU //!< All IPC flags
|
||
|
#endif
|
||
|
|
||
|
//*****************************************************************************
|
||
|
//
|
||
|
// Values that can be passed as parameter ipcInt in
|
||
|
// IPC_registerInterrupt and IPC_unregisterInterrupt functions.
|
||
|
// Please refer to the datasheet for the actual number of interrupts available
|
||
|
// for each IPC instance
|
||
|
//
|
||
|
//*****************************************************************************
|
||
|
#define IPC_INT0 0x0U //!< IPC Interrupt 0
|
||
|
#define IPC_INT1 0x1U //!< IPC Interrupt 1
|
||
|
#define IPC_INT2 0x2U //!< IPC Interrupt 2
|
||
|
#define IPC_INT3 0x3U //!< IPC Interrupt 3
|
||
|
#define IPC_INT4 0x4U //!< IPC Interrupt 4
|
||
|
#define IPC_INT5 0x5U //!< IPC Interrupt 5
|
||
|
#define IPC_INT6 0x6U //!< IPC Interrupt 6
|
||
|
#define IPC_INT7 0x7U //!< IPC Interrupt 7
|
||
|
|
||
|
//*****************************************************************************
|
||
|
//
|
||
|
// Values that can be passed as parameter addrCorrEnable in
|
||
|
// IPC_sendCommand, IPC_readCommand, IPC_sendMessageToQueue and
|
||
|
// IPC_readMessageFromQueue functions.
|
||
|
//
|
||
|
//*****************************************************************************
|
||
|
#define IPC_ADDR_CORRECTION_ENABLE true
|
||
|
#define IPC_ADDR_CORRECTION_DISABLE false
|
||
|
|
||
|
//*****************************************************************************
|
||
|
//
|
||
|
// Values that can be passed as parameter block in
|
||
|
// IPC_sendMessageToQueue and IPC_readMessageFromQueue functions.
|
||
|
//
|
||
|
//*****************************************************************************
|
||
|
#define IPC_BLOCKING_CALL true
|
||
|
#define IPC_NONBLOCKING_CALL false
|
||
|
|
||
|
|
||
|
|
||
|
//*****************************************************************************
|
||
|
//
|
||
|
// Internal macros used for message queue implementation
|
||
|
//
|
||
|
//*****************************************************************************
|
||
|
#define IPC_MAX_BUFFER_INDEX (IPC_BUFFER_SIZE - 1U)
|
||
|
|
||
|
//*****************************************************************************
|
||
|
//
|
||
|
// Enums for the APIs
|
||
|
//
|
||
|
//*****************************************************************************
|
||
|
|
||
|
//*****************************************************************************
|
||
|
//
|
||
|
//! Values that can be passed as parameter \e ipcType in all the driver
|
||
|
//! functions
|
||
|
//
|
||
|
//*****************************************************************************
|
||
|
typedef enum
|
||
|
{
|
||
|
IPC_CPU1_L_CPU2_R, //!< CPU1 - Local core, CPU2 - Remote core
|
||
|
IPC_CPU2_L_CPU1_R, //!< CPU2 - Local core, CPU1 - Remote core
|
||
|
IPC_TOTAL_NUM
|
||
|
}IPC_Type_t;
|
||
|
|
||
|
//*****************************************************************************
|
||
|
//
|
||
|
// Internal structs for register and messaage queue accesses
|
||
|
//
|
||
|
//*****************************************************************************
|
||
|
typedef struct
|
||
|
{
|
||
|
uint32_t IPC_ACK;
|
||
|
uint32_t IPC_STS;
|
||
|
uint32_t IPC_SET;
|
||
|
uint32_t IPC_CLR;
|
||
|
uint32_t IPC_FLG;
|
||
|
uint32_t IPC_RSVDREG;
|
||
|
uint32_t IPC_COUNTERL;
|
||
|
uint32_t IPC_COUNTERH;
|
||
|
}IPC_Flag_Ctr_Reg_t;
|
||
|
|
||
|
typedef struct
|
||
|
{
|
||
|
uint32_t IPC_SENDCOM;
|
||
|
uint32_t IPC_SENDADDR;
|
||
|
uint32_t IPC_SENDDATA;
|
||
|
uint32_t IPC_REMOTEREPLY;
|
||
|
}IPC_SendCmd_Reg_t;
|
||
|
|
||
|
typedef struct
|
||
|
{
|
||
|
uint32_t IPC_RECVCOM;
|
||
|
uint32_t IPC_RECVADDR;
|
||
|
uint32_t IPC_RECVDATA;
|
||
|
uint32_t IPC_LOCALREPLY;
|
||
|
}IPC_RecvCmd_Reg_t;
|
||
|
|
||
|
typedef struct
|
||
|
{
|
||
|
uint32_t IPC_BOOTSTS;
|
||
|
uint32_t IPC_BOOTMODE;
|
||
|
}IPC_Boot_Pump_Reg_t;
|
||
|
|
||
|
#if IPC_MSGQ_SUPPORT == 1U
|
||
|
typedef struct
|
||
|
{
|
||
|
uint32_t command;
|
||
|
uint32_t address;
|
||
|
uint32_t dataw1;
|
||
|
uint32_t dataw2;
|
||
|
}IPC_Message_t;
|
||
|
|
||
|
typedef struct
|
||
|
{
|
||
|
IPC_Message_t Buffer[IPC_NUM_OF_INTERRUPTS][IPC_BUFFER_SIZE];
|
||
|
uint16_t PutWriteIndex[IPC_NUM_OF_INTERRUPTS];
|
||
|
uint16_t GetReadIndex[IPC_NUM_OF_INTERRUPTS];
|
||
|
}IPC_PutBuffer_t;
|
||
|
|
||
|
typedef struct
|
||
|
{
|
||
|
IPC_Message_t Buffer[IPC_NUM_OF_INTERRUPTS][IPC_BUFFER_SIZE];
|
||
|
uint16_t GetWriteIndex[IPC_NUM_OF_INTERRUPTS];
|
||
|
uint16_t PutReadIndex[IPC_NUM_OF_INTERRUPTS];
|
||
|
}IPC_GetBuffer_t;
|
||
|
#endif
|
||
|
|
||
|
//*****************************************************************************
|
||
|
//
|
||
|
// Internal struct used to store the required information regarding an IPC
|
||
|
// instance
|
||
|
//
|
||
|
//*****************************************************************************
|
||
|
typedef struct
|
||
|
{
|
||
|
volatile IPC_Flag_Ctr_Reg_t *IPC_Flag_Ctr_Reg;
|
||
|
volatile IPC_SendCmd_Reg_t *IPC_SendCmd_Reg;
|
||
|
volatile IPC_RecvCmd_Reg_t *IPC_RecvCmd_Reg;
|
||
|
volatile IPC_Boot_Pump_Reg_t *IPC_Boot_Pump_Reg;
|
||
|
uint32_t IPC_IntNum[8U];
|
||
|
uint32_t IPC_MsgRam_LtoR;
|
||
|
uint32_t IPC_MsgRam_RtoL;
|
||
|
uint32_t IPC_Offset_Corr;
|
||
|
#if IPC_MSGQ_SUPPORT == 1U
|
||
|
IPC_PutBuffer_t *IPC_PutBuffer;
|
||
|
IPC_GetBuffer_t *IPC_GetBuffer;
|
||
|
#endif
|
||
|
}IPC_Instance_t;
|
||
|
|
||
|
extern const IPC_Instance_t IPC_Instance[IPC_TOTAL_NUM];
|
||
|
|
||
|
#if IPC_MSGQ_SUPPORT == 1U
|
||
|
//*****************************************************************************
|
||
|
//
|
||
|
// A structure that defines an IPC message queue. These
|
||
|
// fields are used by the IPC drivers, and normally it is not necessary for
|
||
|
// user software to directly read or write fields in the table.
|
||
|
//
|
||
|
//*****************************************************************************
|
||
|
|
||
|
typedef struct
|
||
|
{
|
||
|
IPC_Message_t * PutBuffer;
|
||
|
uint32_t PutFlag;
|
||
|
uint16_t * PutWriteIndex;
|
||
|
uint16_t * PutReadIndex;
|
||
|
IPC_Message_t * GetBuffer;
|
||
|
uint16_t * GetWriteIndex;
|
||
|
uint16_t * GetReadIndex;
|
||
|
} IPC_MessageQueue_t;
|
||
|
#endif
|
||
|
|
||
|
//*****************************************************************************
|
||
|
//
|
||
|
// API Function prototypes
|
||
|
//
|
||
|
//*****************************************************************************
|
||
|
|
||
|
//*****************************************************************************
|
||
|
//
|
||
|
//! Local core sets Local to Remote IPC Flag
|
||
|
//!
|
||
|
//! \param ipcType is the enum corresponding to the IPC instance used
|
||
|
//! \param flags is the IPC flag mask for the flags being set
|
||
|
//!
|
||
|
//! This function will allow the Local core system to set the designated IPC
|
||
|
//! flags to send to the Remote core system. The \e flags parameter can be any
|
||
|
//! of the IPC flag values: \b IPC_FLAG0 - \b IPC_FLAG31.
|
||
|
//!
|
||
|
//! \return None.
|
||
|
//
|
||
|
//*****************************************************************************
|
||
|
static inline void
|
||
|
IPC_setFlagLtoR(IPC_Type_t ipcType, uint32_t flags)
|
||
|
{
|
||
|
IPC_Instance[ipcType].IPC_Flag_Ctr_Reg->IPC_SET = flags;
|
||
|
}
|
||
|
|
||
|
//*****************************************************************************
|
||
|
//
|
||
|
//! Local core clears Local to Remote IPC Flag
|
||
|
//!
|
||
|
//! \param ipcType is the enum corresponding to the IPC instance used
|
||
|
//! \param flags is the IPC flag mask for the flags being cleared
|
||
|
//!
|
||
|
//! This function will allow the Local core system to clear the designated IPC
|
||
|
//! flags sent to the Remote core system. The \e flags parameter can be any
|
||
|
//! of the IPC flag values: \b IPC_FLAG0 - \b IPC_FLAG31.
|
||
|
//!
|
||
|
//! \return None.
|
||
|
//
|
||
|
//*****************************************************************************
|
||
|
static inline void
|
||
|
IPC_clearFlagLtoR(IPC_Type_t ipcType, uint32_t flags)
|
||
|
{
|
||
|
IPC_Instance[ipcType].IPC_Flag_Ctr_Reg->IPC_CLR = flags;
|
||
|
}
|
||
|
|
||
|
//*****************************************************************************
|
||
|
//
|
||
|
//! Local core acknowledges Remote to Local IPC Flag.
|
||
|
//!
|
||
|
//! \param ipcType is the enum corresponding to the IPC instance used
|
||
|
//! \param flags is the IPC flag mask for the flags being acknowledged.
|
||
|
//!
|
||
|
//! This function will allow the Local core system to acknowledge/clear the IPC
|
||
|
//! flag set by the Remote core system. The \e flags parameter can be any of
|
||
|
//! the IPC flag values: \b IPC_FLAG0 - \b IPC_FLAG31.
|
||
|
//!
|
||
|
//! \return None.
|
||
|
//
|
||
|
//*****************************************************************************
|
||
|
static inline void
|
||
|
IPC_ackFlagRtoL(IPC_Type_t ipcType, uint32_t flags)
|
||
|
{
|
||
|
IPC_Instance[ipcType].IPC_Flag_Ctr_Reg->IPC_ACK = flags;
|
||
|
}
|
||
|
|
||
|
//*****************************************************************************
|
||
|
//
|
||
|
//! Determines whether the given IPC flags are busy or not.
|
||
|
//!
|
||
|
//! \param ipcType is the enum corresponding to the IPC instance used
|
||
|
//! \param flags is the Local to Remote IPC flag masks to check the status of
|
||
|
//!
|
||
|
//! Allows the caller to determine whether the designated Local to Remote
|
||
|
//! IPC flags are pending. The \e flags parameter can be any of the IPC flag
|
||
|
//! values: \b IPC_FLAG0 - \b IPC_FLAG31.
|
||
|
//!
|
||
|
//! \return Returns \b true if the any of the designated IPC flags are busy
|
||
|
//! or \b false if all the designated IPC flags are free.
|
||
|
//
|
||
|
//*****************************************************************************
|
||
|
static inline bool
|
||
|
IPC_isFlagBusyLtoR(IPC_Type_t ipcType, uint32_t flags)
|
||
|
{
|
||
|
return((IPC_Instance[ipcType].IPC_Flag_Ctr_Reg->IPC_FLG & flags) != 0U);
|
||
|
}
|
||
|
|
||
|
//*****************************************************************************
|
||
|
//
|
||
|
//! Determines whether the given Remote to Local IPC flags are busy or not.
|
||
|
//!
|
||
|
//! \param ipcType is the enum corresponding to the IPC instance used
|
||
|
//! \param flags is the Remote to Local IPC Flag masks to check the status of
|
||
|
//!
|
||
|
//! Allows the caller to determine whether the designated Remote to Local
|
||
|
//! IPC flags are pending. The \e flags parameter can be any of the IPC flag
|
||
|
//! values: \b IPC_FLAG0 - \b IPC_FLAG31.
|
||
|
//!
|
||
|
//! \return Returns \b true if the any of the designated IPC flags are busy
|
||
|
//! or \b false if all the designated IPC flags are free.
|
||
|
//
|
||
|
//*****************************************************************************
|
||
|
static inline bool
|
||
|
IPC_isFlagBusyRtoL(IPC_Type_t ipcType, uint32_t flags)
|
||
|
{
|
||
|
return((IPC_Instance[ipcType].IPC_Flag_Ctr_Reg->IPC_STS & flags) != 0U);
|
||
|
}
|
||
|
|
||
|
//*****************************************************************************
|
||
|
//
|
||
|
//! Wait for the remote core to send a flag
|
||
|
//!
|
||
|
//! \param ipcType is the enum corresponding to the IPC instance used
|
||
|
//! \param flag is the Remote to Local IPC flag mask to wait for
|
||
|
//!
|
||
|
//! Allows the caller to wait for the Remote to Local flag to be send by
|
||
|
//! the remote core. The \e flags parameter can be any of the IPC flag
|
||
|
//! values: \b IPC_FLAG0 - \b IPC_FLAG31.
|
||
|
//!
|
||
|
//! \return None
|
||
|
//
|
||
|
//*****************************************************************************
|
||
|
static inline void
|
||
|
IPC_waitForFlag(IPC_Type_t ipcType, uint32_t flag)
|
||
|
{
|
||
|
while((IPC_Instance[ipcType].IPC_Flag_Ctr_Reg->IPC_STS & flag) == 0U)
|
||
|
{
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//*****************************************************************************
|
||
|
//
|
||
|
//! Wait for the IPC flag to be acknowledged
|
||
|
//!
|
||
|
//! \param ipcType is the enum corresponding to the IPC instance used
|
||
|
//! \param flag is the IPC flag mask for which ack is pending
|
||
|
//!
|
||
|
//! Allows the caller to wait for the IPC flag to be acknowledged by the
|
||
|
//! remote core. The \e flagsparameter can be any of the IPC flag values:
|
||
|
//! \b IPC_FLAG0 - \b IPC_FLAG31.
|
||
|
//!
|
||
|
//! \return None
|
||
|
//
|
||
|
//*****************************************************************************
|
||
|
static inline void
|
||
|
IPC_waitForAck(IPC_Type_t ipcType, uint32_t flag)
|
||
|
{
|
||
|
while((IPC_Instance[ipcType].IPC_Flag_Ctr_Reg->IPC_FLG & flag) != 0U)
|
||
|
{
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//*****************************************************************************
|
||
|
//
|
||
|
//! Synchronises the two cores
|
||
|
//!
|
||
|
//! \param ipcType is the enum corresponding to the IPC instance used
|
||
|
//! \param flag is the IPC flag mask with which synchronisation is done
|
||
|
//!
|
||
|
//! Allows the local and remote cores to synchronise. Neither core will return
|
||
|
//! from this function call before the other core enters it.
|
||
|
//!
|
||
|
//! \note Must be called with same flag mask on both the cores
|
||
|
//!
|
||
|
//! \return None
|
||
|
//
|
||
|
//*****************************************************************************
|
||
|
static inline void
|
||
|
IPC_sync(IPC_Type_t ipcType, uint32_t flag)
|
||
|
{
|
||
|
IPC_setFlagLtoR(ipcType, flag);
|
||
|
IPC_waitForFlag(ipcType, flag);
|
||
|
IPC_ackFlagRtoL(ipcType, flag);
|
||
|
IPC_waitForAck(ipcType, flag);
|
||
|
}
|
||
|
|
||
|
//*****************************************************************************
|
||
|
//
|
||
|
//! Initialize IPC
|
||
|
//!
|
||
|
//! \param ipcType is the enum corresponding to the IPC instance used
|
||
|
//
|
||
|
//! This function initializes IPC by clearing all the flags
|
||
|
//!
|
||
|
//! \return None
|
||
|
//
|
||
|
//*****************************************************************************
|
||
|
static inline void
|
||
|
IPC_init(IPC_Type_t ipcType)
|
||
|
{
|
||
|
IPC_clearFlagLtoR(ipcType, IPC_FLAG_ALL);
|
||
|
}
|
||
|
|
||
|
//*****************************************************************************
|
||
|
//
|
||
|
//! Sends a command to the Remote core
|
||
|
//!
|
||
|
//! \param ipcType is the enum corresponding to the IPC instance used
|
||
|
//! \param flags is the IPC flag mask for the flags to be set
|
||
|
//! \param addrCorrEnable is the flag used to determine whether or not to
|
||
|
//! convert the addr parameter to remote core's address space
|
||
|
//! \param command is the 32-bit command value
|
||
|
//! \param addr is the 32-bit address to be sent as part of command
|
||
|
//! \param data is the 32-bit data to be sent as part of command
|
||
|
//!
|
||
|
//! Allows the caller to send a command to the remote core. A command consists
|
||
|
//! of a unique command value, a 32-bit address and a 32-bit data. The function
|
||
|
//! also sends the designated flags to the remote core.
|
||
|
//! There may be differences in the address spaces of Local and Remote core.
|
||
|
//! For example in case of F2838X device, the address spaces of C28x core and
|
||
|
//! CM core are different. In case the \e addr refers to an address in the IPC
|
||
|
//! MSG RAM, \e addrCorrEnable param may be used to correct the address mismatch
|
||
|
//!
|
||
|
//! The \e flags parameter can be any of the IPC flag values: \b IPC_FLAG0 -
|
||
|
//! \b IPC_FLAG31.
|
||
|
//! The \e addrCorrEnable parameter can take values IPC_ADDR_CORRECTION_ENABLE
|
||
|
//! (converts the address to remote core's address space) or
|
||
|
//! IPC_ADDR_CORRECTION_DISABLE(does not modify the addr parmeter)
|
||
|
//!
|
||
|
//! The application shall use the function IPC_getResponse to read the response
|
||
|
//! sent by the remote core.
|
||
|
//!
|
||
|
//! \note The application is expected to wait until the the response is
|
||
|
//! received before sending another command.
|
||
|
//!
|
||
|
//! \note \e addrCorrEnable parameter must be kept same on the sending and
|
||
|
//! receiving cores
|
||
|
//!
|
||
|
//! \return Returns \b true if the command is sent properly and \b false if
|
||
|
//! the designated flags were busy and hence command was not sent.
|
||
|
//
|
||
|
//*****************************************************************************
|
||
|
extern bool
|
||
|
IPC_sendCommand(IPC_Type_t ipcType, uint32_t flags, bool addrCorrEnable,
|
||
|
uint32_t command, uint32_t addr, uint32_t data);
|
||
|
|
||
|
//*****************************************************************************
|
||
|
//
|
||
|
//! Reads a command sent by the Remote core
|
||
|
//!
|
||
|
//! \param ipcType is the enum corresponding to the IPC instance used
|
||
|
//! \param flags is the IPC flag mask for the flags sent by the remote core
|
||
|
//! \param addrCorrEnable is the flag used to determine whether or not to
|
||
|
//! convert the addr parameter to remote core's address space
|
||
|
//! \param command is the 32-bit pointer at which the command value is read to
|
||
|
//! \param addr is the 32-bit pointer at which address value is read to
|
||
|
//! \param data is the 32-bit pointer at which the data is read to
|
||
|
//!
|
||
|
//! Allows the caller to read a command sent by the remote core. A command
|
||
|
//! consists of a unique command value, a 32-bit address and a 32-bit data.
|
||
|
//! There may be differences in the address spaces of Local and Remote core.
|
||
|
//! For example in case of F2838X device, the address spaces of C28x core and
|
||
|
//! CM core are different. In case the \e addr refers to an address in the IPC
|
||
|
//! MSG RAM, \e addrCorrEnable param may be used to correct the address mismatch
|
||
|
//!
|
||
|
//! The \e flags parameter can be any of the IPC flag values: \b IPC_FLAG0 -
|
||
|
//! \b IPC_FLAG31.
|
||
|
//! The \e addrCorrEnable parameter can take values IPC_ADDR_CORRECTION_ENABLE
|
||
|
//! (converts the address to remote core's address space) or
|
||
|
//! IPC_ADDR_CORRECTION_DISABLE(does not modify the addr parmeter)
|
||
|
//!
|
||
|
//! \note The application is expected to acknowledge the flag and send a
|
||
|
//! response (if needed) after reading the command
|
||
|
//!
|
||
|
//! \note \e addrCorrEnable parameter must be kept same on the sending and
|
||
|
//! receiving cores
|
||
|
//!
|
||
|
//! \return Returns \b true if the command is read properly and \b false if
|
||
|
//! the designated flags were empty and hence command was not read.
|
||
|
//
|
||
|
//*****************************************************************************
|
||
|
extern bool
|
||
|
IPC_readCommand(IPC_Type_t ipcType, uint32_t flags, bool addrCorrEnable,
|
||
|
uint32_t *command, uint32_t *addr, uint32_t *data);
|
||
|
|
||
|
//*****************************************************************************
|
||
|
//
|
||
|
//! Sends the response to the command sent by remote core.
|
||
|
//!
|
||
|
//! \param ipcType is the enum corresponding to the IPC instance used
|
||
|
//! \param data is the 32-bit value of the response to be sent
|
||
|
//!
|
||
|
//! Allows the caller to send a response to the command previously sent by the
|
||
|
//! remote core
|
||
|
//!
|
||
|
//! \return None.
|
||
|
//
|
||
|
//*****************************************************************************
|
||
|
static inline void
|
||
|
IPC_sendResponse(IPC_Type_t ipcType, uint32_t data)
|
||
|
{
|
||
|
IPC_Instance[ipcType].IPC_RecvCmd_Reg->IPC_LOCALREPLY = data;
|
||
|
}
|
||
|
|
||
|
//*****************************************************************************
|
||
|
//
|
||
|
//! Reads the response from the remote core.
|
||
|
//!
|
||
|
//! \param ipcType is the enum corresponding to the IPC instance used
|
||
|
//!
|
||
|
//! Allows the caller to read the response sent by the remote core to the
|
||
|
//! command previously sent by the local core
|
||
|
//!
|
||
|
//! \return the 32-bit value of the response.
|
||
|
//
|
||
|
//*****************************************************************************
|
||
|
static inline uint32_t
|
||
|
IPC_getResponse(IPC_Type_t ipcType)
|
||
|
{
|
||
|
return(IPC_Instance[ipcType].IPC_SendCmd_Reg->IPC_REMOTEREPLY);
|
||
|
}
|
||
|
|
||
|
//*****************************************************************************
|
||
|
//
|
||
|
//! Sets the BOOTMODE register.
|
||
|
//!
|
||
|
//! \param ipcType is the enum corresponding to the IPC instance used
|
||
|
//! \param mode is the 32-bit value to be set
|
||
|
//!
|
||
|
//! Allows the caller to set the BOOTMODE register.
|
||
|
//!
|
||
|
//! \note This function shall be called by CPU1 only.
|
||
|
//!
|
||
|
//! \return None
|
||
|
//
|
||
|
//*****************************************************************************
|
||
|
static inline void
|
||
|
IPC_setBootMode(IPC_Type_t ipcType, uint32_t mode)
|
||
|
{
|
||
|
ASSERT(ipcType == IPC_CPU1_L_CPU2_R);
|
||
|
|
||
|
IPC_Instance[ipcType].IPC_Boot_Pump_Reg->IPC_BOOTMODE = mode;
|
||
|
}
|
||
|
|
||
|
//*****************************************************************************
|
||
|
//
|
||
|
//! Reads the BOOTMODE register.
|
||
|
//!
|
||
|
//! \param ipcType is the enum corresponding to the IPC instance used
|
||
|
//!
|
||
|
//! Allows the caller to read the BOOTMODE register.
|
||
|
//!
|
||
|
//!
|
||
|
//! \return 32-bit value of the BOOOTMODE register
|
||
|
//
|
||
|
//*****************************************************************************
|
||
|
static inline uint32_t
|
||
|
IPC_getBootMode(IPC_Type_t ipcType)
|
||
|
{
|
||
|
return(IPC_Instance[ipcType].IPC_Boot_Pump_Reg->IPC_BOOTMODE);
|
||
|
}
|
||
|
|
||
|
//*****************************************************************************
|
||
|
//
|
||
|
//! Sets the BOOTSTS register.
|
||
|
//!
|
||
|
//! \param ipcType is the enum corresponding to the IPC instance used
|
||
|
//! \param status is the 32-bit value to be set
|
||
|
//!
|
||
|
//! Allows the caller to set the BOOTSTS register.
|
||
|
//!
|
||
|
//! \note This function shall be called by CPU2 and CM only
|
||
|
//!
|
||
|
//! \note This function shall be called by CPU2 only.
|
||
|
//!
|
||
|
//! \return None.
|
||
|
//
|
||
|
//*****************************************************************************
|
||
|
static inline void
|
||
|
IPC_setBootStatus(IPC_Type_t ipcType, uint32_t status)
|
||
|
{
|
||
|
ASSERT(ipcType == IPC_CPU2_L_CPU1_R);
|
||
|
|
||
|
IPC_Instance[ipcType].IPC_Boot_Pump_Reg->IPC_BOOTSTS = status;
|
||
|
}
|
||
|
|
||
|
//*****************************************************************************
|
||
|
//
|
||
|
//! Reads the BOOTSTS register.
|
||
|
//!
|
||
|
//! \param ipcType is the enum corresponding to the IPC instance used
|
||
|
//!
|
||
|
//! Allows the caller to set the BOOTMODE register.
|
||
|
//!
|
||
|
//!
|
||
|
//! \return 32-bit value of the BOOOTSTS register
|
||
|
//
|
||
|
//*****************************************************************************
|
||
|
static inline uint32_t
|
||
|
IPC_getBootStatus(IPC_Type_t ipcType)
|
||
|
{
|
||
|
return(IPC_Instance[ipcType].IPC_Boot_Pump_Reg->IPC_BOOTSTS);
|
||
|
}
|
||
|
|
||
|
//*****************************************************************************
|
||
|
//
|
||
|
//! Reads the timestamp counter value.
|
||
|
//!
|
||
|
//! \param ipcType is the enum corresponding to the IPC instance used
|
||
|
//!
|
||
|
//! Allows the caller to read the IPC timestamp counter value.
|
||
|
//!
|
||
|
//! \return 64-bit counter value.
|
||
|
//
|
||
|
//*****************************************************************************
|
||
|
static inline uint64_t
|
||
|
IPC_getCounter(IPC_Type_t ipcType)
|
||
|
{
|
||
|
//
|
||
|
// Get the Counter High and Low values. Read to the Counter low register
|
||
|
// saves the value of Counter High register.
|
||
|
//
|
||
|
uint32_t ctrL = IPC_Instance[ipcType].IPC_Flag_Ctr_Reg->IPC_COUNTERL;
|
||
|
uint32_t ctrH = IPC_Instance[ipcType].IPC_Flag_Ctr_Reg->IPC_COUNTERH;
|
||
|
|
||
|
//
|
||
|
// Return the 64-bit value of the counter
|
||
|
//
|
||
|
return(((uint64_t)ctrH << 32) | ((uint64_t)ctrL));
|
||
|
}
|
||
|
|
||
|
//*****************************************************************************
|
||
|
//
|
||
|
//! Registers an interrupt handler for IPC
|
||
|
//!
|
||
|
//! \param ipcType is the enum corresponding to the IPC instance used
|
||
|
//! \param ipcInt is the Flag number for which interrupt is being registered
|
||
|
//! \param pfnHandler is the pointer to ISR function
|
||
|
//!
|
||
|
//! This function registers the handler to be called when an IPC interrupt
|
||
|
//! occurs. This function enables the global interrupt in the interrupt
|
||
|
//! controller.
|
||
|
//! The \e ipcInt parameter can be any of the IPC flag values:\b IPC_INT0 -
|
||
|
//! \b IPC_INT7. IPC_INT0 corresponds to IPC Flag 0 interrupt and so on.
|
||
|
//
|
||
|
//*****************************************************************************
|
||
|
extern void
|
||
|
IPC_registerInterrupt(IPC_Type_t ipcType, uint32_t ipcInt,
|
||
|
void (*pfnHandler)(void));
|
||
|
|
||
|
//*****************************************************************************
|
||
|
//
|
||
|
//! Unregisters an interrupt handler for IPC
|
||
|
//!
|
||
|
//! \param ipcType is the enum corresponding to the IPC instance used
|
||
|
//! \param ipcInt is the Flag number for which interrupt is being unregistered
|
||
|
//!
|
||
|
//! This function clears the handler to be called when an IPC interrupt
|
||
|
//! occurs. This function also masks off the interrupt in the interrupt
|
||
|
//! controller so that the interrupt handler no longer is called.
|
||
|
//! The \e ipcInt parameter can be any of the IPC flag values:\b IPC_INT0 -
|
||
|
//! \b IPC_INT7. IPC_INT0 corresponds to IPC Flag 0 interrupt and so on.
|
||
|
//
|
||
|
//*****************************************************************************
|
||
|
extern void
|
||
|
IPC_unregisterInterrupt(IPC_Type_t ipcType, uint32_t ipcInt);
|
||
|
|
||
|
#if IPC_MSGQ_SUPPORT == 1U
|
||
|
//*****************************************************************************
|
||
|
//
|
||
|
//! Initializes the IPC message queue
|
||
|
//!
|
||
|
//! \param ipcType is the enum corresponding to the IPC instance used
|
||
|
//! \param msgQueue specifies the address of a \e IPC_MessageQueue_t instance
|
||
|
//! \param ipcInt_L specifies the interrupt number on the local core used by
|
||
|
//! the message queue .
|
||
|
//! \param ipcInt_R specifies the interrupt number on the remote core used by
|
||
|
//! the message queue.
|
||
|
//!
|
||
|
//! This function initializes the IPC message queue with circular buffer
|
||
|
//! and index addresses for an IPC interrupt pair. The
|
||
|
//! \e ipcInt_L and \e ipcInt_R parameters can be one of the following values:
|
||
|
//! \b IPC_INT0, \b IPC_INT1, \b IPC_INT2, \b IPC_INT3.
|
||
|
//!
|
||
|
//! \note If an interrupt is currently in use by an \e IPC_MessageQueue_t
|
||
|
//! instance, that particular interrupt should not be tied to a second
|
||
|
//! \e IPC_MessageQueue_t instance.
|
||
|
//!
|
||
|
//! \note For a particular ipcInt_L - ipcInt_R pair, there must be an instance
|
||
|
//! of IPC_MessageQueue_t defined and initialized on both the locakl and remote
|
||
|
//! systems.
|
||
|
//!
|
||
|
//! \return None.
|
||
|
//
|
||
|
//*****************************************************************************
|
||
|
extern void
|
||
|
IPC_initMessageQueue(IPC_Type_t ipcType, volatile IPC_MessageQueue_t *msgQueue,
|
||
|
uint32_t ipcInt_L, uint32_t ipcInt_R);
|
||
|
|
||
|
//*****************************************************************************
|
||
|
//
|
||
|
//! Sends a message into the messageQueue.
|
||
|
//!
|
||
|
//! \param ipcType is the enum corresponding to the IPC instance used
|
||
|
//! \param msgQueue specifies the address of a \e IPC_MessageQueue_t instance
|
||
|
//! \param addrCorrEnable is the flag used to determine whether or not to
|
||
|
//! convert the addr parameter to remote core's address space
|
||
|
//! \param msg specifies the address of the \e IPC_Message_t instance to be
|
||
|
//! sent to message queue.
|
||
|
//! \param block specifies whether to allow function to block until the buffer
|
||
|
//! has a free slot
|
||
|
//!
|
||
|
//! This function checks if there is a free slot in the message queue. If so, it
|
||
|
//! puts the message pointed to by \e msg into the free and sets the
|
||
|
//! appropriate IPC interrupt flag
|
||
|
//!
|
||
|
//! The \e addrCorrEnable parameter can take values IPC_ADDR_CORRECTION_ENABLE
|
||
|
//! (converts the address to remote core's address space) or
|
||
|
//! IPC_ADDR_CORRECTION_DISABLE(does not modify the addr parmeter)
|
||
|
//! The \e block parameter can be one of the following values:
|
||
|
//! \b IPC_BLOCKING_CALL or \b IPC_NONBLOCKING_CALL.
|
||
|
//!
|
||
|
//! \return \b false if the queue is full. \b true if the message is
|
||
|
//! successfully sent.
|
||
|
//
|
||
|
//*****************************************************************************
|
||
|
extern bool
|
||
|
IPC_sendMessageToQueue(IPC_Type_t ipcType,
|
||
|
volatile IPC_MessageQueue_t *msgQueue,
|
||
|
bool addrCorrEnable, IPC_Message_t *msg, bool block);
|
||
|
|
||
|
//*****************************************************************************
|
||
|
//
|
||
|
//! Reads a message from the messageQueue.
|
||
|
//!
|
||
|
//! \param ipcType is the enum corresponding to the IPC instance used
|
||
|
//! \param msgQueue specifies the address of a \e IPC_MessageQueue_t instance
|
||
|
//! \param addrCorrEnable is the flag used to determine whether or not to
|
||
|
//! convert the addr parameter to remote core's address space
|
||
|
//! \param msg specifies the address of the \e IPC_Message_t instance to which
|
||
|
//! the message needs to be read
|
||
|
//! \param block specifies whether to allow function to block until a message
|
||
|
//! is available in the message queue
|
||
|
//!
|
||
|
//! This function checks if there is a message in the message queue. If so, it
|
||
|
//! reads the message and writes to the address pointed to by \e msg into.
|
||
|
//!
|
||
|
//! The \e addrCorrEnable parameter can take values IPC_ADDR_CORRECTION_ENABLE
|
||
|
//! (converts the address to remote core's address space) or
|
||
|
//! IPC_ADDR_CORRECTION_DISABLE(does not modify the addr parmeter)
|
||
|
//! The \e block parameter can be one of the following values:
|
||
|
//! \b IPC_BLOCKING_CALL or \b IPC_NONBLOCKING_CALL.
|
||
|
//!
|
||
|
//! \return \b false if the queue is empty. \b true if the message successfully
|
||
|
//! read.
|
||
|
//
|
||
|
//*****************************************************************************
|
||
|
extern bool
|
||
|
IPC_readMessageFromQueue(IPC_Type_t ipcType,
|
||
|
volatile IPC_MessageQueue_t *msgQueue,
|
||
|
bool addrCorrEnable, IPC_Message_t *msg, bool block);
|
||
|
#endif
|
||
|
//*****************************************************************************
|
||
|
//
|
||
|
// Close the Doxygen group.
|
||
|
//! @}
|
||
|
//
|
||
|
//*****************************************************************************
|
||
|
|
||
|
//*****************************************************************************
|
||
|
//
|
||
|
// Mark the end of the C bindings section for C++ compilers.
|
||
|
//
|
||
|
//*****************************************************************************
|
||
|
#ifdef __cplusplus
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
#endif // IPC_H
|