前言
??第一种情况的改进和第三种情况,都可以在应用层来做 ??比如我们可以设置快速读写模式fastmode,在应用层调用这个函数open时,配置寄存器屏蔽掉其他子地址的中断,直接源头上减少信号量,提升操作系统处理效率,退出时在close,恢复正常的配置,以免影响其他业务流程使用 ??而高频率数据偶尔出现的读写错误,处理PL测对读写时序的修改,也可以通过多读几次数据判断筛选,大大降低错误概率,(目前没有发现过规避后的出错,但是源头上还是需要在FPGA部分更改读写时序) ??另外还有个驱动开发时需要注意的是:在接收到命令字之后,由于1553B特殊的机制,我们可以判断收发标志位,有区别的是,收到接收命令后再去做根据数据指针(芯片内部指针,不是编程创建的)做接收处理是完全没有问题的,但是如果收到的是发送命令,BC会在第一时间将对应子地址下的数据拿走,想根据收发标志去做发送处理的判断是完全来不及的,需要我们清楚的熟悉业务流程,在需要的时候提前填好数据,以便收到发送消息时可以让BC设备拿走正确的数据
1553test.c
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <pthread.h>
#include "rt.h"
static int fd;
unsigned int commandWord[8]={0};
void Xil_Out32(unsigned int * Addr, unsigned int Value)
{
volatile unsigned int *LocalAddr = (volatile unsigned int *)Addr;
*LocalAddr = Value;
}
void Delay()
{
unsigned int n=1000;
while(n--);
}
unsigned int MEM_Read(unsigned int BaseAddress,unsigned int RegOffset)
{
unsigned int temp[3]= {0};
temp[0] = Xil_In32((BaseAddress) + (RegOffset));
Delay();
temp[1] = Xil_In32((BaseAddress) + (RegOffset));
Delay();
temp[2] = Xil_In32((BaseAddress) + (RegOffset));
if(temp[0] == temp[1])
{
return temp[0];
}
else if(temp[0] == temp[2] )
{
return temp[0];
}
else if(temp[1] == temp[2])
{
return temp[1];
}
else
{
return 0xFFFF;
}
}
unsigned int * Xil_In32(unsigned int * Addr)
{
return *(volatile unsigned int *) Addr;
}
int rt1553open()
{
int mem_fd = open("/dev/mem", O_RDWR | O_SYNC);
if (mem_fd < 0) {
printf("can not open /dev/mem \n");
return (-1);
}
printf("/dev/mem is open \n");
rt1553B_map_base0 = mmap(NULL, 4096 * 4, PROT_READ | PROT_WRITE, MAP_SHARED, mem_fd, XPAR_BRAM_0_BASEADDR);
rt1553B_map_base1 = mmap(NULL, 4096 * 4, PROT_READ | PROT_WRITE, MAP_SHARED, mem_fd, MEM_BASEADDR);
if (rt1553B_map_base0 == 0 || rt1553B_map_base1 == 0) {
printf("NULL pointer\n");
}
else {
printf("mmap successful\n");
}
close(mem_fd);
return 0;
}
void fastenable(void)
{
Xil_Out32(rt1553B_map_base0 + 68, 0);
RT_WriteReg(rt1553B_map_base1, 0x00, 0x0010);
Xil_Out32(rt1553B_map_base1 + 68, 1);
MEM_Write(rt1553B_map_base1, (0x01A3) * 4, 0x4200);
MEM_Write(rt1553B_map_base1, (0x01A4) * 4, 0x4200);
MEM_Write(rt1553B_map_base1, (0x01A5) * 4, 0x4200);
MEM_Write(rt1553B_map_base1, (0x01A6) * 4, 0x0000);
MEM_Write(rt1553B_map_base1, (0x01A7) * 4, 0x0000);
MEM_Write(rt1553B_map_base1, (0x01A8) * 4, 0x0000);
MEM_Write(rt1553B_map_base1, (0x01A9) * 4, 0x0000);
MEM_Write(rt1553B_map_base1, (0x01AA) * 4, 0x0000);
MEM_Write(rt1553B_map_base1, (0x01AB) * 4, 0x0000);
MEM_Write(rt1553B_map_base1, (0x01AC) * 4, 0x0000);
}
void fastdisable(void)
{
Xil_Out32(rt1553B_map_base0 + 68, 0);
RT_WriteReg(rt1553B_map_base1, 0x00, 0x0037);
Xil_Out32(rt1553B_map_base0 + 68, 1);
MEM_Write(rt1553B_map_base1, (0x01A3) * 4, 0x0000);
MEM_Write(rt1553B_map_base1, (0x01A4) * 4, 0x0000);
MEM_Write(rt1553B_map_base1, (0x01A5) * 4, 0x0000);
MEM_Write(rt1553B_map_base1, (0x01A6) * 4, 0x0000);
MEM_Write(rt1553B_map_base1, (0x01A7) * 4, 0x0000);
MEM_Write(rt1553B_map_base1, (0x01A8) * 4, 0x0000);
MEM_Write(rt1553B_map_base1, (0x01A9) * 4, 0x0000);
MEM_Write(rt1553B_map_base1, (0x01AA) * 4, 0x0000);
MEM_Write(rt1553B_map_base1, (0x01AB) * 4, 0x0000);
MEM_Write(rt1553B_map_base1, (0x01AC) * 4, 0x0000);
}
unsigned int rt1553B_rcv()
{
unsigned int tempVar = 0;
unsigned int read_tmp=0;
memset(rt1553B_BUMSG.data, 0, sizeof(rt1553B_BUMSG.data));
if (!rt1553B_BUMSG.dataCntModeCode)
{
tempVar = 0x20;
printf("**********32*************\n");
}
else
{
tempVar = rt1553B_BUMSG.dataCntModeCode;
printf("**********tempVar is %d*************\n",tempVar);
}
Xil_Out32(rt1553B_map_base0 + 68, 1);
for (int i = 0; i < tempVar; i++)
{
rt1553B_BUMSG.data[i]= MEM_Read(rt1553B_map_base1, (rt1553B_BUMSG.dataBlockPointer + i) * 4);
}
for (int i = 0; i < 32; i++)
{
printf(" rcv 32word data %d is 0x%x\r\n",i, rt1553B_BUMSG.data[i]);
}
memset(rt1553B_BUMSG.data, 0, sizeof(rt1553B_BUMSG.data));
return tempVar;
}
unsigned int rt1553B_send(unsigned char *buf,int send_len,unsigned char subaddr)
{
unsigned int send_tmp=0;
Xil_Out32(rt1553B_map_base0 + 68, 1);
usleep(10);
printf("subaddr is %d",subaddr);
switch (subaddr)
{
case BusCheckRespAddr:
for (int i = 0; i < send_len; i++)
{
send_tmp=((unsigned int)buf[i*2])| (((unsigned int)buf[i*2+1])<<8);
MEM_Write(rt1553B_map_base1, (0x400 + i) * 4, send_tmp);
}
break;
case SelfCheckAndUpdateCtrlRespAddr:
for (int i = 0; i < send_len; i++)
{
send_tmp=((unsigned int)buf[i*2])| (((unsigned int)buf[i*2+1])<<8);
MEM_Write(rt1553B_map_base1, (0x440 + i) * 4, send_tmp);
}
break;
case StatusCheckAndUpdateDataGroupRespAddr:
for (int i = 0; i < send_len; i++)
{
send_tmp=((unsigned int)buf[i*2])| (((unsigned int)buf[i*2+1])<<8);
MEM_Write(rt1553B_map_base1, (0x480 + i) * 4, send_tmp);
}
break;
case UpdateBlock1Addr:
for (int i = 0; i < send_len; i++)
{
send_tmp=((unsigned int)buf[i*2])| (((unsigned int)buf[i*2+1])<<8);
MEM_Write(rt1553B_map_base1, (0x4C0 + i) * 4, send_tmp);
}
break;
case UpdateBlock2Addr:
for (int i = 0; i < send_len; i++)
{
send_tmp=((unsigned int)buf[i*2])| (((unsigned int)buf[i*2+1])<<8);
MEM_Write(rt1553B_map_base1, (0x500 + i) * 4, send_tmp);
}
break;
case EndecryptRespAndUpdateBlock3Addr :
for (int i = 0; i < send_len; i++)
{
send_tmp=((unsigned int)buf[i*2])| (((unsigned int)buf[i*2+1])<<8);
MEM_Write(rt1553B_map_base1, (0x540 + i) * 4, send_tmp);
}
break;
case UpdateBlock4Addr:
for (int i = 0; i < send_len; i++)
{
send_tmp=((unsigned int)buf[i*2])| (((unsigned int)buf[i*2+1])<<8);
MEM_Write(rt1553B_map_base1, (0x580 + i) * 4, send_tmp);
}
break;
case DdChannelSetRespAndUpdateBlock5Addr:
for (int i = 0; i < send_len; i++)
{
send_tmp=((unsigned int)buf[i*2])| (((unsigned int)buf[i*2+1])<<8);
MEM_Write(rt1553B_map_base1, (0x5C0 + i) * 4, send_tmp);
}
break;
case UpdateBlock6Addr:
for (int i = 0; i < send_len; i++)
{
send_tmp=((unsigned int)buf[i*2])| (((unsigned int)buf[i*2+1])<<8);
MEM_Write(rt1553B_map_base1, (0x600 + i) * 4, send_tmp);
}
break;
case UpdateBlock7Addr:
for (int i = 0; i < send_len; i++)
{
send_tmp=((unsigned int)buf[i*2])| (((unsigned int)buf[i*2+1])<<8);
MEM_Write(rt1553B_map_base1, (0x640 + i) * 4, send_tmp);
}
break;
case UpdateBlock8Addr:
for (int i = 0; i < send_len; i++)
{
send_tmp=((unsigned int)buf[i*2])| (((unsigned int)buf[i*2+1])<<8);
MEM_Write(rt1553B_map_base1, (0x680 + i) * 4, send_tmp);
}
break;
case TransBookRespAddr:
for (int i = 0; i < send_len; i++)
{
send_tmp=((unsigned int)buf[i*2])| (((unsigned int)buf[i*2+1])<<8);
MEM_Write(rt1553B_map_base1, (0x700 + i) * 4, send_tmp);
}
break;
case DjChannelSetRespSysSetAddr:
for (int i = 0; i < send_len; i++)
{
send_tmp=((unsigned int)buf[i*2])| (((unsigned int)buf[i*2+1])<<8);
MEM_Write(rt1553B_map_base1, (0x780 + i) * 4, send_tmp);
}
break;
case DxChannelSetRespAddr:
for (int i = 0; i < send_len; i++)
{
send_tmp=((unsigned int)buf[i*2])| (((unsigned int)buf[i*2+1])<<8);
MEM_Write(rt1553B_map_base1, (0x840 + i) * 4, send_tmp);
}
break;
case ForwardDataG2Addr:
for (int i = 0; i < send_len; i++)
{
send_tmp=((unsigned int)buf[i*2])| (((unsigned int)buf[i*2+1])<<8);
MEM_Write(rt1553B_map_base1, (0x880 + i) * 4, send_tmp);
}
break;
case DjChannelSetRespSelfCheckAddr:
for (int i = 0; i < send_len; i++)
{
send_tmp=((unsigned int)buf[i*2])| (((unsigned int)buf[i*2+1])<<8);
MEM_Write(rt1553B_map_base1, (0x8C0 + i) * 4, send_tmp);
}
break;
default:
break;
}
return 0;
}
static void RT_signal_func(int signum)
{
int rcv_len;
int status;
printf("*********demo command is 0x%x*******************\n",rt1553B_BUMSG.commandWord);
rt1553B_BUMSG.remoteTerminalAddr = (rt1553B_BUMSG.commandWord >> 11) & 0x1f;
rt1553B_BUMSG.tr = (rt1553B_BUMSG.commandWord >> 10) & 0x01;
rt1553B_BUMSG.subAddModeCode = (rt1553B_BUMSG.commandWord >> 5) & 0x1f;
rt1553B_BUMSG.dataCntModeCode = (rt1553B_BUMSG.commandWord) & 0x1f;
switch (rt1553B_BUMSG.tr)
{
case BURX:
rcv_len = rt1553B_rcv();
printf("rcv length is 0x%x\r\n", rcv_len);
break;
case BUTX:
printf("************INPUT send**********************\n");
break;
default:
break;
}
}
int main(void)
{
int flags = 0;
int err;
rt1553open();
fd = open("/dev/1553drv", O_RDWR);
if(fd < 0) {
printf("*********open fail************\n");
return -1;
}
signal(SIGIO, RT_signal_func);
fcntl(fd, F_SETOWN, getpid());
flags = fcntl(fd, F_GETFD);
fcntl(fd, F_SETFL, flags | FASYNC);
while(1)
{
sleep(1);
}
return 0;
}
rt.h
#ifndef __RT_H_
#define __RT_H_
#include <stdio.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define BUINTMASK 0x0
#define BUCFG1 0x1
#define BUCFG2 0x2
#define BURST 0x3
#define BUCMDSTACKPOINT 0x3
#define BURTSUBADDRCTRL 0x4
#define BUTIMETAG 0x5
#define BUINTSTATUS 0x6
#define BUCFG3 0x7
#define BUCFG4 0x8
#define BUCFG5 0x9
#define BURTDATASTACKADDR 0xa
#define BUBCFRAMETIME 0xb
#define BUBCTIMEREMAIN 0xc
#define BURTLASTCMD 0xd
#define BURTSTATUSWORD 0xe
#define BURTBITWORD 0xf
#define BUTSTMODE0 0x10
#define BUTSTMODE1 0x11
#define BUTSTMODE2 0x12
#define BUTSTMODE3 0x13
#define BUTSTMODE4 0x14
#define BUTSTMODE5 0x15
#define BUTSTMODE6 0x16
#define BUTSTMODE7 0x17
#define BUMSGDATANUM 0x20
#define BUCHANNELA 0x0
#define BUCHANNELB 0x1
#define BURX 0x0
#define BUTX 0x1
#define ERR1 0x0
#define ERR3 0x1
#define ERR 0x2
#define OK 0x0
#define INTMASK 0x0
#define BUM400 0x400
#define BUM800 0x800
#define BUZERO 0x0
#define BUMSGDATANUM 0x20
#define BUSUBADDR0 0x0
#define BUSUBADDR31 0x20
#define BUMSGBUFSIZE 0x40
#define BUEOMINT 0x1
#define BUMSGBUFBGN 0x0
#define BusCheckRespAddr 1
#define SelfCheckAndUpdateCtrlRespAddr 3
#define StatusCheckAndUpdateDataGroupRespAddr 4
#define UpdateBlock1Addr 5
#define UpdateBlock2Addr 6
#define EndecryptRespAndUpdateBlock3Addr 7
#define UpdateBlock4Addr 8
#define DdChannelSetRespAndUpdateBlock5Addr 9
#define UpdateBlock6Addr 10
#define UpdateBlock7Addr 11
#define UpdateBlock8Addr 12
#define TransBookRespAddr 15
#define DjChannelSetRespSysSetAddr 17
#define DxChannelSetRespAddr 21
#define ForwardDataG2Addr 24
#define DjChannelSetRespSelfCheckAddr 26
#define XPAR_BRAM_0_BASEADDR 0x40000000
#define MEM_BASEADDR 0x43c00000
unsigned char *rt1553B_map_base0;
unsigned char *rt1553B_map_base1;
typedef struct
{
unsigned int channelAB;
unsigned int blockStatusWord;
unsigned int timeTagWord;
unsigned int dataBlockPointer;
unsigned int commandWord;
unsigned int remoteTerminalAddr;
unsigned int tr;
unsigned int subAddModeCode;
unsigned int dataCntModeCode;
unsigned int data[BUMSGDATANUM];
}BUMSGIFM;
BUMSGIFM rt1553B_BUMSG;
typedef struct
{
BUMSGIFM buRxRPool[BUMSGBUFSIZE];
unsigned int buRxRPoint;
BUMSGIFM buRxTPool[BUMSGBUFSIZE];
unsigned int buRxTPoint;
} BUBUFFER;
void Xil_Out32(unsigned int * Addr, unsigned int Value);
unsigned int * Xil_In32(unsigned int * Addr);
#define RT_WriteReg(BaseAddress, RegOffset, Data) \
Xil_Out32((BaseAddress) + (RegOffset), (Data))
#define RT_ReadReg(BaseAddress, RegOffset) \
Xil_In32((BaseAddress) + (RegOffset))
#define MEM_Write(BaseAddress, RegOffset, Data) \
Xil_Out32((BaseAddress) + (RegOffset), (Data))
extern unsigned int MEM_Read(BaseAddress, RegOffset);
int rt1553open();
int rt1553init();
int showreg();
unsigned int rt1553B_handle();
unsigned int rt1553B_rcv();
unsigned int rt1553B_send(unsigned char *buf,int send_len,unsigned char subaddr);
#endif
|