- Many fixes to tas code
- fixes to amor writing and status code - edited ecbcounter to stop at no beam - updated documentation - fixed a bug in project code affecting SANS
This commit is contained in:
152
ecbcounter.c
152
ecbcounter.c
@@ -13,6 +13,7 @@
|
||||
#include <unistd.h>
|
||||
#include "fortify.h"
|
||||
#include "sics.h"
|
||||
#include "status.h"
|
||||
#include "ecb.h"
|
||||
#include "countdriv.h"
|
||||
|
||||
@@ -22,6 +23,7 @@ typedef struct {
|
||||
unsigned char prescaler[8]; /* an array for the prescaler values */
|
||||
int tfreq; /* timer frequency */
|
||||
unsigned char control; /* marks the control monitor */
|
||||
int state; /* current counting state */
|
||||
}ECBCounter, *pECBCounter;
|
||||
|
||||
/*----------------- private defines ------------------------------------*/
|
||||
@@ -33,7 +35,13 @@ typedef struct {
|
||||
#define STLOAD 156
|
||||
#define STCPRE 133
|
||||
#define STARTS 135
|
||||
#define SPCSTA 169
|
||||
|
||||
/*------------------ state codes --------------------------------------*/
|
||||
#define IDLE 0
|
||||
#define COUNT 2
|
||||
#define NOBEAM 3
|
||||
/*--------------------------------------------------------------------*/
|
||||
#define MAX_COUNT 4294967295.0
|
||||
/*------------------ error codes --------------------------------------*/
|
||||
#define COMMERROR -300
|
||||
@@ -66,12 +74,79 @@ static int readScaler(pECBCounter pPriv, int scaler, int *count){
|
||||
|
||||
return 1;
|
||||
}
|
||||
/*---------------------------------------------------------------------*/
|
||||
static int check4Beam(struct __COUNTER *pCter, int *beam){
|
||||
Z80_reg in, out;
|
||||
pECBCounter self = NULL;
|
||||
int status;
|
||||
|
||||
self = (pECBCounter)pCter->pData;
|
||||
assert(self);
|
||||
|
||||
in.c = 1;
|
||||
status = ecbExecute(self->ecb,SPCSTA,in,&out);
|
||||
if(status != 1){
|
||||
pCter->iErrorCode = COMMERROR;
|
||||
return HWFault;
|
||||
}
|
||||
*beam = (int)out.d;
|
||||
return 1;
|
||||
}
|
||||
/*----------------------------------------------------------------------*/
|
||||
static int stopScalers(pECBCounter self){
|
||||
int status;
|
||||
Z80_reg in, out;
|
||||
|
||||
status = ecbExecute(self->ecb,STOPS,in,&out);
|
||||
if(status != 1){
|
||||
return COMMERROR;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/*========================================================================
|
||||
These two functions currently rely on the idea that the ECB stops
|
||||
and starts without clearing counters in between. The sequence of
|
||||
things necessary to start it, suggests this. If this is not the case then
|
||||
this will not work.
|
||||
===========================================================================*/
|
||||
static int ECBPause(struct __COUNTER *self){
|
||||
int status;
|
||||
pECBCounter pPriv = NULL;
|
||||
|
||||
assert(self);
|
||||
pPriv = (pECBCounter)self->pData;
|
||||
assert(pPriv);
|
||||
|
||||
if((status = stopScalers(pPriv)) <= 0){
|
||||
self->iErrorCode = status;
|
||||
return HWFault;
|
||||
}
|
||||
return OKOK;
|
||||
}
|
||||
/*=======================================================================*/
|
||||
static int ECBContinue(struct __COUNTER *self){
|
||||
int status;
|
||||
pECBCounter pPriv = NULL;
|
||||
Z80_reg in, out;
|
||||
|
||||
assert(self);
|
||||
pPriv = (pECBCounter)self->pData;
|
||||
assert(pPriv);
|
||||
|
||||
status = ecbExecute(pPriv->ecb,STARTS,in,&out);
|
||||
if(status != 1){
|
||||
self->iErrorCode = status;
|
||||
return HWFault;
|
||||
}
|
||||
|
||||
return OKOK;
|
||||
}
|
||||
/*-----------------------------------------------------------------------*/
|
||||
static int ECBGetStatus(struct __COUNTER *self, float *fControl){
|
||||
pECBCounter pPriv = (pECBCounter)self->pData;
|
||||
int status, result, scaler;
|
||||
Z80_reg in, out;
|
||||
int count;
|
||||
int count, beam;
|
||||
|
||||
assert(pPriv);
|
||||
|
||||
@@ -81,14 +156,36 @@ static int ECBGetStatus(struct __COUNTER *self, float *fControl){
|
||||
status = ecbExecute(pPriv->ecb,STFRD,in,&out);
|
||||
if(status != 1){
|
||||
self->iErrorCode = COMMERROR;
|
||||
pPriv->state = IDLE;
|
||||
return HWFault;
|
||||
}
|
||||
if(out.d == 0){
|
||||
result = HWIdle;
|
||||
pPriv->state = IDLE;
|
||||
} else {
|
||||
result = HWBusy;
|
||||
}
|
||||
|
||||
/*
|
||||
check beam status
|
||||
*/
|
||||
status = check4Beam(self,&beam);
|
||||
if(status != 1){
|
||||
self->iErrorCode = COMMERROR;
|
||||
return HWFault;
|
||||
}
|
||||
beam &= 1;
|
||||
if(result == HWBusy && pPriv->state == COUNT && beam == 0){
|
||||
ECBPause(self);
|
||||
pPriv->state = NOBEAM;
|
||||
SetStatus(eOutOfBeam);
|
||||
}
|
||||
if(result == HWBusy && pPriv->state == NOBEAM && beam == 1){
|
||||
ECBContinue(self);
|
||||
pPriv->state = COUNT;
|
||||
SetStatus(eCounting);
|
||||
}
|
||||
|
||||
/*
|
||||
select which scaler to read
|
||||
*/
|
||||
@@ -106,18 +203,7 @@ static int ECBGetStatus(struct __COUNTER *self, float *fControl){
|
||||
|
||||
return result;
|
||||
}
|
||||
/*======================================================================*/
|
||||
static int stopScalers(pECBCounter self){
|
||||
int status;
|
||||
Z80_reg in, out;
|
||||
|
||||
status = ecbExecute(self->ecb,STOPS,in,&out);
|
||||
if(status != 1){
|
||||
return COMMERROR;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/*----------------------------------------------------------------------*/
|
||||
/*=====================================================================*/
|
||||
static int clearScalers(pECBCounter self){
|
||||
int status;
|
||||
Z80_reg in, out;
|
||||
@@ -225,44 +311,7 @@ static int ECBStart(struct __COUNTER *self){
|
||||
return HWFault;
|
||||
}
|
||||
|
||||
return OKOK;
|
||||
}
|
||||
/*========================================================================
|
||||
These two functions currently rely on the idea that the ECB stops
|
||||
and starts without clearing counters in between. The sequence of
|
||||
things necessary to start it, suggests this. If this is not the case then
|
||||
this will not work.
|
||||
===========================================================================*/
|
||||
static int ECBPause(struct __COUNTER *self){
|
||||
int status;
|
||||
pECBCounter pPriv = NULL;
|
||||
|
||||
assert(self);
|
||||
pPriv = (pECBCounter)self->pData;
|
||||
assert(pPriv);
|
||||
|
||||
if((status = stopScalers(pPriv)) <= 0){
|
||||
self->iErrorCode = status;
|
||||
return HWFault;
|
||||
}
|
||||
return OKOK;
|
||||
}
|
||||
/*=======================================================================*/
|
||||
static int ECBContinue(struct __COUNTER *self){
|
||||
int status;
|
||||
pECBCounter pPriv = NULL;
|
||||
Z80_reg in, out;
|
||||
|
||||
assert(self);
|
||||
pPriv = (pECBCounter)self->pData;
|
||||
assert(pPriv);
|
||||
|
||||
status = ecbExecute(pPriv->ecb,STARTS,in,&out);
|
||||
if(status != 1){
|
||||
self->iErrorCode = status;
|
||||
return HWFault;
|
||||
}
|
||||
|
||||
pPriv->state = COUNT;
|
||||
return OKOK;
|
||||
}
|
||||
/*=======================================================================*/
|
||||
@@ -274,6 +323,7 @@ static int ECBHalt(struct __COUNTER *self){
|
||||
pPriv = (pECBCounter)self->pData;
|
||||
assert(pPriv);
|
||||
|
||||
pPriv->state = IDLE;
|
||||
if((status = stopScalers(pPriv)) <= 0){
|
||||
self->iErrorCode = status;
|
||||
return HWFault;
|
||||
|
||||
Reference in New Issue
Block a user