📄 6-7.c
字号:
#include "prolog.h"
#include <stdio.h>
#include <errno.h>
#include <time.h>
#include <asm/io.h>
/*** For mmap function ***/
#include <unistd.h>
#include <sys/mman.h>
/*** For open function ***/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
/*** For system function errors "errno", for example ***/
#include <stdlib.h>
#define BASE_ATC40_ADDR 0xd0000L /* size_t baze for mmap function and also
Default Address Shunt Position, see "ATC40 User Manual", page 10 */
#define SIZE_ATC40_MEM 0x300L /* size_t length for mmap function */
#define PAGE_SIZE 0x1000
/* simple for(;;) loop without hardware read (2000 countes): 600us and 100 us */
#define N_POLLS 500 /* 640us for 130MHz pentium, 950us for 33Mhz 486 */
#include "rpcdefs.h"
#include "sedac.h"
#include "errors.h"
#include "unixcmd.h"
int nSedacLines = 4;
int SedacSimulate = 0;
u16 *ATC40Address = NULL;
u16 sedacSimulationBuffer[4];
u16 sedacSimulationCount[4] = {0,0,0,0};
SEDAC_LINE volatile *line[4];
/***************************************/
void initSedac(void)
{
int i, mem_fd;
caddr_t atc40_mem; /* Pointer to "reflected" ATC40 memory */
if (SedacSimulate) return;
for (i=0; i<nSedacLines; i++) // look for up to # SEDAC lines
{
if( ATC40Address == NULL ) { /*** Open /dev/mem ***/
if(( mem_fd = open("/dev/mem", O_RDWR) ) < 0 ) {
printf(" ATC40 memory-window can't open /dev/mem \n");
exit(-1);
}
/*** mmap ATC40 memory ***/
if((atc40_mem = malloc( SIZE_ATC40_MEM + (PAGE_SIZE-1) )) == NULL) {
printf(" ATC40 memory allocation error \n");
exit(-1);
}
// printf("malloc -> atc40_mem = %p, %x\n", atc40_mem, atc40_mem );
if(( unsigned long)atc40_mem % PAGE_SIZE )
atc40_mem += PAGE_SIZE - ((unsigned long)atc40_mem % PAGE_SIZE );
// printf("corrected atc40_mem = %p, %x\n", atc40_mem, atc40_mem );
atc40_mem = (caddr_t)mmap( /* void *mmap */
(void *)atc40_mem, /* void *start */
(size_t)SIZE_ATC40_MEM, /* size_t length */
PROT_READ|PROT_WRITE, /* int prot */
MAP_SHARED|MAP_FIXED, /* int flags */
(int)mem_fd, /* int fd */
(off_t)BASE_ATC40_ADDR ); /* size_t baze */
if( (long)atc40_mem < 0 ) {
printf(" ATC40 memory map error: atc40_mem = %x\n", atc40_mem);
printf("\n\n\tERROR - mmap failed, errno: %d: %s\n", errno, strerror(errno));
exit(-1);
}
/* mlock( BASE_ATC40_ADDR, SIZE_ATC40_MEM ); */
// printf("init sedac called: mmap atc40_mem = %p, %x\n", atc40_mem, atc40_mem );
ATC40Address = (u16 *)atc40_mem;
// ATC40Address = (u16 *)BASE_ATC40_ADDR;
}
line[i] = (SEDAC_LINE *) (ATC40Address + (i/2)*0x100 + (i%2)*0x04);
printf("Initializing SEDAC line %d at base address %x, %x, %x\n>",i+1, &line[i]->csr, &line[i]->igr, &line[i]->dat);
line[i]->csr = 0; // init sedac ip moudule
line[i]->igr = 0;
}
RegisterUserCommand("nlines",NULL,&nSedacLines,NULL,CA_READ);
RegisterUserCommand("sedac",cmdReadSedac,NULL,NULL,CA_READ);
RegisterUserCommand("sedac",cmdWriteSedac,NULL,NULL,CA_WRITE);
RegisterUserCommand("crates",cmdCrates,NULL,NULL,CA_READ);
RegisterUserCommand("addr",cmdAddr,NULL,NULL,CA_READ);
return;
}
// ============ poll sedac active bit ===================================
int sedacReady(u16 ln, u16 *data)
{ int i;
u16 ret;
for (i=0; i<N_POLLS ; i++ ) {
ret = line[ln]->csr;
if ( (ret & _RBE) == 0 ) break;
}
if ( data && i < N_POLLS ) *data = line[ln]->dat;
return (i < N_POLLS ? (ret & ERRALL) : -2) ;
}
// ============ write routine ===================================
int wsedac(u16 ln, u16 crate, u16 subadd, u16 data)
{ int i, ret;
if (ln<1 || ln>nSedacLines) return -1;
ln--;
if (SedacSimulate)
{
sedacSimulationBuffer[ln] = data;
return 0;
}
line[ln]->dat = data;
line[ln]->cmd = 0x4000 | (crate << 8) | subadd;
return sedacReady(ln, 0);
}
// ================ read routine ===================================
int rsedac(u16 ln, u16 crate, u16 subadd, u16 *data)
{ int i, ret;
if (ln<1 || ln>nSedacLines) return -1;
ln--;
if (SedacSimulate) {
*data = sedacSimulationBuffer[ln] + sedacSimulationCount[ln]++;
return 0;
}
line[ln]->cmd = 0x8000 | (crate << 8) | subadd;
return sedacReady(ln, data);
}
// ================ read Async routine ===================================
int rsedacAsync(u16 ln, u16 crate, u16 subadd)
{
if (ln<1 || ln>nSedacLines) return -1;
ln--;
if ( SedacSimulate == 0 ) line[ln]->cmd = 0x8000 | (crate << 8) | subadd;
return 0;
}
// ================ read Async Poll routine ===================================
int rsedacPoll(u16 ln, u16 *data)
{ int i, ret;
if (ln<1 || ln>nSedacLines) return -1;
ln--;
if (SedacSimulate) {
*data = sedacSimulationBuffer[ln] + sedacSimulationCount[ln]++;
return 0;
}
return sedacReady(ln, data);
}
// ============ Block routines ==========================================
void sedac4(SedacInfo *sedacList, int RWF, int num, int (*fcn)(int))
{ int i, l;
switch( RWF )
{
case READ:
for (i=0; i<num; i++) {
for (l=0; !SedacSimulate && l<nSedacLines; l++) line[l]->cmd = 0x8000 | sedacList[l].csa[i];
if (fcn) fcn(i); // service function
for (l=0; l<nSedacLines; l++) // SEDAC line in
if (SedacSimulate) {
sedacList[l].data[i] = sedacSimulationBuffer[l] + sedacSimulationCount[l]++;
sedacList[l].error[i] = 0;
} else {
sedacList[l].error[i] = sedacReady(l, &sedacList[l].data[i]);
}
}
if (fcn) fcn(i);
return;
case WRITE:
for (i=0; i<num; i++) {
for (l=0; !SedacSimulate && l<nSedacLines; l++) {
line[l]->dat = sedacList[l].data[i];
line[l]->cmd = 0x4000 | sedacList[l].csa[i];
}
if (fcn) fcn(i);
for (l=0; l<nSedacLines; l++) { // SEDAC lines in
if (SedacSimulate) {
sedacSimulationBuffer[l] = sedacList[l].data[i];
sedacList[l].error[i] = 0;
} else { /* poll RBE bit */
sedacList[l].error[i] = sedacReady(l, 0);
}
}
}
if (fcn) fcn(i); // i = num
}
return;
}
// ================ read/write nwords telegram ===================================
int sedac(int ln, u16 csa, int RWF, u16 *data, int nwords)
{ int i, err;
u16 addr;
if (ln<1 || ln>nSedacLines) return -1;
ln--;
switch( RWF )
{
case READ:
addr = 0x8000 | csa;
for (err=0, i=0; i<nwords; i++, data++) {
if (SedacSimulate) {
*data = sedacSimulationBuffer[ln] + sedacSimulationCount[ln]++;
} else {
line[ln]->cmd = addr;
if ( sedacReady(ln, data) ) err++;
}
}
return err;
case WRITE:
addr = 0x4000 | csa;
for (err=0,i=0; i<nwords; i++, data++ ) {
if (SedacSimulate) {
sedacSimulationBuffer[ln] = *data;
} else {
line[ln]->dat = *data;
line[ln]->cmd = addr;
if ( sedacReady(ln, 0) ) err++;
}
}
return err;
default:
return -1;
}
}
// ================ find crates ===================================
int F_crates(int *ncrates, int rwflag, u16 ln)
{ u16 data;
int i,n;
if (ln < 1 || ln > nSedacLines) return no_such_line;
switch (rwflag)
{
case READ:
printf("line %d has crates :\n>",ln);
for (i=0,n=0; i<32; i++) if (!rsedac(ln, i, 252, &data))
{
printf(" %2d",i);
if ((++n%10) == 0) printf("\n>");
}
printf("\n>");
*ncrates = n;
return 0;
default:
return illegal_read_write;
}
}
// ================ find sub addres (16*n) ===================================
int F_addr(int *naddr, int rwflag, u16 ln, u16 crate)
{ u16 data;
int i,n;
if (ln < 1 || ln > nSedacLines) return no_such_line;
switch (rwflag)
{
case READ:
printf("line %d crate %d has subaddresses :\n>",ln,crate);
for (i=0,n=0; i<252; i+=16) if (!rsedac(ln,crate,i,&data))
{
printf(" %2d",i);
if ((++n%10) == 0) printf("\n>");
}
printf("\n>");
*naddr = n;
return 0;
default:
return illegal_read_write;
}
}
int cmdReadSedac(int ln,int cr,int sa,int val)
{
UINT16 data;
int cc;
char str[128];
if (nSedacLines)
{
if ((cc=rsedac(ln,cr,sa,&data)) != 0) sprintf(str,"SEDAC error");
else sprintf(str,"lin %d cra %d bsa %d : %d (0x%x)\n>",ln,cr,sa,data,data);
ttyoutput(str);
return cc;
}
return -1;
}
int cmdWriteSedac(int ln,int cr,int sa,int val)
{
UINT16 data = val;
int cc=0;
char str[128];
if (nSedacLines)
{
if ((cc=wsedac(ln,cr,sa,data)) != 0) sprintf(str,"SEDAC error");
else sprintf(str,"lin %d cra %d bsa %d wrote : %d (0x%x)\n>",ln,cr,sa,data,data);
ttyoutput(str);
return cc;
}
return -1;
}
int cmdCrates(int ln,int cr,int sa,int access)
{
UINT16 data;
int cc,n=0;
char str[128];
if (nSedacLines)
{
if ((cc=F_crates(&n,1,ln)) != 0) sprintf(str,"line %d : %s",ln,erlst[cc]);
else sprintf(str,"line %d : %d crates\n>",ln,n);
ttyoutput(str);
return n;
}
}
int cmdAddr(int ln,int cr,int sa,int access)
{
UINT16 data;
int cc,n=0;
char str[128];
if (nSedacLines)
{
if ((cc=F_addr(&n,1,ln,cr)) != 0) sprintf(str,"lin %d cra %d : %s",ln,cr,erlst[cc]);
else sprintf(str,"lin %d cra %d : %d sub-addresses\n>",ln,cr,n);
ttyoutput(str);
return n;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -