#ifndef COUNTERH #define COUNTERH /*counter.h 12/12/02 Nathan Z. Gustavson ngustavson@emacinc.com Emac.inc www.emacinc.com */ /*! @addtogroup count The 37e12 provides 8 general purpose digital lines on port 0 that can be configured as counters. These counters are all 16 bit down counters that can be configured to trigger on any edge. They can be set to do any of the following things when they hit zero: - Automatically roll over to a reload value. - Stop. - Send a notification packet with a 32 bit timestamp. Counters are typically used by calling E12_CountConfig followed by a call to E12_CountCommand to start/stop the counter. */ /*@{*/ #include #include #include typedef void (*CountHander)(int, void *); /*IC modes*/ /*!no input capture*/ #define NOE 0 /*!rising edge*/ #define RISEE 1 /*!falling edge*/ #define FALLE 2 /*!any edge*/ #define ANYE 3 /*ioctl counter command codes these codes are used by E12_CountCommand to send commands to counters. The counters must be configured by E12_CountConfig before these will have any effect */ /*!start the addressed counter*/ #define ICSTART 0 /*!stop the addressed counter*/ #define ICSTOP 1 /*!turn on zero cross notification*/ #define ICNOTIFYON 2 /*!turn off zero cross notification*/ #define ICNOTIFYOFF 3 /*!do nothing, legacy command*/ #define NULLCOMMAND 4 /*configuration flags These are bits to set in the flag variable passed to E12_CountConfig. They define certain characteristics of the counter */ /*!enable zero cross notification this will stick a packet into the 37e12's output FIFO whenever a zero cross occurs If the 37e12 goes for long periods without being read and isn't in autostop mode you may want to leave this off so you don't read a huge amount of notifications when you return to reading it. If you are reading periodically however it is recommended that you turn it on, as the parser will use it's notifications to store timestamp information about zero crossings */ #define ANOTE 1 /*!automatically reload from the threshold element when roll-over from zero occurs*/ #define AUTOLOAD 2 /*!stop counter when zero is reached, notification will still work in this case as it notifys at zero and not at the roll-over-*/ #define AUTOSTOP 4 #define NOTIFYRESPONSE BITMASK(ICNOTIFY) #define COUNTRESPONSE BITMASK(COUNTER) /*!This is the first step in using a counter. Before any of the other function will work this must be called. This function is used to configure a general purpose digital line on port 0 as a counter. Configuring a line as a counter will destroy any other configuration currently held on that pin, this will be reflected in the Cop_Data's configuration structures. This command does not start the counter, only configures it. To start a counter E12_CountCommand must be used with the ICSTART command. @param fd the 37e12 device being addressed @param counter the counter, or line number, to configure. 0-COUNTNUM. Only port 0 lines are configurable as counters. @param trigger int value from 0-3 determining what edge the counter counts on NOE, RISEE, FALLE, or ANYE @param threshold the reload value for the counter when the AUTOLOAD flag is on. @param flags a bitmask of 0 or more of the following counter options: ANOTE, AUTOLOAD and AUTOSTOP, @return 0 @see countconfig */ int E12_CountConfig(int fd, int counter, int trigger, int threshold,int flags,Cop_Data *Cop); /*!Compute an average frequency for a running counter from the timestamps. The frequency is calculated by dividing the starting count by the difference between the zero cross timestamp and the starting timestamp. It is therefore only accurate under the following conditions 1. The notify flag must be set. If it isn't then the 37e12 will not notify the board when zero crossings occur so accurate timestamps will not be available. 2. The counter value most not be modified while it's running. The 37e12 only sends a timer start timestamp when the board first receives the timer start signal, therefore if the counter value is modified during a count the timestamp will be wrong. 3. The frequency must be constant, if not the function can only compute an average frequency, not the current frequency. The greater the count relative to the frequency the more accurate the calculation. */ int E12_CounterCalcFreq(int counter, Cop_Data *Cop); /*!Change the value of a counter. This function can be used to change the current count. It can be used at any time, including while the counter is running. Changing the value of a running counter will not send a new countstart timestamp, only the start counter command does this. Therefore if a counter is changed while it's running E12_CounterCalcFreq will return an invalid value until the next count cycle. @param fd the 37e12 device being addressed @param counter the counter to modify 0-COUNTNUM @param data the new 16 bit value of the counter 0-0xffff @param Cop Cop data structure to shadow the variables into. @return 0 */ int E12_CounterLoad(int fd, int counter, int data, Cop_Data *Cop); /*!Request an update of a Cop counter element. This sends a request to the 37e12 to return the current status of a counter. This will result in a packet of type COUNTER being returned, or a bitmask of COUNTRESPONSE. The appropriate parsemask will be set for the counter returned. @param fd the 37e12 device being addressed @param counter the counter to request 0-COUNTNUM */ int E12_CounterReadRQ(int fd, int counter); /*!Send a command to a configured counter. Once a counter has been configured with E12_CountConfig it can be used toxz @param fd the 37e12 device being addressed @param counter the counter to request 0-COUNTNUM @param command ICSTART, ICSTOP, ICNOTIFYON, or ICNOTIFYOFF */ int E12_CountCommand(int fd, int counter,int command); /*!Request a counters configuration information from the hardware This function requests a counters configuration information from the hardware. Typically it's wrapped by UpdatetHardwareCounterInfo to update all the counters at once and handle the reading/parsing as well. @param fd the 37e12 device being addressed @param counter the counter to request 0-COUNTNUM */ int E12_CountCfg_Req(int fd, int counter); /*!Update the Cop structures count_config structures with data from the hardware. @param fd the 37e12 device being addressed @param Cop Cop data structure to shadow the variables into. @return 0 */ int UpdatetHardwareCounterInfo(int fd, Cop_Data *Cop); /*@}*/ #endif