versadac  1
versadac - Scalable Recorder Firmware
fi_ssm.h
1 /*******************************************************************************
2 FILE : fi_ssm.h
3 VERSION : $Id: fi_ssm.h 5611 2006-11-08 17:33:52Z davec $
4 AUTHOR : David Cozens
5 SYSTEM : Diab C for PowerPC under vxWorks
6 DESCRIPTION : Scheduled message class for driving the FI2
7 *******************************************************************************/
8 #ifndef __FI_SSM_H
9 #define __FI_SSM_H
10 #include "spismsg.h"
11 
12 enum
13 {
14  FI2_SSM_TIME_STATUS_RANGING,
15  FI2_SSM_TIME_STATUS_FREQUENCY_TOO_HIGH,
16  FI2_SSM_TIME_STATUS_FREQUENCY_TOO_LOW,
17  FI2_SSM_TIME_STATUS_PSU_FAIL,
18  FI2_SSM_TIME_STATUS_OK = 255
19 };
20 #define FI2_SSM_STATUS_MASK 0x3F
21 #define FI2_SSM_STATUS_SENSOR_BREAK_MASK 0x40
22 #define FI2_SSM_STATUS_SHORT_CIRCUIT_MASK 0x80
23 
24 #define FI2_RX_TIME_MSB_MASK 0x1F
25 #define FI2_RX_COUNT_MSB_MASK 0x3F
26 #define FI2_SSM_TIME_MASK ((((unsigned int)FI2_RX_TIME_MSB_MASK)<<24)|0xFFFFFF)
27 
28 #define EIO_FI2_LED_3_MASK 0x01
29 #define EIO_FI2_LED_CHANNEL_1_FAULT_MASK 0x02
30 #define EIO_FI2_LED_4_MASK 0x04
31 #define EIO_FI2_LED_CHANNEL_2_FAULT_MASK 0x08
32 #define EIO_FI2_LED_2_MASK 0x10
33 #define EIO_FI2_LED_1_MASK 0x20
34 
35 #ifdef FI_MODULE_FIRMWARE_DEBUG
36  extern int g_fred;
37 #endif
38 
39 class FrequencyInputSpiScheduledMessage:public SpiScheduledMessage
40 {
41  public:
42  FrequencyInputSpiScheduledMessage(unsigned char device);
44  virtual void sent();
45 
46  /*------------------------------------------------------------------------------
47  FUNCTION : wasCommandOk
48  DESCRIPTION : Was the last response to the message OK
49  ARGUMENTS :
50  RETURN : true - message was OK
51  NOTES :
52  ------------------------------------------------------------------------------*/
53  bool wasCommandOk()
54  {
55  unsigned char * rxp = getRxPtr();
56  unsigned char checksum = FI2_RX_CHECKSUM_SEED;
57  unsigned char returnedChecksum = rxp[FI2_RX_CHECKSUM];
58  for(int i = 0; i < FI2_RX_LENGTH-FI2_CHECKSUM_SIZE; i++)
59  {
60  checksum += rxp[i];
61  }
62  return checksum == returnedChecksum;
63  }
64 
65 
66  /*------------------------------------------------------------------------------
67  FUNCTION : getTransacted
68 
69  DESCRIPTION : Can be called to see if the message has been transacted since it
70  was created or last checked.
71  ARGUMENTS :
72  RETURN :
73  NOTES :
74  ------------------------------------------------------------------------------*/
75  bool getTransacted(){bool temp = m_transacted; m_transacted = false; return temp;};
76 
77  /*------------------------------------------------------------------------------
78  FUNCTION : FrequencyInputSpiScheduledMessage::getCountData
79  DESCRIPTION : extract count, timestamp and error data from the response
80  ARGUMENTS : channel - return the channel whose data is in this message
81  sensorBreak - set to true if we have a sensorBreak - false otherwise
82  time - set to the timestamp of the last pulse detected
83  count - set to the count at the time the last pulse was detected
84  status - set to the status returned.
85  RETURN :
86  NOTES :
87  ------------------------------------------------------------------------------*/
88  void getCountData(unsigned char * channel, bool * sensorBreak, bool * shortCct, bool * shuntFitted, bool * contactFitted, unsigned long * time,
89  unsigned long * count, unsigned short * status)
90  {
91  unsigned char * rxp = getRxPtr();
92 
93  *channel = (rxp[FI2_RX_COUNT_A_AND_STATUS] & FI2_RX_CHANNEL_NUMBER_MASK )?1:0;
94  *sensorBreak = (rxp[FI2_RX_TIME_A_AND_STATUS] & FI2_RX_SENSOR_BREAK_MASK ) == FI2_RX_SENSOR_BREAK_MASK;
95  *shortCct = (rxp[FI2_RX_TIME_A_AND_STATUS] & FI2_RX_SHORT_CCT_MASK ) == FI2_RX_SHORT_CCT_MASK;
96  *shuntFitted = (rxp[FI2_RX_TIME_A_AND_STATUS] & FI2_RX_SHUNT_FITTED_MASK ) == FI2_RX_SHUNT_FITTED_MASK;
97  *contactFitted = (rxp[FI2_RX_COUNT_A_AND_STATUS] & FI2_RX_CONTACT_FITTED_MASK ) == FI2_RX_CONTACT_FITTED_MASK;
98 
99  /* short cct and sensor break is used to flag other failures */
100  if (*sensorBreak && *shortCct)
101  {
102  *status = rxp[FI2_RX_TIME_D] & FI2_SSM_STATUS_MASK;
103  // if both sensor_break and short circuit are flagged this means we have
104  // a status byte. Two bits in the status byte reflect the real state of
105  // sensor break and short circuit.
106  *sensorBreak = (rxp[FI2_RX_TIME_D] & FI2_SSM_STATUS_SENSOR_BREAK_MASK) == FI2_SSM_STATUS_SENSOR_BREAK_MASK;
107  *shortCct = (rxp[FI2_RX_TIME_D] & FI2_SSM_STATUS_SHORT_CIRCUIT_MASK) == FI2_SSM_STATUS_SHORT_CIRCUIT_MASK;
108  }
109  else
110  {
111  *status = FI2_SSM_TIME_STATUS_OK;
112  }
113  *time = (rxp[FI2_RX_TIME_A_AND_STATUS] & FI2_RX_TIME_MSB_MASK ) << 24;
114  *time += rxp[FI2_RX_TIME_B] << 16;
115  *time += rxp[FI2_RX_TIME_C] << 8;
116  *time += rxp[FI2_RX_TIME_D];
117  *count = (rxp[FI2_RX_COUNT_A_AND_STATUS] & FI2_RX_COUNT_MSB_MASK ) << 16;
118  *count += rxp[FI2_RX_COUNT_B] << 8;
119  *count += rxp[FI2_RX_COUNT_C];
120 
121 #ifdef FI_MODULE_FIRMWARE_DEBUG
122 if ((g_fred>0) && (*channel == (g_fred-1))) printf("%d,%d\r\n",*time,*count);
123 if (g_fred>=3)
124 {
125  unsigned char * txp = getTxPtr();
126  unsigned char csum=42;
127  for (char i=0;i<8;i++)
128  {
129  printf("%02X",rxp[i] );
130  }
131  if (*channel) printf("\r\n");
132 }
133 #endif
134  }
135 
136  /*------------------------------------------------------------------------------
137  FUNCTION : FrequencyInputSpiScheduledMessage::setConfig
138  DESCRIPTION : Set the configuration parts of the update message for a single channel
139  ARGUMENTS : channel - which channel (0 or 1)
140  debounceCode - one of the static const debounce codes EIO_FI2_DEBOUNCE_CODE_XXmS
141  voltCode - one of the static const PSU codes EIO_FI2_PSU_XXV_CODE
142  threshold - threshold and magnetic settings wrapped into a single byte
143  - 255 implies magnetic
144  - in mA mode 0 to 200 equates to 0 to 20mA
145  - in V mode 0 to 200 equates to 0 to 20V.
146  RETURN :
147  NOTES :
148  ------------------------------------------------------------------------------*/
149  void setConfig(int channel, unsigned char debounceCode, unsigned char voltCode, unsigned char threshold, bool on)
150  {
151  unsigned char * txp = getTxPtr();
152 
153 #ifdef FI_MODULE_FIRMWARE_DEBUG
154  if (g_fred==4)
155  {
156  txp[FI2_TX_CHANNEL_1_PSU_AND_DEBOUNCE] = g_conf1;
157  txp[FI2_TX_CHANNEL_1_THRESHOLD] = g_thr1;
158  txp[FI2_TX_CHANNEL_2_PSU_AND_DEBOUNCE] = g_conf2;
159  txp[FI2_TX_CHANNEL_2_THRESHOLD] = g_thr2;
160  }
161  else
162 #endif
163  if(channel)
164  {
165  /* channel 2 */
166  txp[FI2_TX_CHANNEL_2_PSU_AND_DEBOUNCE] = (voltCode & FI2_TX_SUPPLY_VOLTS_MASK) +
167  debounceCode;
168  txp[FI2_TX_CHANNEL_2_THRESHOLD] = threshold;
169 
170  if (!on)
171  txp[FI2_TX_CHANNEL_2_ENABLE] = FI2_TX_CHANNEL_OFF_MASK;
172  else
173  txp[FI2_TX_CHANNEL_2_ENABLE] = 0;
174  }
175  else
176  {
177  /* channel 1 */
178  txp[FI2_TX_CHANNEL_1_PSU_AND_DEBOUNCE] = (voltCode & FI2_TX_SUPPLY_VOLTS_MASK) +
179  debounceCode;
180  txp[FI2_TX_CHANNEL_1_THRESHOLD] = threshold;
181  if (!on)
182  txp[FI2_TX_CHANNEL_1_ENABLE] = FI2_TX_CHANNEL_OFF_MASK;
183  else
184  txp[FI2_TX_CHANNEL_1_ENABLE] = 0;
185  }
186 
187  }
188 
189  /*------------------------------------------------------------------------------
190  FUNCTION : FrequencyInputSpiScheduledMessage::setModuleLEDs
191  DESCRIPTION : Set which LEDs should be on or off.
192  ARGUMENTS : leds - this is made up by ORing together the macros
193  EIO_FI2_LED_2_MASK
194  EIO_FI2_LED_3_MASK
195  EIO_FI2_LED_CHANNEL_1_FAULT_MASK
196  EIO_FI2_LED_CHANNEL_2_FAULT_MASK
197  EIO_FI2_LED_1_MASK
198  EIO_FI2_LED_4_MASK
199  RETURN :
200  NOTES : inline for speed
201  ------------------------------------------------------------------------------*/
202  void setModuleLEDs(unsigned char leds)
203  {
204  unsigned char * txp = getTxPtr();
205  txp[FI2_TX_LEDS] = ~leds;
206 #ifdef FI_MODULE_FIRMWARE_DEBUG
207  if (g_fred==4)
208  txp[FI2_TX_LEDS] = g_leds;
209 #endif
210  }
211 
212  /*------------------------------------------------------------------------------
213  FUNCTION : FrequencyInputSpiScheduledMessage::checkTx
214  DESCRIPTION : Generate a checksum for data to be sent and place it at the end of
215  the data to be sent
216  ARGUMENTS :
217  RETURN :
218  NOTES :
219  ------------------------------------------------------------------------------*/
220  void checkTx()
221  {
222  unsigned char * txp = getTxPtr();
223  unsigned char checksum = FI2_TX_CHECKSUM_SEED;
224  for(int i = 0; i < FI2_TX_LENGTH-FI2_CHECKSUM_SIZE; i++)
225  {
226  checksum += txp[i];
227  }
228  txp[FI2_TX_CHECKSUM] = checksum;
229  }
230 
231 
232  public:
233  static const unsigned char EIO_FI2_MAGNETIC_THRESHOLD = 255;
234  static const unsigned char EIO_FI2_MAX_LOGIC_THRESHOLD = 200;
235 
236  static const unsigned char EIO_FI2_DEBOUNCE_CODE_50mS = 0x04;
237  static const unsigned char EIO_FI2_DEBOUNCE_CODE_20mS = 0x08;
238  static const unsigned char EIO_FI2_DEBOUNCE_CODE_10mS = 0x0C;
239  static const unsigned char EIO_FI2_DEBOUNCE_CODE_5mS = 0x10;
240  static const unsigned char EIO_FI2_DEBOUNCE_CODE_500uS = 0x14;
241  static const unsigned char EIO_FI2_DEBOUNCE_CODE_150uS = 0x18;
242  static const unsigned char EIO_FI2_DEBOUNCE_CODE_50uS = 0x1C;
243  static const unsigned char EIO_FI2_DEBOUNCE_CODE_15uS = 0x20;
244  static const unsigned char EIO_FI2_DEBOUNCE_CODE_OFF = 0x3C;
245 
246  static const unsigned char EIO_FI2_PSU_8V_CODE = 0;
247  static const unsigned char EIO_FI2_PSU_12V_CODE = 1;
248  static const unsigned char EIO_FI2_PSU_24V_CODE = 3;
249 
250  private:
251  static unsigned short moduleToDevice(unsigned char module);
252  bool m_transacted;
253  static const unsigned char FI2_TX_CHECKSUM_SEED = 213;
254  static const unsigned char FI2_RX_CHECKSUM_SEED = 42;
255  static const unsigned char FI2_CHECKSUM_SIZE = 1;
256 
257  static const unsigned char FI2_RX_CHANNEL_NUMBER_MASK = 0x40;
258  static const unsigned char FI2_RX_SENSOR_BREAK_MASK = 0x20;
259  static const unsigned char FI2_RX_SHORT_CCT_MASK = 0x40;
260  static const unsigned char FI2_RX_SHUNT_FITTED_MASK = 0x80;
261  static const unsigned char FI2_RX_CONTACT_FITTED_MASK = 0x80;
262 
263  enum
264  {
265  FI2_RX_TIME_A_AND_STATUS,
266  FI2_RX_TIME_B,
267  FI2_RX_TIME_C,
268  FI2_RX_TIME_D,
269  FI2_RX_COUNT_A_AND_STATUS,
270  FI2_RX_COUNT_B,
271  FI2_RX_COUNT_C,
272  FI2_RX_CHECKSUM,
273  FI2_RX_LENGTH
274  };
275 
276  static const unsigned char FI2_TX_DEBOUNCE_MASK = 0x3C;
277 
278  static const unsigned char FI2_CH1_CONFIG_MASK = 0x13;
279  static const unsigned char FI2_TX_SUPPLY_VOLTS_MASK = 0x03;
280  static const unsigned char FI2_CH2_CONFIG_MASK = 0x2C;
281  static const unsigned char FI2_TX_CHANNEL_OFF_MASK = 0x01;
282 
283  enum
284  {
285  FI2_TX_CHANNEL_1_PSU_AND_DEBOUNCE,
286  FI2_TX_CHANNEL_1_THRESHOLD,
287  FI2_TX_CHANNEL_2_PSU_AND_DEBOUNCE,
288  FI2_TX_CHANNEL_2_THRESHOLD,
289  FI2_TX_LEDS,
290  FI2_TX_CHANNEL_1_ENABLE,
291  FI2_TX_CHANNEL_2_ENABLE,
292  FI2_TX_CHECKSUM,
293  FI2_TX_LENGTH
294  };
295 };
296 
297 
298 #endif /*__FI_SSM_H */
299 
Definition: fi_ssm.h:39