forked from gatsby/datalink_repo
Initial version.
This commit is contained in:
@@ -0,0 +1,211 @@
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* Description: Implementations of chip to chip data bridge.
|
||||
*
|
||||
* Author: Fan Hao
|
||||
* Date: 2022-09-02 15:01
|
||||
* LastEditors: Fan Hao
|
||||
* LastEditTime: 2022-09-02 15:49
|
||||
* Revisions: Rev 0.0
|
||||
* History:
|
||||
* [2022-09-02]: Initial version
|
||||
*
|
||||
* Note:
|
||||
* Branch from Analog Devices version (by DBogdan [email protected]).
|
||||
*
|
||||
* Copyright(c) 2022 Beijing Institute of Technology.
|
||||
* Lab of Communication and Networking
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/***************************** Include Files **********************************/
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "c2c_bridge.h"
|
||||
#include "xgpio.h"
|
||||
#include "../axi_dma/axi_dma.h"
|
||||
#include "../util/util.h"
|
||||
#include "../error.h"
|
||||
#include "../common.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
// C2C Configs
|
||||
#define C2C_GPIO_OUT_CH 1
|
||||
#define C2C_SEND_TRIGGER BIT(0)
|
||||
#define C2C_RECV_TRIGGER BIT(1)
|
||||
|
||||
/************************** Variable Definitions *****************************/
|
||||
C2C_DESC* c2cInstPtr = NULL;
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
inline bool C2c_IsSendBusy(C2C_DESC* instPtr){
|
||||
ASSERT(instPtr != NULL);
|
||||
return (instPtr->txDone == false);
|
||||
}
|
||||
|
||||
inline bool C2c_IsRecvBusy(C2C_DESC* instPtr){
|
||||
ASSERT(instPtr != NULL);
|
||||
return (instPtr->rxDone == false);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* @brief Initialize c2c bridge descriptor instance.
|
||||
*
|
||||
* @param instPtr second rank pointer to c2c instance.
|
||||
* @param configPtr pointer to c2c instance configuration struct.
|
||||
*
|
||||
* @return NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
int32_t C2c_Init(C2C_DESC** instPtr, C2C_CONFIG* configPtr){
|
||||
ASSERT(configPtr != NULL);
|
||||
int32_t Status;
|
||||
(*instPtr) = (C2C_DESC*)malloc(sizeof(C2C_DESC));
|
||||
if((*instPtr) == NULL){
|
||||
return EALLOC;
|
||||
}
|
||||
memcpy(&(*instPtr)->c2cCofig, configPtr, sizeof(C2C_CONFIG));
|
||||
Status = Dma_Init(&((*instPtr)->axiDmaInst), &(*instPtr)->c2cCofig.dmaConfig);
|
||||
if(Status != SUCCESS){
|
||||
DBG_ERROR("C2C axi DMA init failed, with error code: %d.\r\n", Status);
|
||||
return Status;
|
||||
}
|
||||
(*instPtr)->isInit = true;
|
||||
(*instPtr)->txDone = true;
|
||||
(*instPtr)->rxDone = true;
|
||||
(*instPtr)->lastRxBuff = (uintptr_t)NULL;
|
||||
(*instPtr)->lastRxBuffSize = 0;
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
int32_t C2c_IrqEnable(C2C_DESC* instPtr){
|
||||
if(instPtr==NULL || instPtr->isInit == false){
|
||||
return FAILURE;
|
||||
}
|
||||
/* Enable all interrupts */
|
||||
return Dma_IrqEnable(instPtr->axiDmaInst);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* @brief Send data through c2c bridge.
|
||||
*
|
||||
* @param instPtr second rank pointer to c2c instance.
|
||||
* @param buff data buffer stores the data needs to be sent
|
||||
* @param dLen data length needs to be sent
|
||||
*
|
||||
* @return NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
int32_t C2c_SendData(C2C_DESC* instPtr, uint8_t* buff, uint32_t dLen){
|
||||
ASSERT(instPtr != NULL);
|
||||
ASSERT(buff != NULL);
|
||||
if(instPtr->isInit == false){
|
||||
return EDINVAL;
|
||||
}
|
||||
if(dLen > instPtr->c2cCofig.capacity){
|
||||
return EPARAM;
|
||||
}
|
||||
IO_Out32((uintptr_t)(buff + C2C_HEAD_OFFSET), C2C_HEADER);
|
||||
IO_Out32((uintptr_t)(buff + C2C_DLEN_OFFSET), dLen + C2C_HEADER_LEN);
|
||||
instPtr->txDone = false;
|
||||
instPtr->lastTxBuff = (uintptr_t)buff;
|
||||
instPtr->lastTxBuffSize = dLen;
|
||||
if (SUCCESS == Dma_SendData(instPtr->axiDmaInst, buff, dLen + C2C_HEADER_LEN)){
|
||||
return SUCCESS;
|
||||
}
|
||||
else{
|
||||
return FAILURE;
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
int32_t C2c_BlockingSendData(C2C_DESC* instPtr, uint8_t* buff, uint32_t dLen) {
|
||||
ASSERT(instPtr != NULL);
|
||||
ASSERT(buff != NULL);
|
||||
if(instPtr->isInit == false){
|
||||
return EDINVAL;
|
||||
}
|
||||
if(dLen > instPtr->c2cCofig.capacity){
|
||||
return EPARAM;
|
||||
}
|
||||
IO_Out32((uintptr_t)(buff + C2C_HEAD_OFFSET), C2C_HEADER);
|
||||
IO_Out32((uintptr_t)(buff + C2C_DLEN_OFFSET), dLen + C2C_HEADER_LEN);
|
||||
instPtr->txDone = false;
|
||||
instPtr->lastTxBuff = (uintptr_t)buff;
|
||||
instPtr->lastTxBuffSize = dLen;
|
||||
if (SUCCESS == Dma_BlockingSendData(instPtr->axiDmaInst, buff, dLen + C2C_HEADER_LEN)){
|
||||
return SUCCESS;
|
||||
}
|
||||
else{
|
||||
return FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* @brief Receive data from c2c bridge.
|
||||
*
|
||||
* @param instPtr second rank pointer to c2c instance.
|
||||
* @param buff data buffer stores the received data.
|
||||
* @param dLen data length that received
|
||||
*
|
||||
* @return NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
int32_t C2c_RecvData(C2C_DESC* instPtr, uint8_t* buff, uint32_t buffSize){
|
||||
ASSERT(instPtr != NULL);
|
||||
ASSERT(buff != NULL);
|
||||
if(instPtr->isInit == false){
|
||||
return EDINVAL;
|
||||
}
|
||||
instPtr->rxDone = false;
|
||||
instPtr->lastRxBuff = (uintptr_t)buff;
|
||||
instPtr->lastRxBuffSize = buffSize;
|
||||
if (SUCCESS == Dma_RecvData(instPtr->axiDmaInst, buff, buffSize)){
|
||||
return SUCCESS;
|
||||
}
|
||||
else{
|
||||
return FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t C2c_SendIrqHandler(C2C_DESC* instPtr){
|
||||
ASSERT(instPtr != NULL);
|
||||
if(instPtr->isInit == false){
|
||||
return EDINVAL;
|
||||
}
|
||||
instPtr->txDone = true;
|
||||
if (SUCCESS == Dma_SendIrqHandler(instPtr->axiDmaInst)){
|
||||
return SUCCESS;
|
||||
}
|
||||
else{
|
||||
return EUNEXP;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t C2c_RecvIrqHandler(C2C_DESC* instPtr){
|
||||
ASSERT(instPtr != NULL);
|
||||
if(instPtr->isInit == false){
|
||||
return EDINVAL;
|
||||
}
|
||||
instPtr->rxDone = true;
|
||||
if (SUCCESS == Dma_RecvIrqHandler(instPtr->axiDmaInst)){
|
||||
return SUCCESS;
|
||||
}
|
||||
else{
|
||||
return EUNEXP;
|
||||
}
|
||||
if(IO_In32(instPtr->lastRxBuff + C2C_HEAD_OFFSET) != C2C_HEADER){
|
||||
return EIGNORE;
|
||||
}
|
||||
if(IO_In32(instPtr->lastRxBuff + C2C_DLEN_OFFSET) > instPtr->lastRxBuffSize){
|
||||
return EIGNORE;
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* Description: Chip to chip data bridge.
|
||||
*
|
||||
* Author: Fan Hao
|
||||
* Date: 2022-09-02 15:01
|
||||
* LastEditors: Fan Hao
|
||||
* LastEditTime: 2022-09-02 15:49
|
||||
* Revisions: Rev 0.0
|
||||
* History:
|
||||
* [2022-09-02]: Initial version
|
||||
* [2023-02-23]: DMA version
|
||||
*
|
||||
* Note:
|
||||
* Branch from Analog Devices version (by DBogdan [email protected]).
|
||||
*
|
||||
* Copyright(c) 2022 Beijing Institute of Technology.
|
||||
* Lab of Communication and Networking
|
||||
*
|
||||
******************************************************************************/
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "../axi_dma/axi_dma.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
#define C2C_HEADER_LEN 8 //bytes
|
||||
#define C2C_HEADER 0x7E7E7E7E
|
||||
#define C2C_HEAD_OFFSET 0
|
||||
#define C2C_DLEN_OFFSET 4
|
||||
#define C2C_PLOAD_OFFSET 8
|
||||
#define C2C_BUFF_MAX 1024
|
||||
/**************************** Type Definitions *******************************/
|
||||
typedef struct {
|
||||
uint32_t capacity;
|
||||
DMA_CONFIG dmaConfig;
|
||||
} C2C_CONFIG;
|
||||
|
||||
typedef struct {
|
||||
C2C_CONFIG c2cCofig;
|
||||
DMA_DESC* axiDmaInst;
|
||||
bool isInit;
|
||||
bool txDone;
|
||||
bool rxDone;
|
||||
uintptr_t lastTxBuff;
|
||||
uint32_t lastTxBuffSize;
|
||||
uintptr_t lastRxBuff;
|
||||
uint32_t lastRxBuffSize;
|
||||
} C2C_DESC;
|
||||
|
||||
/************************** Variable Definitions *****************************/
|
||||
extern C2C_DESC* c2cInstPtr;
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
int32_t C2c_Init(C2C_DESC** instPtr, C2C_CONFIG* configPtr);
|
||||
int32_t C2c_IrqEnable(C2C_DESC* instPtr);
|
||||
int32_t C2c_SendData(C2C_DESC* instPtr, uint8_t* buff, uint32_t dLen);
|
||||
int32_t C2c_RecvData(C2C_DESC* instPtr, uint8_t* buff, uint32_t buffSize);
|
||||
int32_t C2c_BlockingSendData(C2C_DESC* instPtr, uint8_t* buff, uint32_t dLen);
|
||||
bool C2c_IsSendBusy(C2C_DESC* instPtr);
|
||||
bool C2c_IsRecvBusy(C2C_DESC* instPtr);
|
||||
int32_t C2c_SendIrqHandler(C2C_DESC* instPtr);
|
||||
int32_t C2c_RecvIrqHandler(C2C_DESC* instPtr);
|
||||
Reference in New Issue
Block a user