// phy_services.h

// PMD services which apply on a per-port basis, the port is implicit
// as these are referenced from the per-port code (except for bias_detect)

typedef enum {
   PMD_CROSSOVER,
   PMD_NO_CROSSOVER,
   PMD_TONE_ON,   	                // instructs the PMD to generate a tone (see 6.8.1)
   PMD_TONE_OFF,                    // instructs the PMD to cease generating a tone,
                                    // remove the signalling bias voltage and set the
                                    // port transmitters to high impedance
   PMD_SELECT_BPORT,                // PMD uses bport for beta mode I/O - only set while
                                    // bport_on is TRUE, unset during suspend etc
   PMD_SELECT_DS_PORT,              // PMD uses dsport for data, arb states and speed signals
                                    // remains set during suspend etc
                                    // note, this does not affect use of bias or dc connect
   PMD_UNSELECT_PORT
} PMD_control_request_type;

PMD_CONTROL_request(PMD_control_request_type control_request, speedCode speed);


// PMD status flags - one set per port
#define PMD_BIAS_DETECT        0x00000001   // undebounced output of the PMD bias comparator
#define PMD_CONNECT_DETECT     0x00000002   // undebounced PMD output of connect_detect comparator
#define PMD_LOCAL_PLUG_PRESENT 0x00000004   // When AC coupled (possibly via, say, an optical transceiver)
            // indicates that an  external implementation dependent mechanism has determined that   
            // there is at least a physical connection from the local node to a cable 
            // (although there may not be a connection to the peer port). Used to avoid 
            // performing connection toning if there is definitely no connection. If there
            // is no such mechanism, then this flag shall be set permanently to TRUE.
            // This is a read-only bit in the port register map.
#define PMD_SIGNAL_DETECT      0x00000008   // set by PMD if a valid signal is being received
#define PMD_AUTOCROSSOVER_SUPPORTED 0x00000010  // Implementation dependent. Set by hardware. 
            // When true, indicates that the implementation supports crossover function 
            // (transmit on TPA, receive and signal detect on TPB). 
            // Only required to be true for ports which support UTP-5.

#ifdef unsubscripted
eventVar PMD_STATUS_request();        // returns bit map of the above
#else
eventVar PMD_STATUS_request(int i);
#endif

// Beta PMD
typedef struct { dataBit data; } PMD_data_ind_service;  // for data from PMD
PMD_data_ind_service waitPMD_DATA_indication();
void PMD_DATA_request(dataBit data);
speedCode PMD_CABLE_SPEED_request();
					            // Set by implementation-dependent means to the maximum speed 
					            // at which the cable attached to the port is allowed to operate. If no 
					            // cable-dependent speed indication is available, then the implementation 
					            // shall return the maximum speed that the port is capable of. 
					            // The encoding is the same as max_port_speed. This value is also 
					            // maintained as a read-only register in the port register map.

// DS PMD

RX_signal PMD_DSPORT_SIGNAL_request();                 // Return current signal from port

// DS PMD speed event flags
#define RX_S200               0x00000001
#define RX_S400               0x00000002
eventVar PMD_DSPORT_RXSPEED_request();

void PMD_DSPORT_DATA_request(portData pd);         // Transmit the data/strobe encoded data on the DS port
void PMD_DSPORT_ARB_request(TX_arbstate arb);  // Transmit the specified arbitration state on the DS port
void PMD_DSPORT_TXSPEED_request(speedCode speed);// Transmit the specified analog speed signal on the DS port
void PMD_DSPORT_TPBIAS_request(tpBiasSig sig);         // sig = Bias_On instructs the PMD to generate TpBias on TPA 
                                    // (as defined in IEEE 1394-1995). 
                                    // sig = GND instructs the PMD to drive the common mode 
                                    // voltage on TPA to VG. 
                                    // sig = ZZ instructs the PMD to cease generating TpBias and 
                                    // set TPA to high impedance.

// PHY level PMD service

boolean PMD_PS_request();           // TRUE if cable power active
                                    // value is maintained in Register 0

// Link
typedef enum {
  PH_IMMED_REQ=1,
  PH_NEXT_EVEN=2,
  PH_NEXT_ODD=3,
  PH_CURRENT=4,
  PH_ISOCH_REQ_EVEN=6,
  PH_ISOCH_REQ_ODD=7,
  PH_CYC_START_REQ=8,
  PH_RESET=9,
  PH_LPS_ACTIVE=10,
  PH_LPS_INACTIVE=11,
  PH_ISOCH_PHASE_ODD=12,
  PH_ISOCH_PHASE_EVEN=13,
  PH_CYCLE_START_DUE=14,
  PH_CYCLE_START_SEEN=16,
  PH_ISOCH_REQ=17,
  PH_PRIORITY_REQ=18,
  PH_FAIR_REQ=19
} phyArbReqType;
    
typedef struct {                    // request signal from link
  phyArbReqType reqType;            // The type of request
  speedCode speed;                  // speed of request, valid if reqType is PH_IMMED_REQ,
                                    // PH_CURRENT, PH_NEXT, PH_CYC_START_REQ, PH_ISOCH_REQ 
  boolean Beta_format;              // Set true when the link selected Beta-Only
} PH_arb_req_service;

PH_arb_req_service waitPH_ARB_request();

typedef enum { PH_REQ_DATA, PH_REQ_DATA_PREFIX,
  PH_REQ_DATA_END, PH_REQ_SUBACTION_END, PH_REQ_HOLD } phyDataReqType;

typedef struct {                    // data from link
  phyDataReqType reqType;
  union {
    byte data;                      // valid if reqType is PH_REQ_DATA
    speedCode speed;                // valid if reqType is PH_REQ_DATA_PREFIX for concatenated packets
  };
} PH_data_req_service;

PH_data_req_service waitPH_DATA_request();

typedef enum {PH_WON, PH_LOST, PH_WON_IMMED, PH_WON_ISOCH, PH_WON_CYCLE_START, 
  PH_WON_ASYNC} PH_arb_confirmations;
void PH_ARB_confirmation(PH_arb_confirmations Confirmation, speedCode Speed_Code,
                           pktType pkt_format);

typedef enum {PH_DATA_START, PH_DATA_BYTE, PH_DATA_PREFIX, PH_DATA_END, 
  PH_SUBACTION_GAP, PH_ARBITRATION_RESET_GAP, PH_ARB_RESET_ODD, PH_ARB_RESET_EVEN, 
  PH_ISOCH_ODD, PH_ISOCH_EVEN} PH_data_indications;
void PH_DATA_indication(PH_data_indications Indication, speedCode Speed_Code, 
                          byte Data_Byte, pktType pkt_format);

typedef enum {PH_LINK_ON, PH_BUS_RESET_START, PH_SELF_IDENTITY,  
  PH_BUS_RESET_COMPLETE, PH_INTERRUPT, PH_CABLE_POWER_FAIL, PH_CONFIG_TIMEOUT, 
  PH_RESTORE_RESET, PH_RESTORE_NO_RESET} PH_event_indications;
void PH_EVENT_indication(PH_event_indications Indication, int Physical_id, boolean Root);

void waitPH_EVENT_response();
void PH_CLOCK_indication();

linkType PH_LINK_TYPE_response();
