##############################################################################
#                                                                            #
# IAR ARM ANSI C/C++ Compiler V4.11A/W32               20/Jul/2004  18:58:49 #
# Copyright 1999-2004 IAR Systems. All rights reserved.                      #
#                                                                            #
#    Cpu mode        =  arm                                                  #
#    Endian          =  little                                               #
#    Stack alignment =  4                                                    #
#    Source file     =  C:\medusa\sfpdiag.c                                  #
#    Command line    =  -I "C:\Program Files\IAR Systems\Embedded Workbench  #
#                       4.0\ARM\INC\" -lc C:\medusa\Debug\List\ -la          #
#                       C:\medusa\Debug\List\ -o C:\medusa\Debug\Obj\ -s2    #
#                       --no_cse --no_unroll --no_inline --no_code_motion    #
#                       --no_tbaa --no_clustering --no_scheduling --debug    #
#                       --cpu_mode arm --endian little --cpu ARM7TDMI-S      #
#                       --stack_align 4 -e --fpu None                        #
#                       "-D_DLIB_CONFIG_FILE=C:\Program Files\IAR            #
#                       Systems\Embedded Workbench                           #
#                       4.0\ARM\LIB\dl4tpannl8n.h" C:\medusa\sfpdiag.c       #
#    List file       =  C:\medusa\Debug\List\sfpdiag.lst                     #
#    Object file     =  C:\medusa\Debug\Obj\sfpdiag.r79                      #
#                                                                            #
#                                                                            #
##############################################################################

C:\medusa\sfpdiag.c
      1          #include "archinc.h"
      2          #include "cli.h"
      3          #include "i2cmaster.h"
      4          #include "i2cswitch.h"
      5          #include "sfp.h"
      6          #include "sfpdiag.h"
      7          
      8          #include <stdio.h>
      9          #include <stdlib.h>
     10          
     11          #if (defined(CONFIG_INCLUDE_LPC210X_I2C) && defined(CONFIG_INCLUDE_I2C_SFPDIAG))
     12          
     13          // SFP diagnostic address is hardwired to 0xa2
     14          
     15          /*
     16           * Control and status bits at offset 0x110
     17           *
     18           * 7 6 5 4 | 3 2 1 0          
     19           * x       |         - Tx Disable state (R/O)
     20           *   x     |         - Soft Tx disable (1=laser disabled)
     21           *     x   |         - reserved
     22           *       x |         - Rx rate select state (R/O)
     23           *         | x       - Soft rx rate select (1=full bandwidth)
     24           *         |   x     - Tx fault state (R/O)
     25           *         |     x   - LOS output state (R/O)
     26           *         |       x - Data ready state (R/O 0=data ready)
     27           *
     28           */
     29          
     30          static int sfpdiagHandler(int argc, char * argv[], int flags);
     31          
     32          typedef struct {
     33            unsigned short temp;           // 16-bit signed, 2's complement, LSB=1/256 deg C
     34            unsigned short vcc;            // 16-bit unsigned, LSB=100mV
     35            unsigned short txBiasCurrent;  // 16-bit unsigned, LSB=2uA
     36            unsigned short txPower;        // 16-bit unsigned, LSB=0.1 uWatt
     37            unsigned short rxPower;        // 16-bit unsigned, LSB=0.1 uWatt
     38            char status;
     39            } sfpDiagInfoRaw_t;
     40          
     41          typedef struct {
     42            float temp;           // 16-bit signed, 2's complement, LSB=1/256 deg C
     43            float vcc;            // 16-bit unsigned, LSB=100mV
     44            float txBiasCurrent;  // 16-bit unsigned, LSB=2uA
     45            float txPower;        // 16-bit unsigned, LSB=0.1 uWatt
     46            float rxPower;        // 16-bit unsigned, LSB=0.1 uWatt
     47            char status;
     48            } sfpDiagInfo_t;
     49          
     50          static sfpDiagInfo_t sfpDiagInfo[4];
     51          static sfpDiagInfoRaw_t sfpDiagInfoRaw[4];
     52          
     53          static unsigned short wavelength[4];
     54          
     55          static char diagOptsRaw[2];
     56          
     57          int sfpdiagInit(void)
     58          {
     59            int retVal;
     60            int i;
     61          
     62            cliRegisterCommand("sfpdiag", sfpdiagHandler, "get SFP diagnostic info on [bus number 0-3]");
     63          
     64            return retVal;
                          ^
Warning[Pe549]: variable "retVal" is used before its value is set

    int i;
        ^
"C:\medusa\sfpdiag.c",60  Warning[Pe177]: variable "i" was declared but never
          referenced
     65          }
     66          
     67          static unsigned char sfpDiagRawData[2*12];
     68          
     69          static void decodeDiagData(char * pDiagData, sfpDiagInfo_t *pSfpDiagInfo)
     70          {
     71            union {
     72              unsigned short int uint16;
     73              signed short int sint16;
     74              unsigned char uint8[2];
     75              } u;
     76          
     77            int i;
     78          
     79            if ((pDiagData == NULL) || (pSfpDiagInfo == NULL))
     80              return;
     81          
     82            for(i=0;i<8;i++) {
     83              // NOTE: swap the bytes: even byte is MSB, odd byte is LSB
     84              u.uint8[1] = pDiagData[(2*i)];
     85              u.uint8[0] = pDiagData[((2*i)+1)];
     86              switch(i) {
     87                case 0:
     88                  // 16-bit signed, 2's complement, LSB=1/256 deg C
     89                  pSfpDiagInfo->temp = (float)(u.sint16 * ((float)(1.0/256.0)));
     90                  break;
     91                case 1:
     92                  // 16-bit unsigned, LSB=100mV
     93                  pSfpDiagInfo->vcc = (float)(u.uint16 * ((float)(1.0/10000.0)));
     94                  break;
     95                case 2:
     96                  // 16-bit unsigned, LSB=2uA, expressed as mA
     97                  pSfpDiagInfo->txBiasCurrent = (float)(u.uint16 * ((float)(1.0/2000.0)));
     98                  break;
     99                case 3:
    100                  // 16-bit unsigned, LSB=0.1 uWatt, expressed in mW
    101                  pSfpDiagInfo->txPower = (float)(u.uint16 * ((float)(1.0/10000.0)));
    102                  break;
    103                case 4:
    104                  // 16-bit unsigned, LSB=0.1 uWatt, expressed in mW
    105                  pSfpDiagInfo->rxPower = (float)(u.uint16 * ((float)(1.0/10000.0)));
    106                  break;
    107                case 5:
    108                case 6:
    109                  // reserved
    110                  break;
    111                case 7:
    112                  pSfpDiagInfo->status = u.uint8[1];
    113                  break;
    114                }
    115              }
    116          
    117            return;
    118          }
    119          
    120          static void decodeDiagDataRaw(char * pDiagData, sfpDiagInfoRaw_t *pSfpDiagInfoRaw)
    121          {
    122            union {
    123              unsigned short uint16;
    124              signed short sint16;
    125              unsigned char uint8[2];
    126              } u;
    127          
    128            int i;
    129          
    130            if ((pDiagData == NULL) || (pSfpDiagInfoRaw == NULL))
    131              return;
    132          
    133            for(i=0;i<8;i++) {
    134                  u.uint8[0] = pDiagData[(2*i)];
    135                  u.uint8[1] = pDiagData[((2*i)+1)];
    136              switch(i) {
    137                case 0:
    138                  // 16-bit signed, 2's complement, LSB=1/256 deg C
    139                  pSfpDiagInfoRaw->temp = u.sint16;
    140                  break;
    141                case 1:
    142                  // 16-bit unsigned, LSB=100mV
    143                  pSfpDiagInfoRaw->vcc = u.uint16;
    144                  break;
    145                case 2:
    146                  // 16-bit unsigned, LSB=2uA
    147                  pSfpDiagInfoRaw->txBiasCurrent = u.uint16;
    148                  break;
    149                case 3:
    150                  // 16-bit unsigned, LSB=0.1 uWatt
    151                  pSfpDiagInfoRaw->txPower = u.uint16;
    152                  break;
    153                case 4:
    154                  // 16-bit unsigned, LSB=0.1 uWatt
    155                  pSfpDiagInfoRaw->rxPower = u.uint16;
    156                  break;
    157                case 5:
    158                case 6:
    159                  // reserved
    160                  break;
    161                case 7:
    162                  pSfpDiagInfoRaw->status = u.uint8[0];
    163                  break;
    164                }
    165              }
    166          
    167            return;
    168          }
    169          
    170          static int setupBus(int bus, unsigned char probeAddr)
    171          {
    172            int retVal;
    173          
    174            // setup the bus mux
    175            retVal = i2cswitchSetBus(bus);
    176          
    177            if (retVal == -1)
    178              return retVal;
    179          
    180            retVal = i2cmasterProbe(probeAddr);
    181          
    182            if (retVal == -1)
    183              return -2;
    184          
    185            return retVal;
    186          }
    187          
    188          // retrieves the diagnostic info from a particular bus
    189          int sfpdiagGetDiags(int bus)
    190          {
    191            int retVal = -1;
    192            int i;
    193          
    194            if ((retVal = setupBus(bus, 0xa2)) != 0)
    195              return retVal;
    196            
    197            // send the initial offset (96 decimal!!), and then read 16 bytes
    198            if (i2cmasterSendOne(0xa2, 96, false) != -1) {
    199              // TODO: check size
    200              retVal = i2cmasterReceive(0xa2, 24, true);
    201              for(i=0;((i<24) && (retVal != -1));i++) {
    202                retVal = i2cmasterGetData(&(sfpDiagRawData[i]));
    203                }
    204              }
    205          
    206            i2cswitchDisable();
    207          
    208            decodeDiagData(sfpDiagRawData, &(sfpDiagInfo[bus]));
                                  ^
Warning[Pe167]: argument of type "unsigned char *" is incompatible with
          parameter of type "char *"
    209            decodeDiagDataRaw(sfpDiagRawData, &(sfpDiagInfoRaw[bus]));
                                     ^
Warning[Pe167]: argument of type "unsigned char *" is incompatible with
          parameter of type "char *"
    210          
    211            return 0;
    212          }
    213          
    214          
    215          // retrieves the diagnostic info from a particular bus
    216          int sfpdiagGetWavelength(int bus)
    217          {
    218            int retVal = -1;
    219            int i;
    220          
    221            union {
    222              unsigned short uint16;
    223              char uint8[2];
    224            } u;
    225          
    226            if ((retVal = setupBus(bus, 0xa0)) != 0)
    227              return retVal;
    228            
    229            // send the initial offset (60 decimal!!), and then read 2 bytes
    230            if (i2cmasterSendOne(0xa0, 60, false) != -1) {
    231              // TODO: check size
    232              retVal = i2cmasterReceive(0xa0, 2, true);
    233          
    234              if (retVal != -1) {
    235                i2cmasterGetData(&(u.uint8[1]));
                                        ^
Warning[Pe167]: argument of type "char *" is incompatible with parameter of
          type "unsigned char *"
    236                i2cmasterGetData(&(u.uint8[0]));
                                        ^
Warning[Pe167]: argument of type "char *" is incompatible with parameter of
          type "unsigned char *"

    int i;
        ^
"C:\medusa\sfpdiag.c",219  Warning[Pe177]: variable "i" was declared but never
          referenced
    237                wavelength[bus] = u.uint16;
    238                }
    239              }
    240          
    241            i2cswitchDisable();
    242          
    243            return 0;
    244          }
    245          
    246          sfpDiagInfo_t * sfpdiagRetrieveInfo(int bus)
    247          {
    248            return &(sfpDiagInfo[bus]);
    249          }
    250          
    251          sfpDiagInfoRaw_t * sfpdiagRetrieveInfoRaw(int bus)
    252          {
    253            return &(sfpDiagInfoRaw[bus]);
    254          }
    255          
    256          static char vendorName[16];
    257          
    258          static int sfpdiagGetVendor(int bus)
    259          {
    260            int i, retVal;
    261          
    262            if ((retVal = setupBus(bus, 0xa0)) != 0) 
    263              return retVal;
    264          
    265            if (i2cmasterSendOne(0xa0, 20, true) != -1) {
    266              // TODO: check size
    267              retVal = i2cmasterReceive(0xa0, 16, true);
    268              for(i=0;((i<16) && (retVal != -1));i++) {
    269                retVal = i2cmasterGetData(&(vendorName[i]));
                                                 ^
Warning[Pe167]: argument of type "char *" is incompatible with parameter of
          type "unsigned char *"
    270                }
    271              }
    272          
    273            return retVal;
    274          }
    275          
    276          static void printSfpDiags(int diagChannel)
    277          {
    278            int bufLen;
    279            char * pOutBuf;
    280            sfpDiagInfo_t * pSfpInfo;
    281            sfpDiagInfoRaw_t * pSfpInfoRaw;
    282          
    283            pOutBuf = clicharGetOutputBuffer(&bufLen);
    284              
    285            sfpdiagGetDiags(diagChannel);
    286            pSfpInfo = sfpdiagRetrieveInfo(diagChannel);
    287            pSfpInfoRaw = sfpdiagRetrieveInfoRaw(diagChannel);
    288          
    289            sprintf(pOutBuf, "--- SFP diagnostics for channel [%d] ---\r\n", diagChannel);
    290            clicharSendOutputBuffer(pOutBuf, bufLen);    
    291            sprintf(pOutBuf, "temperature   : raw[%04x] %f deg C\r\n", pSfpInfoRaw->temp, pSfpInfo->temp);
    292            clicharSendOutputBuffer(pOutBuf, bufLen);    
    293            sprintf(pOutBuf, "Vcc           : raw[%04x] %f V\r\n", pSfpInfoRaw->vcc, pSfpInfo->vcc);
    294            clicharSendOutputBuffer(pOutBuf, bufLen);    
    295            sprintf(pOutBuf, "txBiasCurrent : raw[%04x] %f mA\r\n", pSfpInfoRaw->txBiasCurrent, pSfpInfo->txBiasCurrent);
    296            clicharSendOutputBuffer(pOutBuf, bufLen);    
    297            sprintf(pOutBuf, "txPower       : raw[%04x] %f mW\r\n", pSfpInfoRaw->txPower, pSfpInfo->txPower);
    298            clicharSendOutputBuffer(pOutBuf, bufLen);    
    299            sprintf(pOutBuf, "rxPower       : raw[%04x] %f mW\r\n", pSfpInfoRaw->rxPower, pSfpInfo->rxPower);
    300            clicharSendOutputBuffer(pOutBuf, bufLen);    
    301            sprintf(pOutBuf, "status        : raw[%02x]\r\n", pSfpInfo->status);
    302            clicharSendOutputBuffer(pOutBuf, bufLen);    
    303            sfpdiagGetWavelength(diagChannel);
    304            sprintf(pOutBuf, "wavelength    : %u nm\r\n", wavelength[diagChannel]);
    305            clicharSendOutputBuffer(pOutBuf, bufLen);
    306          
    307            return;
    308          }
    309          
    310          static void printMinSfpDiags(int diagChannel)
    311          {
    312            int bufLen;
    313            char * pOutBuf;
    314            sfpDiagInfo_t * pSfpInfo;
    315            sfpDiagInfoRaw_t * pSfpInfoRaw;
                                      ^
Warning[Pe550]: variable "pSfpInfoRaw" was set but never used
    316          
    317            pOutBuf = clicharGetOutputBuffer(&bufLen);
    318              
    319            sfpdiagGetDiags(diagChannel);
    320            pSfpInfo = sfpdiagRetrieveInfo(diagChannel);
    321            pSfpInfoRaw = sfpdiagRetrieveInfoRaw(diagChannel);
    322            sfpdiagGetWavelength(diagChannel);
    323          
    324            sprintf(pOutBuf, "sfpdiag: channel=%d, temp=%f, vcc=%f, txBiasI=%f, txPower=%f, rxPower=%f, lambda=%u, status=%02x\r\n",
    325              diagChannel, pSfpInfo->temp, pSfpInfo->vcc, pSfpInfo->txBiasCurrent, pSfpInfo->txPower, 
    326              pSfpInfo->rxPower, wavelength[diagChannel], pSfpInfo->status);
    327            clicharSendOutputBuffer(pOutBuf, bufLen);
    328          
    329            return;
    330          
    331          }
    332          
    333          static int sfpdiagHandler(int argc, char * argv[], int flags)
    334          {
    335            int retVal = -1;
    336            int bufLen;
    337            char * pOutBuf;
    338            int i;
    339            char blah;
                        ^
Warning[Pe177]: variable "blah" was declared but never referenced

  static char diagOptsRaw[2];
              ^
"C:\medusa\sfpdiag.c",55  Warning[Pe177]: variable "diagOptsRaw" was declared
          but never referenced

  static int sfpdiagGetVendor(int bus)
             ^
"C:\medusa\sfpdiag.c",258  Warning[Pe177]: function "sfpdiagGetVendor" was
          declared but never referenced
    340            int probeBus;
    341          
    342            pOutBuf = clicharGetOutputBuffer(&bufLen);
    343          
    344            if (argc == 2) {
    345              probeBus = (int)strtol(argv[1], (char **)NULL, 10);
    346              if ((probeBus < 0) || (probeBus > 3)) {
    347                return retVal;
    348                }
    349              if (sfpProbe(probeBus) == 0) {
    350                sprintf(pOutBuf, "%s: error SFP not found on bus [%d]\r\n", argv[0], probeBus);
    351                clicharSendOutputBuffer(pOutBuf, bufLen);
    352                }
    353              else {
    354                printSfpDiags(probeBus);
    355                }
    356              retVal = 0;
    357              }
    358            else if (argc == 1) {
    359              for(i=0;i<4;i++) {
    360                if (sfpProbe(i) == 0) {
    361                  printMinSfpDiags(i);
    362                  }
    363                }
    364              retVal = 0;
    365              }
    366          
    367            return retVal;
    368          }
    369          
    370          #endif /* (defined(CONFIG_INCLUDE_LPC210X_I2C) && defined(CONFIG_INCLUDE_I2C_SFPDIAG)) */
    371          

   Maximum stack usage in bytes:

     Function               CSTACK
     --------               ------
     decodeDiagData            20
     decodeDiagDataRaw          8
     printMinSfpDiags          80
     printSfpDiags             32
     setupBus                  16
     sfpdiagGetDiags           16
     sfpdiagGetWavelength      20
     sfpdiagHandler            40
     sfpdiagInit               12
     sfpdiagRetrieveInfo        0
     sfpdiagRetrieveInfoRaw     0


   Segment part sizes:

     Function/Label                 Bytes
     --------------                 -----
     sfpDiagInfo                      96
     sfpDiagInfoRaw                   48
     wavelength                        8
     sfpdiagInit                      48
     sfpDiagRawData                   24
     decodeDiagData                  304
     decodeDiagDataRaw               192
     setupBus                         80
     sfpdiagGetDiags                 196
     sfpdiagGetWavelength            156
     sfpdiagRetrieveInfo              16
     sfpdiagRetrieveInfoRaw           16
     printSfpDiags                   492
     printMinSfpDiags                220
     sfpdiagHandler                  244
     ??DataTable3                      4
     ??DataTable4                      4
     ??DataTable6                      4
     ?<Constant "sfpdiag">             8
     ?<Constant "get SFP diagnostic in...">
                                      44
     ?<Constant "--- SFP diagnostics f...">
                                      44
     ?<Constant "temperature   : raw[%...">
                                      40
     ?<Constant "Vcc           : raw[%...">
                                      36
     ?<Constant "txBiasCurrent : raw[%...">
                                      36
     ?<Constant "txPower       : raw[%...">
                                      36
     ?<Constant "rxPower       : raw[%...">
                                      36
     ?<Constant "status        : raw[%...">
                                      28
     ?<Constant "wavelength    : %u nm\r\n">
                                      24
     ?<Constant "sfpdiag: channel=%d, ...">
                                     100
     ?<Constant "%s: error SFP not fou...">
                                      40
      Others                         204

 
 2 168 bytes in segment CODE
   472 bytes in segment DATA_C
   176 bytes in segment DATA_Z
    12 bytes in segment INITTAB
 
 1 976 bytes of CODE  memory (+ 204 bytes shared)
   472 bytes of CONST memory
   176 bytes of DATA  memory

Errors: none
Warnings: 12
