mrfioc2  2.3.0
sfp.cpp
Go to the documentation of this file.
1 /*************************************************************************\
2 * Copyright (c) 2014 Brookhaven Science Associates, as Operator of
3 * Brookhaven National Laboratory.
4 * Copyright (c) 2015 Paul Scherrer Institute (PSI), Villigen, Switzerland
5 * mrfioc2 is distributed subject to a Software License Agreement found
6 * in file LICENSE that is included with this distribution.
7 \*************************************************************************/
8 #include <stdio.h>
9 
10 // for htons() et al.
11 #ifdef _WIN32
12  #include <Winsock2.h>
13 #endif
14 
15 #include <epicsExport.h>
16 #include "mrf/object.h"
17 #include "sfp.h"
18 
19 #include "mrfCommonIO.h"
20 
21 #include "sfpinfo.h"
22 
23 epicsInt16 SFP::read16(unsigned int offset) const
24 {
25  epicsUInt16 val = buffer[offset];
26  val<<=8;
27  val |= buffer[offset+1];
28  return val;
29 }
30 
31 SFP::SFP(const std::string &n, volatile unsigned char *reg)
32  :mrf::ObjectInst<SFP>(n)
33  ,base(reg)
34  ,buffer(SFPMEM_SIZE)
35  ,valid(false)
36 {
37  updateNow();
38 
39  /* Check for SFP with LC connector */
40  if(valid)
41  fprintf(stderr, "Found SFP EEPROM\n");
42  else
43  fprintf(stderr, "Found SFP Strangeness %02x%02x%02x%02x\n",
44  buffer[0],buffer[1],buffer[2],buffer[3]);
45 }
46 
48 
49 void SFP::updateNow(bool)
50 {
51  /* read I/O 4 bytes at a time to preserve endianness
52  * for both PCI and VME
53  */
54  epicsUInt32* p32=(epicsUInt32*)&buffer[0];
55 
56  for(unsigned int i=0; i<SFPMEM_SIZE/4; i++)
57  p32[i] = be_ioread32(base+ i*4);
58 
59  valid = buffer[0]==3 && buffer[2]==7;
60 }
61 
62 double SFP::linkSpeed() const
63 {
64  if(!valid){
65  return -1;
66  }
67  return buffer[SFP_linkrate] * 100.0; // Gives MBits/s
68 }
69 
70 double SFP::temperature() const
71 {
72  if(!valid){
73  return -40;
74  }
75  return read16(SFP_temp) / 256.0; // Gives degrees C
76 }
77 
78 double SFP::powerTX() const
79 {
80  if(!valid){
81  return -1e-6;
82  }
83  return read16(SFP_tx_pwr) * 0.1e-6; // Gives Watts
84 }
85 
86 double SFP::powerRX() const
87 {
88  if(!valid){
89  return -1e-6;
90  }
91  return read16(SFP_rx_pwr) * 0.1e-6; // Gives Watts
92 }
93 
94 static const char nomod[] = "<No Module>";
95 
96 std::string SFP::vendorName() const
97 {
98  if(!valid)
99  return std::string(nomod);
100  buffer_t::const_iterator it=buffer.begin()+SFP_vendor_name;
101  return std::string(it, it+16);
102 }
103 
104 std::string SFP::vendorPart() const
105 {
106  if(!valid)
107  return std::string(nomod);
108  buffer_t::const_iterator it=buffer.begin()+SFP_part_num;
109  return std::string(it, it+16);
110 }
111 
112 std::string SFP::vendorRev() const
113 {
114  if(!valid)
115  return std::string(nomod);
116  buffer_t::const_iterator it=buffer.begin()+SFP_part_rev;
117  return std::string(it, it+4);
118 }
119 
120 std::string SFP::serial() const
121 {
122  if(!valid)
123  return std::string(nomod);
124  buffer_t::const_iterator it=buffer.begin()+SFP_serial;
125  return std::string(it, it+16);
126 }
127 
128 std::string SFP::manuDate() const
129 {
130  if(!valid)
131  return std::string(nomod);
132  std::string ret("20XX/XX");
133  ret[2]=buffer[SFP_man_date];
134  ret[3]=buffer[SFP_man_date+1];
135  ret[5]=buffer[SFP_man_date+2];
136  ret[6]=buffer[SFP_man_date+3];
137  return ret;
138 }
139 
140 void SFP::report() const
141 {
142  printf("SFP tranceiver information\n"
143  " Temp: %.1f C\n"
144  " Link: %.1f MBits/s\n"
145  " Tx Power: %.1f uW\n"
146  " Rx Power: %.1f uW\n",
147  temperature(),
148  linkSpeed(),
149  powerTX()*1e6,
150  powerRX()*1e6);
151  printf(" Vendor:%s\n Model: %s\n Rev: %s\n Manufacture date: %s\n Serial: %s\n",
152  vendorName().c_str(),
153  vendorPart().c_str(),
154  vendorRev().c_str(),
155  manuDate().c_str(),
156  serial().c_str());
157 }
158 
160 
161  OBJECT_PROP2("Update", &SFP::junk, &SFP::updateNow);
162 
163  OBJECT_PROP1("Vendor", &SFP::vendorName);
164  OBJECT_PROP1("Part", &SFP::vendorPart);
165  OBJECT_PROP1("Rev", &SFP::vendorRev);
166  OBJECT_PROP1("Serial", &SFP::serial);
167  OBJECT_PROP1("Date", &SFP::manuDate);
168 
169  OBJECT_PROP1("Temperature", &SFP::temperature);
170  OBJECT_PROP1("Link Speed", &SFP::linkSpeed);
171  OBJECT_PROP1("Power TX", &SFP::powerTX);
172  OBJECT_PROP1("Power RX", &SFP::powerRX);
173 
174 } OBJECT_END(SFP)
OBJECT_BEGIN(SFP)
Definition: sfp.cpp:159
double temperature() const
Definition: sfp.cpp:70
virtual ~SFP()
Definition: sfp.cpp:47
void report() const
Definition: sfp.cpp:140
#define SFP_part_num
Definition: sfpinfo.h:26
double linkSpeed() const
Definition: sfp.cpp:62
std::string vendorPart() const
Definition: sfp.cpp:104
void updateNow(bool=true)
Definition: sfp.cpp:49
std::string vendorName() const
Definition: sfp.cpp:96
#define SFP_vendor_name
Definition: sfpinfo.h:25
#define SFP_tx_pwr
Definition: sfpinfo.h:35
#define OBJECT_PROP1(NAME, GET)
Definition: object.h:515
std::string vendorRev() const
Definition: sfp.cpp:112
std::string manuDate() const
Definition: sfp.cpp:128
SFP(const std::string &n, volatile unsigned char *reg)
Definition: sfp.cpp:31
#define SFP_temp
Definition: sfpinfo.h:34
#define SFP_part_rev
Definition: sfpinfo.h:30
#define OBJECT_END(klass)
Definition: object.h:523
#define SFP_linkrate
Definition: sfpinfo.h:22
#define SFP_rx_pwr
Definition: sfpinfo.h:36
#define SFP_serial
Definition: sfpinfo.h:27
double powerTX() const
Definition: sfp.cpp:78
#define OBJECT_PROP2(NAME, GET, SET)
Definition: object.h:518
Definition: sfp.h:16
#define SFPMEM_SIZE
Definition: sfpinfo.h:4
std::string serial() const
Definition: sfp.cpp:120
#define SFP_man_date
Definition: sfpinfo.h:31
Definition: flash.cpp:23
ObjectInst(const std::string &n)
Definition: object.h:466
#define be_ioread32(A)
Definition: mrfIoOpsDef.h:73
bool junk() const
Definition: sfp.h:31
double powerRX() const
Definition: sfp.cpp:86