From aa8f070195c0d791c995570a909ece6b409ebb00 Mon Sep 17 00:00:00 2001 From: Patrick Robbe <robbe@lal.in2p3.fr> Date: Sat, 4 Apr 2020 18:58:22 +0200 Subject: [PATCH] Add minipod configuration program --- .gitignore | 1 + Pcie40Applications/Makefile | 8 +- Pcie40Applications/main_pcie40_miniPod.c | 712 +++++++ Pcie40Libraries/Makefile | 2 +- Pcie40Libraries/avagoMinipodCtrl.c | 2451 ++++++++++++++++++++++ Pcie40Libraries/avagoMinipodCtrl.h | 235 +++ 6 files changed, 3407 insertions(+), 2 deletions(-) create mode 100644 Pcie40Applications/main_pcie40_miniPod.c create mode 100644 Pcie40Libraries/avagoMinipodCtrl.c create mode 100644 Pcie40Libraries/avagoMinipodCtrl.h diff --git a/.gitignore b/.gitignore index 6133ce4..427f7e4 100644 --- a/.gitignore +++ b/.gitignore @@ -35,6 +35,7 @@ Pcie40Applications/pcie40_readFPGAversion Pcie40Applications/pcie40_klmbytestream Pcie40Applications/pcie40_dma_check Pcie40Applications/pcie40_ulreset +Pcie40Applications/pcie40_miniPod *.d **/pcie40_reload.out diff --git a/Pcie40Applications/Makefile b/Pcie40Applications/Makefile index addf4af..a118d35 100644 --- a/Pcie40Applications/Makefile +++ b/Pcie40Applications/Makefile @@ -69,13 +69,18 @@ PCIE40_ULRESET_CXXFLAGS =$(CFLAGS) -I$(TOP) -I$(TOP)/../Pcie40Driver PCIE40_ULRESET_INSTALL =$(PREFIX)/bin PCIE40_ULRESET_LDFLAGS = -L../Pcie40Libraries/lib -lpcie40 -L../Pcie40DriverLibraries/ -lpcie40driver_ecs - PCIE40_READFPGAVERSION :=pcie40_readFPGAversion PCIE40_READFPGAVERSION_OBJS =main_pcie40_readFPGAversion.o PCIE40_READFPGAVERSION_CXXFLAGS =$(CFLAGS) -I$(TOP) -I$(TOP)/../Pcie40Driver -I$(TOP)/../Pcie40DriverLibraries PCIE40_READFPGAVERSION_INSTALL =$(PREFIX)/bin PCIE40_READFPGAVERSION_LDFLAGS = -L../Pcie40Libraries/lib -lpcie40 -L../Pcie40DriverLibraries/ -lpcie40driver_ecs +PCIE40_MINIPOD :=pcie40_miniPod +PCIE40_MINIPOD_OBJS =main_pcie40_miniPod.o +PCIE40_MINIPOD_CXXFLAGS =$(CFLAGS) -I$(TOP) -I$(TOP)/../Pcie40Driver -I$(TOP)/../Pcie40DriverLibraries -I$(TOP)/../Pcie40Libraries +PCIE40_MINIPOD_INSTALL =$(PREFIX)/bin +PCIE40_MINIPOD_LDFLAGS = -L../Pcie40Libraries/lib -lpcie40 -L../Pcie40DriverLibraries/ -lpcie40driver_ecs + VPATH :=$(TOP) include $(TOP)/rules.mk @@ -91,6 +96,7 @@ $(eval $(call ODIR_template,PCIE40_UL)) $(eval $(call ODIR_template,PCIE40_ULRESET)) $(eval $(call ODIR_template,PCIE40_DMA_CHECK)) $(eval $(call ODIR_template,PCIE40_READFPGAVERSION)) +$(eval $(call ODIR_template,PCIE40_MINIPOD)) $(eval $(call COPY_template,SCRIPTS,755)) $(eval $(call LINK_template,PCIE40_RELOAD)) $(eval $(call ODIR_template,PCIE40_RELOAD_SUID)) diff --git a/Pcie40Applications/main_pcie40_miniPod.c b/Pcie40Applications/main_pcie40_miniPod.c new file mode 100644 index 0000000..52ceab9 --- /dev/null +++ b/Pcie40Applications/main_pcie40_miniPod.c @@ -0,0 +1,712 @@ +/**--------------------------------------------------------------------------------------------- +* \file minipodCmd.c +* +* \brief This file contains the command interpreter to execute some commands on the +Avago minipods of the AMC40. +* +* \details Command flags are +* -d vendor data read +* -t internal temperatures read +* -p 33 or 25 the used power read +* -o the optical pave read +* -e elapsed power on +* -v r or w read or write VOD +* -d r or w deamphasis read or write +* -q r or w equalization read or write +* -n the target components which can be: +* x a channel number +* tx for all tx +* rx for all rx +* all for all +* +* output values are strings composed of pairs cahnnelNb=Value comma separated. +* +* \author PYD : Pierre-Yves Duval +* \version 0.1 +* \date 18/06/2013 +* \copyright (c) Copyright CERN for the benefit of the LHCb Collaboration. +* Distributed under the terms of the GNU General Public Licence V3. +* ana.py script is free and open source software. +* +* CHANGELOG +* PYD : 18/06/2013 initial version +* PYD : 04/3/2014 add the script mode with raw printing +* PYD : 07/01/2016 adpated to PCIe40 +*----------------------------------------------------------------------------------------------- +*/ +#include <ctype.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <getopt.h> + +#define MPOCPP 1 +#include <avagoMinipodCtrl.h> +#include <i2cDriver.h> +#include <systemConfig.h> + +#define DEBUG 0 +#define NONE 999 + +#define VPRINT(a) if(interactiv) printf(a); +#define DPRINT(a) if(debug) printf(a); +#define STATUS_LINE printf("=======================================================================================\n") + +int interactiv = 1; +int debug = DEBUG; + +enum targetsMp {ALLMP, ALLTX, ALLRX, SINGLEMP}; +enum targetsCh {ALLCH, SINGLECH}; + +enum targetsMp currentMpTarget = ALLMP; + +int currentBoard = 0; +int currentMinipod = NONE; +int currentChannel = NONE; + +enum commands { +// initSpeed, useless because init speed is executed at each program start +// getSpeed, can't work because library is reloaded + errorStatus, + dumpLos, + dumpFault, + dumpBiasCurrent, + dumpLightOutput, + doReset, + channelDisable, + channelEnable, + channelDump, + marginActivation, + marginDeactivation, + marginDump, + + fullStatus, + vendorData, + squelchDisable, + squelchEnable, + squelchDump, + internalTmp, + vcc33, + vcc25, + dumpLightInput, + pwOnElapsed, + vodRd, + vodWr, + deamphasRd, + deamphasWr, + equalRd, + equalWr, + channelPolarInvert, + channelPolarNormal, + channelPolarDump + }; + +enum commands cmd = fullStatus; + +int arrayParams[12] = {NONE,NONE,NONE,NONE,NONE,NONE,NONE,NONE,NONE,NONE,NONE,NONE}; +int array2Params[2] = {NONE,NONE}; +int singleParam = NONE; + +void printHelp(){ + VPRINT("Usage : minipodCmd ...... c'est la .....\n"); + VPRINT("--------------------------COMMANDS--------------------------------\n"); + VPRINT("--init-speed set i2c bus speed (inClock & SCL freq)(default 125000000 and 100000)\n"); +// VPRINT("--get-speed sget the last set i2c bus speed (inClock & SCL freq)\n"); + VPRINT("--full-status print the full minipods status\n"); + VPRINT("--temperature print the internal temperature of minipods\n"); + VPRINT("--vcc-3.3 print the 3.3 Vcc values of minipods\n"); + VPRINT("--vcc-2.5 print the 2.5 Vcc values of minipods\n"); + VPRINT("--error-status print general erro status of minipods\n"); + VPRINT("--los-status print LOS loss of signal status channels\n"); + VPRINT("--faults-status print faults of TX minipods channels\n"); + VPRINT("--bias-current print bias current of TX minipods channels\n"); + VPRINT("--light-output print light output optical power of TX minipods channels\n"); + VPRINT("--light-input print light input optical power PAVE of RX minipods channels\n"); + VPRINT("--reset do minipods reset (parameters set to factory values)\n"); + VPRINT("--channel-disable disable minipods channels\n"); + VPRINT("--channel-enable enable minipods channels\n"); + VPRINT("--channel-dump print enable/disable status of minipods channels\n"); + VPRINT("--squelch-disable disable squelch of minipods channels\n"); + VPRINT("--squelch-enable enable squelch of minipods channels\n"); + VPRINT("--squelch-dump print squelch status of minipods channels\n"); + VPRINT("--margin-activation activate margin of TX minipods channels\n"); + VPRINT("--margin-deactivation deactivate margin of TX minipods channels\n"); + VPRINT("--margin-dump print margin activation status of minipods channels\n"); + VPRINT("--vendor-info print vendor informations of minipods\n"); + VPRINT("--in-equal-read read the input equalization values of minipods channeles\n"); + VPRINT("--in-equal-write set values for the input equalization of minipods channels\n"); + VPRINT("--out-amplitude-read read the output amplitude VOD of RX minipods channels\n"); + VPRINT("--out-amplitude-write set values for the output amplitude VOD of RX minipods channels\n"); + VPRINT("--out-deamphas-read read the output deamphasis of RX minipods channels\n"); + VPRINT("--out-deamphas-write set values for the output deamphasis of RX minipods channels\n"); + VPRINT("--polarity-invert invert polarity of minipods channels\n"); + VPRINT("--polarity-normal normal plority for minipods channels\n"); + VPRINT("--polarity-dump print enable/disable status of minipods polarity inversion\n"); + + VPRINT("-------------------WRITE VALUES SPECIFICATION----------------------\n"); + VPRINT("--param-list (-l) values parameter 12 comma separated values\n"); + VPRINT("--param-pair (-d) values parameter 2 comma separated values\n"); + VPRINT("--param-val (-v) value parameter one single value\n"); + VPRINT("-------------------TARGETS SPECIFICATION---------------------------\n"); + VPRINT("BOARDS\n"); + VPRINT("--board (-b) the board number to deal with:\n"); + VPRINT("CHANNELS\n"); + VPRINT("--channel (-c) the target components channel specifier which can be:\n"); + VPRINT("\tx a channel number ( x value is between O and 11)\n"); + VPRINT("\tall for all channels\n"); + VPRINT("MINIPODS\n"); + VPRINT("--module (-m) the target minipod specifier which can be:\n"); + VPRINT("\tx a minipod number ( x value is between O and 7)\n"); + VPRINT("\tall for all minipods\n"); + VPRINT("Default is \"all\" but:\n"); + VPRINT("when writing specify at least: one minipod OR one channel (write all minipods) OR both\n"); + VPRINT("when reading specify:\n"); + VPRINT("\tno target (all will be printed)\n"); + VPRINT("\tone minipod (all minipods channels will be printed)\n"); + VPRINT("\tone minipod and a channel\n"); + VPRINT("--------------------------SERVICES--------------------------------\n"); + VPRINT("-h this help\n"); + VPRINT("-i interactiv mode, errors are printed\n"); + VPRINT("-s script mode, minimum raw data are printed\n"); +} +/***********************************************/ +void dumpStatus() +{ + printf("NOT YET IMPLEMENTED\n"); +} +/***********************************************/ +int scan12values(char *chain, int *data){ + if (sscanf(chain, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d", + data,(data+1),(data+2),(data+3),(data+4),(data+5), + (data+6),(data+7),(data+8),(data+9),(data+10),(data+11)) !=12){ + printf("ERROR: parameter sting doesnt contain 12 comma separated values\n"); + return(-1); + } + return(0); +} +int scan2values(char *chain, int *data){ + if (sscanf(chain, "%d,%d", + data,(data+1)) !=2){ + printf("ERROR: parameter sting doesnt contain 2 comma separated values\n"); + return(-1); + } + return(0); +} +int scan1value(char *chain, int *data){ + if (sscanf(chain, "%d", data) != 1){ + printf("ERROR: parameter string doesnt contain 1 single value\n"); + return(-1); + } + return(0); +} +/*********************************************************************************** +* function to print the general error status +**************************************************************************************/ +void printErrorStatus(int dev){ + switch (currentMpTarget) { + case ALLMP: + mpod_dumpErrStatusAll(dev); + break; + case SINGLEMP: + mpod_dumpErrStatus(dev, currentMinipod); + break; + default: printf("ERROR: unknown target\n"); + exit(0); + } + } +/*********************************************************************************** +* function to print status with a dump function by minipod which return 6 values +* It use two different function if its a global printing foa all minipods or +* only one. +* in : ptr to function to print for 1 minipod +* ptr to filtering function which minimod to print (should return 1 for selected) +**************************************************************************************/ +void printMinipodInfo(int dev, int(*dumpAll)(int), int(*dump)(int, int, int*)){ +int val; + + switch (currentMpTarget) { + case ALLMP: + dumpAll(dev); + break; + case SINGLEMP: + dump(dev, currentMinipod, &val); + break; + default: printf("ERROR: unknown target\n"); + exit(0); + } +} +/**************************************************************************** +* function to print status with a dump function by minipod +* in : ptr to function to print for 1 minipod +* ptr to filtering function which minimod to print (should return 1 for selected) +*****************************************************************************/ +void printChannelInfo(int dev, int(*dump)(int,int), int(*filter)(int)){ +int i; + switch (currentMpTarget) { + case ALLMP: + for (i=0; i<8; i++){ + if (filter!=NULL) + if (!filter(i)) + continue; + dump(dev,i); + } + break; + case SINGLEMP: + dump(dev, currentMinipod); + break; + default: printf("ERROR: unknown target\n"); + exit(0); + } +} +/**************************************************************************** +* function to set bits in words for channel parameters stored in one bit +* in : setbit : pointer to function to set the bit channel +* filter : ptr to filtering function which minimod to print (should return 1 for selected) +* bval : the bit value to write 0/1 +*****************************************************************************/ +void setBitsChannel(int dev, int(*setBit)(int,int,int,int), int(*filter)(int), int bval){ +int minipod, channel; + + switch (currentMpTarget) { + case ALLMP: + for (minipod=0; minipod<8; minipod++){ + if (filter!=NULL) + if (!filter(minipod)) + continue; + if (currentChannel==NONE){ + for (channel=0; channel<12; channel++) + setBit(dev, minipod, channel, bval); + } + else + setBit(dev, minipod, currentChannel, bval); + } + break; + case SINGLEMP: + if (currentChannel==NONE){ + for (channel=0; channel<12; channel++) + setBit(dev, currentMinipod, channel, bval); + } + else + setBit(dev, currentMinipod, currentChannel, bval); + break; + default: printf("ERROR: unknown target\n"); + exit(0); + } +} +/**************************************************************************** +* function to print status with a dump function by minipod +* in : dump : ptr to function to print for 1 minipod +* filter: ptr to filtering function which minimod to print (should return 1 for selected) +*****************************************************************************/ +void printfloatMSBLSB(int dev, int(*dump)(int, int,float**), int(*filter)(int)) { +int minipod; +float *bloc = 0; + +switch (currentMpTarget) { + case ALLMP: + for (minipod=0; minipod<8; minipod++){ + if (filter!=NULL) + if (!filter(minipod)) + continue; + dump(dev, minipod, &bloc); // prints on output + free(bloc); + } + break; + case SINGLEMP: +if (filter!=NULL) + if (!filter(currentMinipod)){ + printf("ERROR: Minipod %d is a wrong command's target\n",currentMinipod); + return; + } + dump(dev, currentMinipod, &bloc); // prints on output + free(bloc); + break; + default: printf("ERROR: unknown target\n"); + exit(0); + } +} + +/***************************************************************************************** +* Function to read 12 channel values passed as a bloc of integers. Used for registers +* organized in 6 word with values encode on 4 bits. +* in : read : ptr to function to read for 1 minipod +* readChan : ptr to function to read for 1 channel of 1 minipod +* filter : +*****************************************************************************************/ +void read12Int(int dev, int(*read)(int,int,int**), int(*readChan)(int,int,int,int*), int(*filter)(int)) { +int minipod, code; +int *bloc = 0;//PYD + + switch (currentMpTarget) { + case ALLMP: + for (minipod=0; minipod<8; minipod++){ + if (filter!=NULL) + if (!filter(minipod)) + continue; + read(dev, minipod, &bloc); // prints on output all channels + free(bloc); + } + break; + case SINGLEMP: // one minipod + if (filter!=NULL){ + if (!filter(currentMinipod)){ + printf("ERROR: Minipod %d is a wrong command's target\n",currentMinipod); + return; + } + } + if (currentChannel==NONE){ + read(dev, currentMinipod, &bloc); // prints on output all channels + free(bloc); + } + else { + readChan(dev, currentMinipod, currentChannel, &code); // print one channel + } + break; + default: printf("ERROR: unknown target\n"); + exit(0); + } +} +/***************************************************************************************** +* Function to write 12 channel values passed as a bloc of integers. Used for registers +* organized in 8 word with values encode on 4 bits. +* in : write : ptr to function to write in 1 minipod channels +* writeChan : ptr to function to write in 1 channel of 1 minipod +* filter : +*****************************************************************************************/ +void write12Int(int dev, int(*write)(int,int,int*), int(*writeChan)(int,int,int,int), int(*filter)(int)) { +int minipod; + + switch (currentMpTarget) { + case ALLMP: + for (minipod=0; minipod<8; minipod++){ + if (filter!=NULL) + if (!filter(minipod)) + continue; + if (currentChannel==NONE){ + if (arrayParams[0]!=NONE) + write(dev, minipod, arrayParams); // prints on output + else + printf("ERROR: you should specify the 12 values to write\n"); + } + else { + if (singleParam != NONE) + writeChan(dev, minipod, currentChannel, singleParam); // prints on output + else + printf("ERROR: you should specify a value to write\n"); + } + }//for + break; + case SINGLEMP: + if (filter!=NULL) + if (!filter(currentMinipod)) + break; + if (currentChannel==NONE){ + if (arrayParams[0]!=NONE) + write(dev, currentMinipod, arrayParams); // prints on output + else + printf("ERROR: you should specify the 12 values to write\n"); + } + else { + if (singleParam != NONE) + writeChan(dev, currentMinipod, currentChannel, singleParam); // prints on output + else + printf("ERROR: you should specify a value to write\n"); + } + break; + default: printf("ERROR: unknown target\n"); + exit(0); + } +} + +/***********************************************/ +int main (int argc, char **argv) { + +char * optstring = "m:c:l:d:v:b:fsh"; +struct option longopts[] = { + /* name has_arg flag val */ +// { "init-speed", 0, (int*)&cmd, initSpeed }, +// { "get-speed", 0, (int*)&cmd, getSpeed }, + { "full-status", 0, (int*)&cmd, fullStatus }, + { "error-status", 0, (int*)&cmd, errorStatus }, + { "los-status", 0, (int*)&cmd, dumpLos }, + { "faults-status", 0, (int*)&cmd, dumpFault}, + { "bias-current", 0, (int*)&cmd, dumpBiasCurrent}, + { "temperature", 0, (int*)&cmd, internalTmp}, + { "vcc-3.3", 0, (int*)&cmd, vcc33}, + { "vcc-2.5", 0, (int*)&cmd, vcc25}, + { "light-output", 0, (int*)&cmd, dumpLightOutput}, + { "elapsed", 0, (int*)&cmd, pwOnElapsed}, + { "reset", 0, (int*)&cmd, doReset}, + + { "channel-disable", 0, (int*)&cmd, channelDisable}, + { "channel-enable", 0, (int*)&cmd, channelEnable}, + { "channel-dump", 0, (int*)&cmd, channelDump}, + + { "squelch-disable", 0, (int*)&cmd, squelchDisable}, + { "squelch-enable", 0, (int*)&cmd, squelchEnable}, + { "squelch-dump", 0, (int*)&cmd, squelchDump}, + + { "margin-activation", 0, (int*)&cmd, marginActivation}, + { "margin-deactivation",0, (int*)&cmd, marginDeactivation}, + { "margin-dump", 0, (int*)&cmd, marginDump}, + + { "vendor-info", 0, (int*)&cmd, vendorData}, + + { "in-equal-read", 0, (int*)&cmd, equalRd}, + { "in-equal-write", 0, (int*)&cmd, equalWr}, + + { "light-input", 0, (int*)&cmd, dumpLightInput}, + + { "out-amplitude-read", 0, (int*)&cmd, vodRd}, + { "out-amplitude-write",0, (int*)&cmd, vodWr}, + + { "out-deamphas-read", 0, (int*)&cmd, deamphasRd}, + { "out-deamphas-write", 0, (int*)&cmd, deamphasWr}, + + { "polarity-invert", 0, (int*)&cmd, channelPolarInvert}, + { "polarity-normal", 0, (int*)&cmd, channelPolarNormal}, + { "polarity-dump", 0, (int*)&cmd, channelPolarDump}, + + { "module", 1, NULL, 'm' }, + { "channel", 1, NULL, 'c' }, + { "param-list", 1, NULL, 'l' }, + { "param-val", 1, NULL, 'v' }, + { "param-pair", 1, NULL, 'd' }, + { "board", 1, NULL, 'b' }, + /* Le dernier element doit etre nul */ + { NULL, 0, NULL, 0 }, + }; +int longindex; +int option; +char *cvalue = NULL; +int i, minipod; +opterr = 1; + +// can only be scanned once + while ((option = getopt_long(argc, argv, optstring, longopts, & longindex)) != -1) { + + switch (option) { + case 'm' : + DPRINT("m\n"); + cvalue = optarg; + if (strncmp(cvalue, "all", 3)==0){ + DPRINT("all\n"); + currentMpTarget = ALLMP; + } + else if(sscanf(cvalue, "%d", &i) != 0){ //It's an int. + if((i>=0) && (i<=7)){ + currentMinipod = i; + currentMpTarget = SINGLEMP; + } + else { + VPRINT("ERROR: Wrong minipod number [should be 0 to 5]\n"); + printHelp(); + exit(0); + } + } + else { + VPRINT("ERROR: Wrong target component specification\n"); + printHelp(); + exit(0); + } + break; + case 'b' : + DPRINT("b\n"); + cvalue = optarg; + if(sscanf(cvalue, "%d", &i) != 0){ //It's an int. + if(i < MAX_DEV){ + currentBoard = i; + DPRINT("Current board changed\n"); + } + else { + VPRINT("ERROR: impossible board number\n"); + printHelp(); + exit(0); + } + } + break; + case 'c' : + DPRINT("c\n"); + cvalue = optarg; + if (strncmp(cvalue, "all", 3)==0) { + DPRINT("all\n"); + } + else if(sscanf(cvalue, "%d", &i) != 0){ //It's an int. + if((i>=0) && (i<=11)){ + currentChannel = i; + } + else { + VPRINT("ERROR: Wrong channel number [should be 0 to 11]\n"); + printHelp(); + exit(0); + } + } + else { + VPRINT("ERROR: Wrong target component specification\n"); + printHelp(); + exit(0); + } + break; + case 'l' : + DPRINT("l\n"); + //printf("parameters %s\n", optarg); + if (scan12values(optarg, arrayParams) !=0) + exit(0); + break; + case 'd' : + DPRINT("d\n"); + //printf("parameters %s\n", optarg); + if (scan2values(optarg, array2Params) !=0) + exit(0); + break; + case 'v' : + DPRINT("v\n"); + //printf("single parameter %s\n", optarg); + if (scan1value(optarg, &singleParam) !=0) + exit(0); + break; + case 's': + mpod_setMode(1); + break; + case 'h': + printHelp(); + return(0); + break; + case 0 : + break; + case '?' : + break; + }//switch + }//while + //set default value +/* Remove because reinitialize the bus at each command */ + if (mpod_init(currentBoard, 100000000, 100000)) + exit(2); + + switch (cmd) { + case errorStatus: + printErrorStatus(currentBoard); + break; + case dumpLos: + printChannelInfo(currentBoard, mpod_losDumpAll,NULL); + break; + case dumpFault: + printChannelInfo(currentBoard, mpod_faultDumpAll,mpod_isTX); + break; + case dumpBiasCurrent: + printfloatMSBLSB(currentBoard, mpod_biasCurrent, mpod_isTX); + break; + case dumpLightOutput: + printfloatMSBLSB(currentBoard, mpod_lightOutput, mpod_isTX); + break; + case internalTmp: // validated OK + printMinipodInfo(currentBoard, mpod_internalTempDumpAll, mpod_internalTemp); + break; + case vcc33: // validated OK + printMinipodInfo(currentBoard, mpod_internal33VccDumpAll, mpod_internal33Vcc); + break; + case vcc25: // validated OK + printMinipodInfo(currentBoard, mpod_internal25VccDumpAll, mpod_internal25Vcc); + break; + case dumpLightInput: // validated OK + printfloatMSBLSB(currentBoard, mpod_lightInput, mpod_isRX); + break; + case pwOnElapsed: + printf("Not implemeneted because information is wrong in the chip\n"); + break; + case vendorData: + printChannelInfo(currentBoard, mpod_dumpVendorData,NULL); + break; + case fullStatus: + //dumpStatus(); + printMinipodInfo(currentBoard, mpod_internalTempDumpAll, mpod_internalTemp); + printMinipodInfo(currentBoard, mpod_internal33VccDumpAll, mpod_internal33Vcc); + printMinipodInfo(currentBoard, mpod_internal25VccDumpAll, mpod_internal25Vcc); + printErrorStatus(currentBoard); + printChannelInfo(currentBoard, mpod_losDumpAll,NULL); + printChannelInfo(currentBoard, mpod_faultDumpAll,mpod_isTX); + printfloatMSBLSB(currentBoard, mpod_biasCurrent, mpod_isTX); + printfloatMSBLSB(currentBoard, mpod_lightOutput, mpod_isTX); + break; + case doReset: + switch (currentMpTarget) { + case ALLMP: + for (minipod=0; minipod<8; minipod++) + mpod_reset(currentBoard, minipod); + break; + case SINGLEMP: + mpod_reset(currentBoard, currentMinipod); + break; + default: printf("ERROR: unknown target\n"); + exit(0); + } + break; + + case channelDisable: + setBitsChannel(currentBoard, mpod_channelDisable, NULL, 1); + break; + case channelEnable: + setBitsChannel(currentBoard, mpod_channelDisable, NULL, 0); + break; + case channelDump: + printChannelInfo(currentBoard, mpod_channelDisDumpAll,NULL); + break; + + case channelPolarInvert: + setBitsChannel(currentBoard, mpod_polarityFlip, NULL, 1); + break; + case channelPolarNormal: + setBitsChannel(currentBoard, mpod_polarityFlip, NULL, 0); + break; + case channelPolarDump: + printChannelInfo(currentBoard, mpod_channelPolarFlipDumpAll,NULL); + break; + + case marginActivation: + setBitsChannel(currentBoard, mpod_marginActivation, mpod_isTX, 1); + break; + case marginDeactivation: + setBitsChannel(currentBoard, mpod_marginActivation, mpod_isTX, 0); + break; + case marginDump: + printChannelInfo(currentBoard, mpod_marginActDumpAll,mpod_isTX); + break; + + case squelchDisable: + setBitsChannel(currentBoard, mpod_squelchDisable, NULL, 1); + break; + case squelchEnable: + setBitsChannel(currentBoard, mpod_squelchDisable, NULL, 0); + break; + case squelchDump: + printChannelInfo(currentBoard, mpod_squelchDumpAll,NULL); + break; + + case vodRd: + read12Int(currentBoard, mpod_readVOD, mpod_readVODSingle, mpod_isRX); + break; + case vodWr: + write12Int(currentBoard, mpod_writeVOD, mpod_writeVODSingle, mpod_isRX); + break; + + case deamphasRd: + read12Int(currentBoard, mpod_readDeamphasis, mpod_readDeamphasisSingle, mpod_isRX); + break; + case deamphasWr: + write12Int(currentBoard, mpod_writeDeamphasis, mpod_writeDeamphasisSingle, mpod_isRX); + break; + + case equalRd: + read12Int(currentBoard, mpod_readEqualization, mpod_readEqualizationSingle, mpod_isTX); + break; + case equalWr: + write12Int(currentBoard, mpod_writeEqualization, mpod_writeEqualizationSingle, mpod_isTX); + break; + default: + printf("Should never happen the command requested is unknown\n"); + exit(0); + } // switch + + return(0); +} diff --git a/Pcie40Libraries/Makefile b/Pcie40Libraries/Makefile index fb6ff93..8969d64 100644 --- a/Pcie40Libraries/Makefile +++ b/Pcie40Libraries/Makefile @@ -21,7 +21,7 @@ ECS_SRC= pcie40_ecs.c ECS_OBJ=$(ECS_SRC:%.c=$(OBJ_DIR)%.o) #Minipods -MINIPODS_SRC= i2cDriver.c +MINIPODS_SRC= i2cDriver.c avagoMinipodCtrl.c MINIPODS_OBJ=$(MINIPODS_SRC:%.c=$(OBJ_DIR)%.o) #LTC2990 diff --git a/Pcie40Libraries/avagoMinipodCtrl.c b/Pcie40Libraries/avagoMinipodCtrl.c new file mode 100644 index 0000000..7921f89 --- /dev/null +++ b/Pcie40Libraries/avagoMinipodCtrl.c @@ -0,0 +1,2451 @@ +/****************************************************************************************//** +* \file avagoMinipodCtrl.c +* +* \brief This file contains the user driver to control the 6 AVAGO miniPOD of the AMC40 board. +* +* \author PYD : 17/4/2012 +* \version 0.1 +* \date 17/4/2012 +* \copyright (c) Copyright CERN for the benefit of the LHCb Collaboration. +* Distributed under the terms of the GNU General Public Licence V3. +* ana.py script is free and open source software. +* +* CHANGELOG +* PYD : 17/4/2012 initial version +* PYD : 12/6/2015 several i2c buses implemented +* PYD : 07/01/2016 adaptation for PCIe40 +* PYD : 15/09/2016 add multi boards +* PYD : 01/10/2018 remove code for ES12 and ES3 versions +*//********************************************************************************************/ +#include <stdio.h> +#include <string.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <stdlib.h> +#include <math.h> +#include <errno.h> +#include <sys/ioctl.h> +#include <unistd.h> +#include <linux/i2c-dev.h> +#include <systemConfig.h> +#include <i2cDriver.h> +#include <avagoMinipodCtrl.h> + + typedef struct { + int reg; + int quart; + } quartPlace; + /** + * \var mpod_vodQuarters + * \brief Channels are organized from 0 to 11. Data of channel X are at index X in the array. + * + * The channel data are: + * + * The register number : tab[chnId][0] + * + * The associated quarter : tab[chnId][1] (0 means low, 1 means high quarter) +*/ + +static quartPlace mpod_vodQuarters[12] = { + {MPOD_RXVOD1, 0},{MPOD_RXVOD1, 1},{MPOD_RXVOD2, 0},{MPOD_RXVOD2, 1},{MPOD_RXVOD3, 0},{MPOD_RXVOD3, 1}, + {MPOD_RXVOD4, 0},{MPOD_RXVOD4, 1},{MPOD_RXVOD5, 0},{MPOD_RXVOD5, 1},{MPOD_RXVOD6, 0},{MPOD_RXVOD6, 1} + }; + /** + * \var mpod_deamphQuarters + * \brief Channels are organized from 0 to 11. Data of channel X are at index X in the array. + * + * The channel data are: + * + * The register number : tab[chnId][0] + * + * The associated quarter : tab[chnId][1] (0 means low, 1 means high quarter) +*/ +static quartPlace mpod_deamphQuarters[12] = { + {MPOD_RXDEAMPH1, 0},{MPOD_RXDEAMPH1, 1},{MPOD_RXDEAMPH2, 0},{MPOD_RXDEAMPH2, 1},{MPOD_RXDEAMPH3, 0},{MPOD_RXDEAMPH3, 1}, + {MPOD_RXDEAMPH4, 0},{MPOD_RXDEAMPH4, 1},{MPOD_RXDEAMPH5, 0},{MPOD_RXDEAMPH5, 1},{MPOD_RXDEAMPH6, 0},{MPOD_RXDEAMPH6, 1} + }; + /** + * \var mpod_equalzQuarters + * \brief Channels are organized from 0 to 11. Data of channel X are at index X in the array. + * + * The channel data are: + * + * The register number : tab[chnId][0] + * + * The associated quarter : tab[chnId][1] (0 means low, 1 means high quarter) +*/ +static quartPlace mpod_equalzQuarters[12] = { + {MPOD_TXEQUALZ1, 0},{MPOD_TXEQUALZ1, 1},{MPOD_TXEQUALZ2, 0},{MPOD_TXEQUALZ2, 1},{MPOD_TXEQUALZ3, 0},{MPOD_TXEQUALZ3, 1}, + {MPOD_TXEQUALZ4, 0},{MPOD_TXEQUALZ4, 1},{MPOD_TXEQUALZ5, 0},{MPOD_TXEQUALZ5, 1},{MPOD_TXEQUALZ6, 0},{MPOD_TXEQUALZ6, 1} + }; +/** + * \var mpod_ampControlCodes + * \brief Receiver output Amplitude - Default De-Amphasis given in mVppd unit + * + * The they are 8 possible code values x = 0 to 7: + * + * For each code we have the Min value tab[x][0], Nominal value tab[x][1], Max Value tab[x][2] + * + * Note: another way to get the nominal value without this array is to compute (code+1)*100 +*/ +static unsigned mpod_ampControlCodes[][3] = { + { 70,100,130}, + {150,200,250}, + {240,300,360}, + {320,400,480}, + {400,500,600},/*default*/ + {480,600,720}, + {560,700,840}, + {640,800,960}/*full scale*/ + }; +/** + * \var mpod_equalizationCodes + * \brief Transmitter equalization control + * + * The they are 8 possible code values x = 0 to 7: + * + * For each code we have the Peak value tab[x][0], Midband value tab[x][1], Peak vs Midband Value tab[x][2] + * +*/ +static float mpod_equalizationCodes[][3] = { + {0.3 ,-0.1 ,0.4 }, + {1.3 ,-0.9 ,2.2 }, + {2.1 ,-1.8 ,3.9 }, + {3.05,-3.05,6.1 }, + {4.1 ,-4.7 ,8.8 }, + {5.0 ,-6.6 ,11.6}, + {5.6 ,-8.3 ,13.9}, + {6.1 ,-10.6,16.7} + }; +/* CHECK HOW THE READ WRITE BIT IS MANAGED IN THE DRIVER +# For TX the address is 0101hjkx (hjk is hard add) (x is 1=R 0=W) +# For RX the address is 0110hjkx (hjk is hard add) (x is 1=R 0=W) +# NOTE the x is added in Read/Write function into the driver so don't use it here +# partern 0 + 0101/TX or 0110/RX + fixAdd on 3digits + +minipod devices devices addresses */ +/** + * \var mpod_devAdd + * \brief The i2c addresses of the 8 channels controlers. + * +*/ +static unsigned mpod_devAdd[8] = { +/* FR + 0x30, //!<sRX GBT add(0) 0b 0011 0000 + 0x2a, //!<sTX GBT add(1) 0b 0010 1010 + 0x31, //!<sRX GBT add(2) 0b 0011 0001 + 0x2b, //!<sTX GBT add(3) 0b 0010 1011 + 0x32, //!<sRX GBT add(4) 0b 0011 0010 + 0x2c, //!<sTX Gbe add(5) 0b 0010 1100 + 0x33, //!<sRX Gbe add(6) 0b 0011 0011 + 0x2d, //!<sTX Gbe add(7) 0b 0010 1101 +*/ +/* MJ */ + 0x30, //!<sRX GBT add(0) 0b 0011 0000 + 0x28, //!<sTX GBT add(1) 0b 0010 1000 + 0x31, //!<sRX GBT add(2) 0b 0011 0001 + 0x29, //!<sTX GBT add(3) 0b 0010 1001 + 0x32, //!<sRX GBT add(4) 0b 0011 0010 + 0x2a, //!<sTX Gbe add(5) 0b 0010 1010 + 0x33, //!<sRX Gbe add(6) 0b 0011 0011 + 0x2b, //!<sTX Gbe add(7) 0b 0010 1011 +}; + +static int mpod_rx[8] = {1, 0, 1, 0, 1, 0, 1, 0}; +static int mpod_tx[8] = {0, 1, 0, 1, 0, 1, 0, 1}; + +static int mpod_scriptMode = 0; // mode of printing: 0 for human users else for script scanning +static int mpod_hideText = 0; + +/***********************************************************************//** + * \fn int mpod_setMode() + * \brief Function to set the mode in which the data will be formatted on stdout. + * + * By default the mode is 0 fir human typing the command in a system console. + * Comments and pretty printings are used to make it easy for a human user + * to read the command results. + * In the other mode the results are output in a minimalist comma separated values + * which can be easily scanned by a scripting program. + * + * \param mode: 0 human oriented, other for script scanning + *//***********************************************************************/ + int mpod_setMode(int mode){ + mpod_scriptMode=mode; + return(0); + } + + int mpod_setTextMode(int mode){ + mpod_hideText=mode; + return(0); + } + +/***********************************************************************//** + * \fn int mpod_init(int dev) + * \brief Function to init the avago i2c bus. + * This function has to be done before any i2c access to minipods + * + * Function to program the prescale the SCL clock line. Should be called + * before the I2C use. + * + * \param inCLK: the input system clock ferquency in Hz + * \param SCLfreq: the target SCL clock frequency in Hz + * \return 0 success, -1 error + *//***********************************************************************/ +int mpod_init(int dev, unsigned inCLK, unsigned SCLfreq){ + return( i2c_init(dev, I2C_BUS_MINIPODS, inCLK, SCLfreq) ); +} +/***********************************************************************//** + * \fn void mpod_getInit(int dev) + * \brief Reads the last values in the prescale of the SCL clock line. + * + * + * \param inCLK: the system clock ferquency in Hz + * \param SCLfreq: the target SCL clock frequency in Hz + *//***********************************************************************/ +void mpod_getInit(int dev, unsigned *inCLK, unsigned *SCLfreq){ + i2c_getInit(dev, I2C_BUS_MINIPODS, inCLK, SCLfreq); +} +/**************************************************************************//** + * \fn int mpod_exist(int mpid) + * \brief Function to check if the given minipod exists + * + * \param mpid : the minipod number 0-7 + * \return 0 no, 1 yes + *//**************************************************************************/ +int mpod_exists(int mpid){ + if ((mpid<0) || (mpid>7)){ + printf("ERROR: minipod munber %d is not between 0 and 7\n",mpid); + return(0); + } +return 1; +} +/**************************************************************************//** + * \fn int mpod_add(int mpid, unsigned *add) + * \brief Function to get the I2C address of a given minipod + * + * \param mpid : the minipod number 0-7 + * \param add : a pointer where to get the adress + * \return 0 success, -1 error + *//**************************************************************************/ +static int mpod_add(int mpid, unsigned *add){ + if (!mpod_exists(mpid)) + return(-1); + *add = mpod_devAdd[mpid]; +return 0; +} +/**************************************************************************//** + * \fn int mpod_isTX(int mpid) + * \brief Function to test if a minipod is a transmitter + * + * \param mpid : the minipod number 0-7 + * \return 1=yes, 0=no + *//**************************************************************************/ +int mpod_isTX(int mpid){ + if (!mpod_exists(mpid)) + return(-1); +return(mpod_tx[mpid]); +} +/**************************************************************************//** + * \fn int mpod_isRX(int mpid) + * \brief Function to test if a minipod is a receiver + * + * \param mpid : the minipod number 0-7 + * \return 1=yes, 0=no + *//**************************************************************************/ +int mpod_isRX(int mpid){ + if (!mpod_exists(mpid)) + return(-1); +return(mpod_rx[mpid]); +} +/*********************************************************************//** + * \fn int mpod_write(int dev, int mpid, char reg, unsigned val) + * \brief Function to write val at register reg in minipod number mpid + * + * \param mpid: the target minipod + * \param reg: the device register + * \param val: the value to write (4bytes) + * \return 0 success, -1 error + *//*********************************************************************/ +int mpod_write(int dev, int mpid, char reg, unsigned val){ + unsigned add; + int ret; + + if(mpod_add(mpid, &add)!=0) + return(-1); + + ret = i2c_writeMem(dev, I2C_BUS_MINIPODS, add, reg, &val); + usleep(10000); // not clean but tested as usefull + return (ret); +} +/******************************************************//** + * \fn int mpod_read(int dev, int mpid, char reg, unsigned *val) + * \brief Function to read register reg and get value in val + * + * \param mpid: the target minipod + * \param reg: the device register + * \param val: a ptr to a word to receive the value(4bytes) + * \return 0 success, -1 error + *//******************************************************/ +int mpod_read(int dev, int mpid, char reg, unsigned *val){ + unsigned add; + + if(mpod_add(mpid, &add)!=0) + return(-1); + + return( i2c_readMem(dev, I2C_BUS_MINIPODS, add, reg, val) ); +} +/********************************************************************//** + * \fn int mpod_readBloc(int dev, int file , int index , int nb, unsigned *data) + * \brief Function to select the used memory page + * + * This function malloc the space to put the data in. The user should + * free it after use. + * + * \param mpid : the target minipod number 0 to 7 + * \param index: the start register index + * \param nb: the number of registers to read + * \param data: a pointer to an array to receive the read values + * \return 0 success, -1 error + *//********************************************************************/ +int mpod_readBloc(int dev, int mpid , int index , int nb , unsigned **data){ + unsigned add; + + if(mpod_add(mpid, &add)!=0) + return(-1); +// printf("PYD read on bus %d at add 0x%x reg index %d for %d words\n",I2C_BUS_Minipod, add, index, nb); + return( i2c_multReadMem(dev, I2C_BUS_MINIPODS, add, index, nb, data) ); +} +/******************************************************//** + * \fn int mpod_pageSelect(int dev, int mpid, int page) + * \brief Function to select the used memory page + * + * \param mpid: the target minipod + * \param page: the selected page id (0 or 1) + * \return 0 success, -1 error + *//******************************************************/ +int mpod_pageSelect(int dev, int mpid , unsigned page) { + unsigned val; + if ((page<0) || (page >1)){ + printf("ERROR: MPOD page number should be 0 or 1 not %d\n", page); + return(-1); + } + // read the current value +// printf("Setting page %d for minipod %d\n", page, mpid); + mpod_write(dev, mpid, MPOD_PAGEREG, page); + mpod_read(dev, mpid, MPOD_PAGEREG, &val); + if (val!=page){ + printf("ERROR: page selection on mpod %d failed\n", mpid); + return(-1); + } +// printf("Current page is now %d for minipod %d\n",val, mpid); + return(0); +} +/*****************************************************************************************//** + * \fn int mpod_get12IntData(int(*get)(int,int**), int mpid, int *data) + * \brief Function to wrap other functions to get the 12 channels data of a minipod in python + * + * Function to avoid to have to manage dynamically allocated arrays in the python wrapper. + * used for getVOD, getDeamphasis, getEqualization + * + * \param mpid: the target RX minipod component 0, 2, 4 and 6 (RX) + * \param data: a pointer to an already allocated array of 12 code values + * (chn 0 to 11) that the user will have to freed after use. + * \return 0 success, -1 error + *//****************************************************************************************/ +static int mpod_get12IntData(int dev,int(*get)(int,int,int**),int mpid, int *data){ + int *bloc; + int i, status; + status = get(dev,mpid, &bloc); + if (status==0){ + + for (i=0; i<12; i++) + data[i]=bloc[i]; + free(bloc); + } + return(status); +} +/*****************************************************************************************//** + * \fn int mpod_get12FloatData(int(*get)(int,float**), int mpid, float *data) + * \brief Function to wrap other functions to get the 12 channels data of a minipod in python + * + * Function to avoid to have to manage dynamically allocated arrays in the python wrapper. + * used for biasCurrent, lightOutput, lightInput + * + * \param mpid: the target RX minipod component 0, 2, 4 and 6 (RX) + * \param data: a pointer to an already allocated array of 12 code values + * (chn 0 to 11) that the user will have to freed after use. + * \return 0 success, -1 error + *//****************************************************************************************/ +static int mpod_get12FloatData(int dev, int(*get)(int,int,float**),int mpid, float *data){ + float *bloc; + int i, status; + status = get(dev, mpid, &bloc); + if (status==0){ + for (i=0; i<12; i++) + data[i]=bloc[i]; + free(bloc); + } + return(status); +} +/*****************************************************************************************//** + * \fn int mpod_setBitIn12bitsOn2words (int dev, int mpid, int channel, int flag + unsigned word1, unsigned word2, + char *regMsg, + (int)(*filter)(int)) + * \brief Function to set or unset a bit for a channel in a representation spanning on + * 2 contiguous 8 bits registers. + * + * \param mpid : the target minipod component 0 to 5 + * \param channel: the target channel 0 to 12 + * \param flag : 0=enable 1=disable + * \param word1 : low number register with bits for channels 8 to 11 + * \param word2 : high number register with bits for channels 0 to 7 + * \param regMsg : string identifying the register function + * \param filter : filtering function for the type of minipod + * \return 0 success, -1 error + *//****************************************************************************************/ +static int mpod_setBitIn12bitsOn2words(int dev, int mpid, int channel, int flag, + unsigned word1, unsigned word2, + char *regMsg, + int(*filter)(int) ){ +int shift; +unsigned reg, cval, val; + +if (filter) + if (!filter(mpid)){ + printf("ERROR: %s only for TX minipods\n", regMsg); + return(-1); + } + if (channel<8){ + reg = word2; + shift = channel; + } + else if (channel<=12) { + reg = word1; + shift = channel - 8; + } + else { + printf("ERROR : channel should be in <0-11>\n"); + return(-1); + } + mpod_read(dev, mpid, reg, &cval); + if (flag){ //disable + val = cval | (1<<shift); + if (mpod_write(dev, mpid, reg, val)){ + printf("ERROR: can't %s for channel %d in minipod %d board %d\n", regMsg, channel, mpid, dev); + return(-1); + } + } + else { //enable + val = cval & ~(1<<shift); + if (mpod_write(dev, mpid, reg, val)){ + printf("ERROR: can't %s for channel %d in minipod %d board %d\n", regMsg, channel, mpid, dev); + return(-1); + } + } +return(0); +} +/*****************************************************************************************//** + * \fn int mpod_dumpAllBitsIn12bitsOn2words (int dev, int mpid, + unsigned word1, unsigned word2, + char *regMsg, + (int)(*filter)(int)) + * \brief Function to dump all values coded as 1 bits per channel in 2 contiguous 8 bits registers. + * + * \param mpid : the target minipod component 0 to 7 + * \param word1 : low number register with bits for channels 8 to 11 + * \param word2 : high number register with bits for channels 0 to 7 + * \param regName: string identifying the register function + * \param filter : filtering function for the type of minipod + * \param no : character for 0 + * \param yes : character for 1 + * \return 0 success, -1 error + *//****************************************************************************************/ +static int mpod_dumpAllBitIn12bitsOn2words(int dev, int mpid, + unsigned word1, unsigned word2, + char *regName, + int(*filter)(int), + char no, char yes ){ + unsigned val; + int ch; + + if (filter) + if (filter(mpid)){ + printf("ERROR: %s registers not available for this type of minipod\n", regName); + return(0); + } + if (!mpod_scriptMode){ + for (ch=0; ch<12; ch++) printf("---"); + printf("\n"); + printf("minipod %d %s\n", mpid, regName); + for (ch=0; ch<12; ch++) printf("---"); + printf("\n"); + for (ch=0; ch<12; ch++) printf("%2d ",ch); + printf("\n"); + for (ch=0; ch<12; ch++) printf("---"); + printf("\n"); + } + if (mpod_read(dev, mpid, word2, &val )){ + printf("ERROR: MPOD can't read %s register 2 on i2c bus\n", regName); + return(-1); + } + if (!mpod_scriptMode){ + for (ch=0; ch<8; ch++){ + if ( (val & (1<<ch)) != 0 ) printf(" %c ",yes); + else printf(" %c ",no); + } + } else { + for (ch=0; ch<8; ch++){ + if ( (val & (1<<ch)) != 0 ) printf("%c,",yes); + else printf("%c,",no); + } + } + if (mpod_read(dev, mpid, word1, &val )){ + printf("ERROR: MPOD can't read %s register 1 on i2c bus\n", regName); + return(-1); + } + if (!mpod_scriptMode){ + for (ch=8; ch<12; ch++){ + if ( (val & (1<<(ch-8))) != 0 ) printf(" %c ",yes); + else printf(" %c ",no); + } + } else { + for (ch=8; ch<12; ch++){ + if ( (val & (1<<(ch-8))) != 0 ) ch==11 ? printf("%c",yes): printf("%c,",yes); + else ch==11 ? printf("%c",no): printf("%c,",no); + } + } + printf("\n"); + if (!mpod_scriptMode){ + for (ch=0; ch<12; ch++) printf("---"); + printf("\n"); + } + return(0); +} + +/*****************************************************************************************//** + * \fn int mpod_mkListBitsIn12bitsOn2words (int dev, int mpid, + unsigned word1, unsigned word2, + char *regName, + (int)(*filter)(int), + char no, + char yes, + char **data) + * \brief Function to list all values coded as 1 bits per channel in 2 contiguous 8 bits registers. + * + * The first register has 8 bits and the second 4 bits. + * + * This function is used by the python wrapper + * + * \param mpid : the target minipod component 0 to 7 + * \param word1 : low number register with bits for channels 8 to 11 + * \param word2 : high number register with bits for channels 0 to 7 + * \param filter : filtering function for the type of minipod + * \param no : character for 0 + * \param yes : character for 1 + * \param data : the comma separated values in a string allocated by this function that should be freed + * \return 0 success, -1 error + *//****************************************************************************************/ +static int mpod_mkListBitIn12bitsOn2words(int dev, int mpid, + unsigned word1, unsigned word2, + char *regName, + int(*filter)(int), + char no, char yes, + char **data ){ + unsigned val; + int ch; + char *str; + + // Allocate the memory to make a string + if (!(str = malloc(50))) { // 12 value with , except last followed by \n + printf("ERROR: Can't malloc memory for 12 comma separated values\n"); + return(-1); + } + for (ch=0; ch<50; ch++) + str[ch] = '\n'; + + if (filter) + if (filter(mpid)){ + printf("ERROR: %s registers not available for this type of minipod\n", regName); + return(0); + } + if (mpod_read(dev, mpid, word2, &val )){ + printf("ERROR: MPOD can't read %s register 2 on i2c bus\n", regName); + return(-1); + } + for (ch=0; ch<8; ch++){ + if ( (val & (1<<ch)) != 0 ) { + sprintf(str+2*ch,"%c,",yes); + } + else{ + sprintf(str+2*ch,"%c,",no); + } + } + if (mpod_read(dev, mpid, word1, &val )){ + printf("ERROR: MPOD can't read %s register 1 on i2c bus\n", regName); + return(-1); + } + for (ch=8; ch<12; ch++){ + if ( (val & (1<<(ch-8))) != 0 ) { + if (ch == 11){ + sprintf(str+2*ch,"%c",yes); + } + else { + sprintf(str+2*ch,"%c,",yes); + } + } + else { + if (ch == 11){ + sprintf(str+2*ch,"%c",no); + } + + else { + sprintf(str+2*ch,"%c,",no); + } + } + } + *data = str; + return(0); +} +/********************************************************************//** + * \fn int mpod_getVendorName(int dev, int mpid , char **bloc) + * \brief Function read the vendor name from register 152 to 167 + * + * \param mpid : the target minipod component 0 to 7 + * \param bloc : a pointer to an array to receive the read values + * The bloc is allocated by the function and should be freed + * by the user + * \return 0 success, -1 error + *//********************************************************************/ +int mpod_getVendorName(int dev, int mpid, char **bloc){ + int i; + char *chdata; // allocated here tp make conversion from unsigned to char + unsigned *data; // will be allocated by the called function + int size = MPOD_NBVENDORNAME+1; + + // Allocate the memory to make a string + if (!(chdata = malloc(size+1))) { + printf("ERROR: Can't malloc memory for vendor data\n"); + return(-1); + } + // get data + if ( mpod_readBloc(dev, mpid , MPOD_VENDORNAMEREG , size , &data )!=0){ + printf("ERROR: MPOD can't read vendor name on i2c bus\n"); + return(-1); + } + + for (i=0; i<MPOD_NBVENDORNAME; i++){ + chdata[i] = (char)data[i]; + } + + chdata[i]='\0'; + free(data); + *bloc = chdata; + return(0); +} +/********************************************************************//** + * \fn int mpod_getVendorOUI(int dev, int mpid , char **bloc) + * \brief Function read the vendor OUIom register 168 to 170 + * + * Attention: the characters returned are not printable but values + * to print as hexa digits to be interpreted. + * + * \param mpid : the target minipod component 0 to 7 + * \param bloc : a pointer to an array to receive the read values + * The bloc is allocated by the function and should be freed + * by the user + * \return 0 success, -1 error + *//********************************************************************/ +int mpod_getVendorOUI(int dev, int mpid, char **bloc){ + int i; + char *chdata; // allocated here tp make conversion from unsigned to char + unsigned *data; // will be allocated by the called function + int size = MPOD_NBVENDOROUI+1; + + // Allocate the memory to make a string + if (!(chdata = malloc(size+1))) { + printf("ERROR: Can't malloc memory for vendor OUI data\n"); + return(-1); + } + // get data + if ( mpod_readBloc(dev, mpid , MPOD_VENDOROUIREG , size , &data )!=0){ + printf("ERROR: MPOD can't read vendor OUI on i2c bus\n"); + return(-1); + } + for (i=0; i<MPOD_NBVENDOROUI; i++){ + chdata[i] = (char)data[i]; + } + free(data); + *bloc = chdata; + return(0); +} +/********************************************************************//** + * \fn int mpod_getVendorPartNumber(int dev, int mpid , char **bloc) + * \brief Function read the vendor part number from register 171 to 186 + * + * \param mpid : the target minipod component 0 to 7 + * \param bloc : a pointer to an array to receive the read values + * The bloc is allocated by the function and should be freed + * by the user + * \return 0 success, -1 error + *//********************************************************************/ +int mpod_getVendorPartNumber(int dev, int mpid, char **bloc){ + int i; + char *chdata; // allocated here tp make conversion from unsigned to char + unsigned *data; // will be allocated by the called function + int size = MPOD_NBVENDORPART+1; + + // Allocate the memory to make a string + if (!(chdata = malloc(size+1))) { + printf("ERROR: Can't malloc memory for vendor part number data\n"); + return(-1); + } + // get data + if ( mpod_readBloc(dev, mpid , MPOD_VENDORPARTREG , size , &data )!=0){ + printf("ERROR: MPOD can't read vendor part number on i2c bus\n"); + return(-1); + } + for (i=0; i<MPOD_NBVENDORPART; i++){ + chdata[i] = (char)data[i]; + } + chdata[i]='\0'; + free(data); + *bloc = chdata; + return(0); +} +/********************************************************************//** + * \fn int mpod_getVendorRevNumber(int dev, int mpid , char **bloc) + * \brief Function read the revision number from register 187 to 188 + * + * \param mpid : the target minipod component 0 to 7 + * \param bloc : a pointer to an array to receive the read values + * The bloc is allocated by the function and should be freed + * by the user + * \return 0 success, -1 error + *//********************************************************************/ +int mpod_getVendorRevNumber(int dev, int mpid, char **bloc){ + int i; + char *chdata; // allocated here tp make conversion from unsigned to char + unsigned *data; // will be allocated by the called function + int size = MPOD_NBVENDORREV+1; + + // Allocate the memory to make a string + if (!(chdata = malloc(size+1))) { + printf("ERROR: Can't malloc memory for vendor revision number data\n"); + return(-1); + } + // get data + if ( mpod_readBloc(dev, mpid , MPOD_VENDORREVREG , size , &data )!=0){ + printf("ERROR: MPOD can't read vendor revision number on i2c bus\n"); + return(-1); + } + for (i=0; i<MPOD_NBVENDORREV; i++){ + chdata[i] = (char)data[i]; + } + chdata[i]='\0'; + free(data); + *bloc = chdata; + return(0); +} +/********************************************************************//** + * \fn int mpod_getVendorSerialNumber(int dev, int mpid , char **bloc) + * \brief Function read the vendor serial number from register 189 to 204 + * + * \param mpid : the target minipod component 0 to 7 + * \param bloc : a pointer to an array to receive the read values + * The bloc is allocated by the function and should be freed + * by the user + * \return 0 success, -1 error + *//********************************************************************/ +int mpod_getVendorSerialNumber(int dev, int mpid, char **bloc){ + int i; + char *chdata; // allocated here tp make conversion from unsigned to char + unsigned *data; // will be allocated by the called function + int size = MPOD_NBVENDORSER+1; + + // Allocate the memory to make a string + if (!(chdata = malloc(size+1))) { + printf("ERROR: Can't malloc memory for vendor serial number data\n"); + return(-1); + } + // get data + if ( mpod_readBloc(dev, mpid , MPOD_VENDORSERREG , size , &data )!=0){ + printf("ERROR: MPOD can't read vendor serial number on i2c bus\n"); + return(-1); + } + for (i=0; i<MPOD_NBVENDORSER; i++){ + chdata[i] = (char)data[i]; + } + chdata[i]='\0'; + free(data); + *bloc = chdata; + return(0); +} +/********************************************************************//** + * \fn int mpod_getVendorDate(int dev, int mpid , char **bloc) + * \brief Function read the vendor date from register 205 to 212 + * + * \param mpid : the target minipod component 0 to 7 + * \param bloc : a pointer to an array to receive the read values + * The bloc is allocated by the function and should be freed + * by the user + * \return 0 success, -1 error + *//********************************************************************/ +int mpod_getVendorDate(int dev, int mpid, char **bloc){ + int i; + char *chdata; // allocated here tp make conversion from unsigned to char + unsigned *data; // will be allocated by the called function + int size = MPOD_NBVENDORDATE+1; + + // Allocate the memory to make a string + if (!(chdata = malloc(size+1))) { + printf("ERROR: Can't malloc memory for vendor date data\n"); + return(-1); + } + // get data + if ( mpod_readBloc(dev, mpid , MPOD_VENDORDATEREG , size , &data )!=0){ + printf("ERROR: MPOD can't read vendor date on i2c bus\n"); + return(-1); + } + for (i=0; i<MPOD_NBVENDORDATE; i++){ + chdata[i] = (char)data[i]; + } + chdata[i]='\0'; + free(data); + *bloc = chdata; + return(0); +} +/********************************************************************//** + * \fn int mpod_dumpVendorData(int dev, int mpid) + * \brief Function print the vendor data of a minipod + * + * \param mpid : the target minipod component 0 to 7 + * \return 0 success, -1 error + *//********************************************************************/ +int mpod_dumpVendorData(int dev, int mpid){ + int i; + char *bloc; + + if (!mpod_scriptMode){ + printf("----------------------\n"); + printf("minipod %d vendor data\n", mpid); + printf("----------------------\n"); + }; + if (mpod_getVendorName(dev, mpid, &bloc)==-1) return(-1); + else { + printf("vendor name :%s\n", bloc); + free(bloc); + } + if (mpod_getVendorOUI(dev, mpid, &bloc)==-1) return(-1); + else { + printf("vendor OUI :"); + for (i=0; i<MPOD_NBVENDOROUI; i++) + printf("0x%02xh ",bloc[i]); + printf("\n"); + free(bloc); + } + if (mpod_getVendorPartNumber(dev, mpid, &bloc)==-1) return(-1); + else { + printf("part number :%s\n", bloc); + free(bloc); + } + if (mpod_getVendorRevNumber(dev, mpid, &bloc)==-1) return(-1); + else { + printf("revision number :%s\n", bloc); + free(bloc); + } + if (mpod_getVendorSerialNumber(dev, mpid, &bloc)==-1) return(-1); + else { + printf("serial number :%s\n", bloc); + free(bloc); + } + if (mpod_getVendorDate(dev, mpid, &bloc)==-1) return(-1); + else { + printf("date :%s\n", bloc); + free(bloc); + } + return(0); +} +/********************************************************************//** + * \fn int mpod_getVendorData(int dev, int mpid) + * \brief Function to get a string with the vendor data of a minipod + * + * Function used in the python wrapper + * + * \param mpid : the target minipod component 0 to 7 + * \param data : the vendor data's string allocated here that should be + * \param by the caller + * \return 0 success, -1 error + *//********************************************************************/ +int mpod_getVendorData(int dev, int mpid, char **data){ + int i; + char *bloc; + char *str; + + if ((str = malloc(1000))==0){ + printf("ERROR: Can't malloc memory to build the vendor data info string\n"); + return(-1); + } + sprintf(str+strlen(str),"minipod:%d,", mpid); + if (mpod_getVendorName(dev, mpid, &bloc)==-1) return(-1); + else { + sprintf(str+strlen(str),"vendor-name:%s,", bloc); + free(bloc); + } + if (mpod_getVendorOUI(dev, mpid, &bloc)==-1) return(-1); + else { + sprintf(str+strlen(str),"vendor-OUI:"); + for (i=0; i<MPOD_NBVENDOROUI; i++) + sprintf(str+strlen(str),"0x%02xh ",bloc[i]); + sprintf(str+strlen(str),","); + free(bloc); + } + if (mpod_getVendorPartNumber(dev, mpid, &bloc)==-1) return(-1); + else { + sprintf(str+strlen(str),"part-number:%s,", bloc); + free(bloc); + } + if (mpod_getVendorRevNumber(dev, mpid, &bloc)==-1) return(-1); + else { + sprintf(str+strlen(str),str+strlen(str),"revision-number:%s,", bloc); + free(bloc); + } + if (mpod_getVendorSerialNumber(dev, mpid, &bloc)==-1) return(-1); + else { + sprintf(str+strlen(str),"serial-number:%s,", bloc); + free(bloc); + } + if (mpod_getVendorDate(dev, mpid, &bloc)==-1) return(-1); + else { + sprintf(str+strlen(str),"date:%s", bloc); + free(bloc); + } + *data = str; + return(0); +} +/*********************************************************************************//** + * \fn int mpod_squelchDisable(int dev, int mpid , int channel , int disable) + * \brief Function to disable/enable squelch on one channel of a component + * + * \param mpid : the target minipod component 0 to 7 + * \param channel: the channel number 0-11 + * \param disable: the flag 1=disable 0=enable + * \return 0 success, -1 error + *//*********************************************************************************/ +int mpod_squelchDisable(int dev, int mpid , int channel , int disable){ + +char regMsg[]="squelch disable"; +return (mpod_setBitIn12bitsOn2words(dev, mpid, + channel, + disable, + MPOD_SQUELCHREG1, + MPOD_SQUELCHREG2, + regMsg, + NULL)); +} +/*********************************************************************************//** + * \fn int mpod_squelchDisableAll(int dev, int mpid , int disable) + * \brief Function to disable/enable squelch on all channels of a component + * + * \param mpid : the target minipod component 0 to 7 + * \param disable: the flag 1=disable 0=enable + * \return 0 success, -1 error + *//*********************************************************************************/ +int mpod_squelchDisableAll(int dev, int mpid, int disable){ + int mask; + if (disable){ + printf("Switching squelch to OFF on ALL channels of component %d\n", mpid); + mask = 0xff; + if (mpod_write(dev, mpid, MPOD_SQUELCHREG2, mask)){ + printf("ERROR: MPOD can't write squelch register on i2c bus\n"); + return(-1); + }; + mpod_write(dev, mpid, MPOD_SQUELCHREG1, mask); /*also write useless high quarter doesn't harm*/ + } else { + printf("Switching squelch to ON on ALL channels of component %d\n", mpid); + mask = 0x0; + if (mpod_write(dev, mpid, MPOD_SQUELCHREG2, mask)){ + printf("ERROR: MPOD can't write squelch register on i2c bus\n"); + return(-1); + }; + mpod_write(dev, mpid, MPOD_SQUELCHREG1, mask); /*also write useless high quarter doesn't harm*/ + } + return(0); +} +/*********************************************************************************//** + * \fn int mpod_squelchDumpAll(int dev, int mpid) + * \brief Function to dump the value of squelch enabled status for all channels + * + * \param mpid: the target minipod component 0 to 7 + * \return 0 success, -1 error + *//*********************************************************************************/ +int mpod_squelchDumpAll(int dev, int mpid){ +char regName[]="Squelch enable/disable"; + +return mpod_dumpAllBitIn12bitsOn2words(dev, mpid, + MPOD_SQUELCHREG1, MPOD_SQUELCHREG2, + regName, + NULL, + 'e','d'); +} +/*********************************************************************************//** + * \fn int mpod_dumpErrStatusValues(int dev, int mpid) + * \brief Function to dump the data not ready, int, los and faul status of one minipod + * + * \param mpid: the target minipod component 0 to 7 + * \return 0 success, -1 error + *//*********************************************************************************/ +static int mpod_dumpErrStatusValues(int dev, int mpid){ +unsigned val; + if (mpod_read(dev, mpid, MPOD_ERRORSTAT, &val )){ + printf("ERROR: MPOD can't read error status register on i2c bus\n"); + return(-1); + } + if (!mpod_scriptMode){ + if (mpod_isTX(mpid)) + printf("! %d ! %d ! %d ! %d ! %d !\n", mpid, 3>(val&0x8), 2>(val&0x4), 1>(val&0x2), val&01); + else + printf("! %d ! * ! %d ! %d ! %d !\n", mpid, 2>(val&0x4), 1>(val&0x2), val&01); + } else { + if (mpod_isTX(mpid)) + printf("%d,%d,%d,%d,%d\n", mpid, 3>(val&0x8), 2>(val&0x4), 1>(val&0x2), val&01); + else + printf("%d,*,%d,%d,%d\n", mpid, 2>(val&0x4), 1>(val&0x2), val&01); + } + + return 0; +} +/*********************************************************************************//** + * \fn int mpod_getErrStatus(int dev, int mpid, char **data) + * \brief Function to get the data not ready,int,los and faul status of one minipod + * + * Function used by the python wrapper + * \param mpid: the target minipod component 0 to 7 + * \return 0 success, -1 error + *//*********************************************************************************/ +int mpod_getErrStatus(int dev, int mpid, char **data){ +unsigned val; +char *str; + if ((str = malloc(100))==0){ + printf("ERROR: Can't malloc memory to build the error status info string\n"); + return(-1); + } + if (mpod_read(dev, mpid, MPOD_ERRORSTAT, &val )){ + printf("ERROR: MPOD can't read error status register on i2c bus\n"); + return(-1); + } + if (mpod_isTX(mpid)) + sprintf(str,"fault:%d,los:%d,intL:%d,data-not-ready:%d\n", 3>(val&0x8), 2>(val&0x4), 1>(val&0x2), val&01); + else + sprintf(str,"fault:*,los:%d,intL:%d,data-not-ready:%d\n", 2>(val&0x4), 1>(val&0x2), val&01); + *data = str; + return(0); +} +/*********************************************************************************//** + * \fn int mpod_dumpErrStatus(int dev, int mpid) + * \brief Function to dump the data not ready, int, los and faul status of one minipod + * + * \param mpid: the target minipod component 0 to 7 + * \return 0 success, -1 error + *//*********************************************************************************/ +int mpod_dumpErrStatus(int dev, int mpid){ + if (!mpod_scriptMode){ + printf("minipod %d error status\n", mpid); + printf("!-------------------------------------------!\n"); + printf("! MPOD ! FAULT ! LOS ! INT ! DATA NOT READY !\n"); + printf("!-------------------------------------------!\n"); + } + mpod_dumpErrStatusValues(dev, mpid); + if (!mpod_scriptMode) + printf("!-------------------------------------------!\n"); +return(0); +} +/*********************************************************************************//** + * \fn int mpod_dumpErrStatusAll(int dev) + * \brief Function to dump the data not ready, int, los and faul status of all minipods + * + * \return 0 success, -1 error + *//*********************************************************************************/ +int mpod_dumpErrStatusAll(int dev){ +int mpid; + if (!mpod_scriptMode){ + printf("minipod all error status\n"); + printf("!-------------------------------------------!\n"); + printf("! MPOD ! FAULT ! LOS ! INT ! DATA NOT READY !\n"); + printf("!-------------------------------------------!\n"); + } + for (mpid=0; mpid<=7; mpid++){ + mpod_dumpErrStatusValues(dev, mpid); + } + if (!mpod_scriptMode) + printf("!-------------------------------------------!\n"); +return(0); +} +/*********************************************************************************//** + * \fn int mpod_losDumpAll(int dev, int mpid) + * \brief Function to dump the los status for all channels of one minipod + * + * \param mpid: the target minipod component 0 to 7 + * \return 0 success, -1 error + *//*********************************************************************************/ +int mpod_losDumpAll(int dev, int mpid){ +char regName[]="Loss of signal"; + +return mpod_dumpAllBitIn12bitsOn2words(dev, mpid, + MPOD_LOSREG1, MPOD_LOSREG2, + regName, + NULL, + '0','1'); +} +/*********************************************************************************//** + * \fn int mpod_losListAll(int dev, int mpid, char **data) + * \brief Function to make a list of the the los status for all channels of one minipod + * + * Attention bits should be reordered for 0 to 11 + * Function used by the python wrapper + * + * \param mpid: the target minipod component 0 to 7 + * \return 0 success, -1 error + *//*********************************************************************************/ +int mpod_losListAll(int dev, int mpid, char **data){ +char regName[]="Loss of signal"; +int status; + +// attention clear on read register +status = mpod_mkListBitIn12bitsOn2words(dev, mpid, + MPOD_LOSREG1, MPOD_LOSREG2, + regName, + NULL, + '0','1', + data ); +printf("Loss of signal :%s\n", *data); + +return status; +} +/*********************************************************************************//** + * \fn int mpod_fualtDumpAll(int dev, int mpid) + * \brief Function to dump the fault status for all channels of one TX minipod + * + * \param mpid: the target minipod component 0 to 7 + * \return 0 success, -1 error + *//*********************************************************************************/ +int mpod_faultDumpAll(int dev, int mpid){ +char regName[]="Faults"; + +return mpod_dumpAllBitIn12bitsOn2words(dev, mpid, + MPOD_FAULTREG1, MPOD_FAULTREG2, + regName, + mpod_isRX, + '0','1'); +} +/*********************************************************************************//** + * \fn int mpod_internalTemp(int dev, int mpid, int *temp) + * \brief Function to get the temperature value of one minipod + * + * \param mpid: the target minipod component 0 to 7 + * \param temp: a pointer to the variable to receive the temperature + * \return 0 success, -1 error + *//*********************************************************************************/ +int mpod_internalTemp(int dev, int mpid, int *temp){ + unsigned valh; + + // only use the higher temp at +- 3°C + if (mpod_read(dev, mpid , MPOD_INTEMPMSB , &valh )){ + printf("ERROR: MPOD can't read the internal temperature register on i2c bus\n"); + return(-1); + } + *temp = valh; + if (mpod_hideText); + else if (mpod_scriptMode) + printf("%d,",*temp); + else + printf("minipod %d internal temperature %dC\n",mpid, *temp); + +// printf("Internal temperature of minipod %d is %d°C\n", mpid, *temp); + return(0); +} +/*********************************************************************************//** + * \fn int mpod_internalTempDumpAll(int dev) + * \brief Function to print the temperatures value of all minipods + * + * \param mpid: the target minipod component 0 to 7 + * \param temp: a pointer to the variable to receive the temperature + * \return 0 success, -1 error + *//*********************************************************************************/ +int mpod_internalTempDumpAll(int dev){ + int i, temp; + for (i=0; i<8; i++){ + mpod_internalTemp(dev, i, &temp); + } + return(0); +} +/*********************************************************************************//** + * \fn int mpod_internal33Vcc(int dev, int mpid, int *vcc) + * \brief Function to get the 3.3 vCC value of one minipod + * + * \param mpid: the target minipod component 0 to 7 + * \param vcc: a pointer to the variable to receive the voltage in uV + * \return 0 success, -1 error + *//*********************************************************************************/ +int mpod_internal33Vcc(int dev, int mpid, int *vcc){ + unsigned valh, vall; + // see how the target device is specified ... compute target device address + if (mpod_read(dev, mpid, MPOD_33VCCMSB , &valh )){ + printf("ERROR: MPOD can't read the 3.3Vcc register on i2c bus\n"); + return(-1); + } + mpod_read(dev, mpid , MPOD_33VCCLSB , &vall); + *vcc = (valh<<8) + vall; // value in uV + if (mpod_hideText); + else if (mpod_scriptMode) + printf("%.2f,",(float)*vcc/10000); + else + printf("3.3 power of minipod %d is %.2fV\n", mpid, (float)*vcc/10000); + return(0); +} +/*********************************************************************************//** + * \fn int mpod_internal33VccDumpAll(int dev) + * \brief Function to get the 3.3 vCC value of all minipods voltage in uV + * + * \return 0 success, -1 error + *//*********************************************************************************/ +int mpod_internal33VccDumpAll(int dev){ + int i, temp; + for (i=0; i<8; i++){ + mpod_internal33Vcc(dev, i, &temp); + } + return(0); +} +/*********************************************************************************//** + * \fn int mpod_internal25Vcc(int dev, int mpid, int *vcc) + * \brief Function to get the 2.5 vCC value of one minipod + * + * \param mpid: the target minipod component 0 to 7 + * \param vcc: a pointer to the variable to receive the voltage in uV + * \return 0 success, -1 error + *//*********************************************************************************/ +int mpod_internal25Vcc(int dev, int mpid, int *vcc){ + unsigned valh, vall; + // see how the target device is specified ... compute target device address + if (mpod_read(dev, mpid, MPOD_25VCCMSB , &valh )){ + printf("ERROR: MPOD can't read the 2.5Vcc register on i2c bus\n"); + return(-1); + } + mpod_read(dev, mpid , MPOD_25VCCLSB , &vall); + *vcc = (valh<<8) + vall; + if (mpod_hideText); + else if (mpod_scriptMode) + printf("%2.2f,",(float)*vcc/10000); + else + printf("2.5 power of minipod %d is %2.2fV\n", mpid, (float)*vcc/10000); + return(0); +} +/*********************************************************************************//** + * \fn int mpod_internal25VccDumpAll(int dev) + * \brief Function to get the 2.5 vCC value of all minipods voltage in uV + * + * \return 0 success, -1 error + *//*********************************************************************************/ +int mpod_internal25VccDumpAll(int dev){ + int i, temp; + for (i=0; i<8; i++){ + mpod_internal25Vcc(dev, i, &temp); + } + return(0); +} +/***********************************************************************************//** + * \fn int mpod_biasCurrent(int dev, int mpid, float **data) + * \brief Function to get and print all bias current values of one TX minipod + * + * \param mpid: the target minipod component 1, 3, 5 ,7 + * \param data: a pointer at which the function will put an allocated array of 12 values + * (chn 0 to 11) that the user will have to freed after use. + * value returned in the array are in uA + * \return 0 success, -1 error + *//***********************************************************************************/ +int mpod_biasCurrent(int dev, int mpid, float **data){ + unsigned valh, vall, reg, chn; + float val; + float *cval; + + if (!(mpod_isTX(mpid))){ + printf("ERROR: bias current monitoring only available for TX minipods\n"); + return(-1); + }; + if (!mpod_scriptMode) + printf("Bias current of minipod %d\n", mpid); + if (!(cval = malloc(12*sizeof(float)))){ + printf("ERROR: Can't malloc memory for bias current data\n"); + return(-1); + } + /* All the registers for all channels are in sequence starting with channel 11 downto 0. + They are coded on two bytes the first beeing the MSB. */ + reg = MPOD_BIASCURLSB00; + for (chn=0; chn<12; chn++){ + if (mpod_read(dev, mpid, reg , &vall )){ + printf("ERROR: MPOD can't read the bias current register on i2c bus\n"); + return(-1); + } + mpod_read(dev, mpid, reg-1 , &valh); + val = (float)((valh<<8) + vall) * 2; // unit is 2 uA + if (!mpod_scriptMode) + printf("[%2d] %4.1f uA\n", chn, val); + else + printf("%4.1f,", val); + reg=reg-2; + }//for + if (mpod_scriptMode) printf("\n"); // change line for each minipod + *data = cval; + return(0); +} +/***********************************************************************************//** + * \fn int mpod_getBiasCurrent(int dev, int mpid, float *data) + * \brief Function to get and print all bias current values of one TX minipod in python + * + * \param mpid: the target minipod component 1, 3, 5 ,7 + * \param data: a pointer to an already allocated array of 12 values + * + * \return 0 success, -1 error + *//***********************************************************************************/ +int mpod_getBiasCurrent(int dev, int mpid, float *data){ + return mpod_get12FloatData(dev, mpod_biasCurrent, mpid, data); +} +/***********************************************************************************//** + * \fn int mpod_dumpLightPower( int dev, int mpid, + int reg, + char *regMsg, + (int)(*filter)(int), + float **data) + * \brief Function to get and print all light power values organized as 2 bytes MSB/LSB + * per parameter. values are in 0.1 uW units coded 16 bits unsigned integers + * + * \param mpid : the target minipod component 0, 2 or 4 + * \param reg : the LSB register number for module 0 + * \param regMsg : the register identification message + * \param filter : the filtering function to select proper type of minipods + * \param data : a pointer at which the function will put an allocated array of 11 values + * (chn 0 to 11) that the user will have to freed after use. + * value returned in the array are in uW + * \return 0 success, -1 error + *//***********************************************************************************/ +static int mpod_dumpLightpower(int dev, int mpid,int reg,char *regMsg,int (*filter)(int),float **data){ + unsigned valh, vall, chn; + float val; + float *cval; + + if (filter) + if (!filter(mpid)){ + printf("ERROR: %s doesn't apply to this type of minipod\n", regMsg); + return(-1); + } + if (!mpod_scriptMode) + printf("%s of minipod %d\n", regMsg, mpid); + if (!(cval = malloc(12*sizeof(float)))){ + printf("ERROR: Can't malloc memory for %s data\n", regMsg); + return(-1); + } + /* All the registers for all channels are in sequence starting with channel 11 downto 0. + They are coded on two bytes the first beeing the MSB. */ + for (chn=0; chn<12; chn++){ + if (mpod_read(dev, mpid, reg , &vall )){ + printf("ERROR: MPOD can't read the %s register on i2c bus\n",regMsg); + return(-1); + } + mpod_read(dev, mpid, reg-1 , &valh); + val = (float)((valh<<8) + vall) * 0.1; // unit is 0.1 uW + cval[chn] = 10 * log10f(val/1000); + if (!mpod_scriptMode) + printf("[%2d] %04.1f \tuW %02.2f dBm\n", chn, val, cval[chn]); + else + printf("%04.1f,%02.2f,", val, cval[chn]); + reg=reg-2; + }//for + if (mpod_scriptMode) printf("\n"); // one minipod per line + *data = cval; + return(0); +} +/***********************************************************************************//** + * \fn int mpod_lightOutput(int dev, int mpid, float **data) + * \brief Function to get and print all light output values of one TX minipod + * + * \param mpid: the target minipod component 1, 3, 5 or 7 + * \param data: a pointer at which the function will put an allocated array of 11 values + * (chn 0 to 11) that the user will have to freed after use. + * value returned in the array are in uW + * \return 0 success, -1 error + *//***********************************************************************************/ +int mpod_lightOutput(int dev, int mpid, float **data){ + char regMsg[] = "light output power"; + + return mpod_dumpLightpower(dev, mpid,MPOD_LIGHTOUTLSB00,regMsg,mpod_isTX,data); +} +/***********************************************************************************//** + * \fn int mpod_getLightOutput(int dev, int mpid, float *data) + * \brief Function to get and print all light output values of one TX minipod in python + * + * \param mpid: the target minipod component 1, 3, 5 or 7 + * \param data: a pointer to an already allocated allocated array of 12 values + * value returned in the array are in uW + * \return 0 success, -1 error + *//***********************************************************************************/ +int mpod_getLightOutput(int dev, int mpid, float *data){ + return mpod_get12FloatData(dev, mpod_lightOutput, mpid, data); +} +/***********************************************************************************//** + * \fn int mpod_lightInput(int dev, int mpid, float **data) + * \brief Function to get and print all optical power values of one RX minipod + * + * \param mpid: the target minipod component 0, 2 , 4 or 6 + * \param data: a pointer at which the function will put an allocated array of 11 values + * (chn 0 to 11) that the user will have to freed after use. + * value returned in the array are in dBm + * \return 0 success, -1 error + *//***********************************************************************************/ +int mpod_lightInput(int dev, int mpid, float **data){ + char regMsg[] = "light input power PAVE"; + + return mpod_dumpLightpower(dev,mpid,MPOD_OPPOWERLSB00,regMsg,mpod_isRX,data); +} +/***********************************************************************************//** + * \fn int mpod_getLightInput(int dev, int mpid, float *data) + * \brief Function to get and print all light input values of one RX minipod in python + * + * \param mpid: the target minipod component 0, 2 , 4 or 6 + * \param data: a pointer to an already allocated allocated array of 12 values + * value returned in the array are in uW + * \return 0 success, -1 error + *//***********************************************************************************/ +int mpod_getLightInput(int dev, int mpid, float *data){ + return mpod_get12FloatData(dev, mpod_lightInput, mpid, data); +} +/*****************************************************************************************//** + * \fn int mpod_elapsedPowerOn(int dev, int mpid, int *dur) + * \brief Function to get the elapsed operating time of one minipod in hours (2h resolution) + * + * Comment: this data seem not implemeneted in the chips while documented. + * + * \param mpid: the target minipod component 0 to 7 + * \param dur: a pointer at which the function will put the read value. + * \return 0 success, -1 error + *//****************************************************************************************/ +int mpod_elapsedPowerOn(int dev, int mpid, int *dur){ + unsigned valh, vall; + + // see how the target device is specified ... compute target device address + if (mpod_read(dev, mpid, MPOD_ELAPSEREGMSB, &valh)){ + printf("ERROR: MPOD can't read the power elapse register on i2c bus"); + return(-1); + } + mpod_read(dev, mpid, MPOD_ELAPSEREGLSB , &vall); + *dur = 2*((valh<<8) + vall); + if (!mpod_scriptMode) + printf("Component %d is running since %d Hours (2H granularity)\n", mpid, *dur); + else + printf("%d",*dur); // in hours 2H granularity + + return(0); +} +/*****************************************************************************************//** + * \fn int mpod_reset(int dev, int mpid) + * \brief Function to reset all registers values to their default factory values. + * + * \param mpid: the target minipod component 0 to 7 + * \return 0 success, -1 error + *//****************************************************************************************/ +int mpod_reset(int dev, int mpid){ + + if (mpod_write(dev, mpid, MPOD_RESET , 1)){ + printf("ERROR: can't reset minipod %d board %d\n", mpid, dev); + return(-1); + } + printf("Reset done on minipod %d board %d\n", mpid, dev); + return(0); +} +/*****************************************************************************************//** + * \fn int mpod_channelDisable (int dev, int mpid, int channel, int flag) + * \brief Function to disable one channel of one minipod. + * + * \param mpid : the target minipod component 0 to 7 + * \param channel: the target channel 0 to 12 + * \param flag : 0=enable 1=disable + * \return 0 success, -1 error + *//****************************************************************************************/ +int mpod_channelDisable(int dev, int mpid, int channel, int flag){ + +char regMsg[]="channel disable"; +return (mpod_setBitIn12bitsOn2words(dev, mpid, channel, flag, MPOD_CHDISABLE1, MPOD_CHDISABLE2, + regMsg, NULL)); +} +/*****************************************************************************************//** + * \fn int mpod_channelDisDumpAll (int dev, int mpid) + * \brief Function to dump the disable status of all channels of one minipod. + * + * \param mpid : the target minipod component 0 to 7 + * \return 0 success, -1 error + *//****************************************************************************************/ +int mpod_channelDisDumpAll(int dev, int mpid){ +char regName[]="Disable status enable/disable"; + +return mpod_dumpAllBitIn12bitsOn2words(dev, mpid, + MPOD_CHDISABLE1, MPOD_CHDISABLE2, + regName, + NULL, + 'e','d'); +} +/*****************************************************************************************//** + * \fn int mpod_polarityFlip (int dev, int mpid, int channel, int flag) + * \brief Function to flip input/output polarity one channel of one minipod. + * + * \param mpid : the target minipod component 0 to 7 + * \param channel: the target channel 0 to 12 + * \param flag : 0=enable 1=disable + * \return 0 success, -1 error + *//****************************************************************************************/ +int mpod_polarityFlip(int dev, int mpid, int channel, int flag){ + +char regMsg[]="polarity flipped"; +int res; + +mpod_pageSelect(dev, mpid , 1) ; +res = mpod_setBitIn12bitsOn2words(dev, mpid, channel, flag, MPOD_POLARFLIP1, MPOD_POLARFLIP2, + regMsg, NULL); +mpod_pageSelect(dev, mpid , 0) ; +return res; +} +/*****************************************************************************************//** + * \fn int mpod_channelPolarFlipDumpAll (int dev, int mpid) + * \brief Function to dump the input/output polarity status of all channels of one minipod. + * + * \param mpid : the target minipod component 0 to 7 + * \return 0 success, -1 error + *//****************************************************************************************/ +int mpod_channelPolarFlipDumpAll(int dev, int mpid){ +char regName[]="Polarity flip status"; +int res; + +mpod_pageSelect(dev, mpid , 1) ; +res = mpod_dumpAllBitIn12bitsOn2words(dev, mpid, + MPOD_POLARFLIP1, MPOD_POLARFLIP2, + regName, + NULL, + '0','1'); +mpod_pageSelect(dev, mpid , 0) ; +return res; +} +/*****************************************************************************************//** + * \fn int mpod_marginActivation (int dev, int mpid, int channel, int flag) + * \brief Function to acivate margin one channel of one minipod. + * + * \param mpid : the target minipod component 0 to 7 + * \param channel: the target channel 0 to 12 + * \param flag : 0=enable 1=disable + * \return 0 success, -1 error + *//****************************************************************************************/ +int mpod_marginActivation(int dev, int mpid, int channel, int flag){ + +char regMsg[]="margin activation"; +return (mpod_setBitIn12bitsOn2words(dev, mpid, channel, flag, MPOD_MARGINACT1, MPOD_MARGINACT2, + regMsg, mpod_isTX)); +} +/*****************************************************************************************//** + * \fn int mpod_marginActDumpAll (int dev, int mpid) + * \brief Function to dump the margin activation status of all channels of one minipod. + * + * \param mpid : the target minipod component 0 to 7 + * \return 0 success, -1 error + *//****************************************************************************************/ +int mpod_marginActDumpAll(int dev, int mpid){ +char regName[]="margin activation/deactivation"; +return mpod_dumpAllBitIn12bitsOn2words(dev, mpid, + MPOD_MARGINACT1, MPOD_MARGINACT2, + regName, + mpod_isRX, + 'd','a'); +} +/*****************************************************************************************//** + * \fn int mpod_readPatQuartMulti(int dev, int mpid, unsigned **data, int higherReg, char *idChain) + * \brief Function general to read the 12 channels 4 bits codes of a minipod when they are + * stored 2 by 2 (msb/lsb) in 6 registers (reverse order higher channel in lower registers) + * + * It is used to factorize code for VOD, deamphasis and equalization read/write global or single + * + * \param mpid: the target RX minipod component 0, 2, 4 and 6 (RX) + * \param data: a pointer at which the function will put an allocated array of 12 code values + * (chn 0 to 11) that the user will have to freed after use. + * \param higherReg : the higher register number (for channel 0 and 1) + * \param idChain: an identification chain to put in error message + * \return 0 success, -1 error + *//****************************************************************************************/ +static int mpod_readPatQuartMulti(int dev, int mpid, int **data, int higherReg, char *idChain){ + int reg, i, msb, lsb, chn; + unsigned val; + int *res; + + mpod_pageSelect(dev, mpid , 1) ; + if (!(res = malloc(12*sizeof(int)))){ + printf("ERROR: Can't malloc memory for amplitude control data\n"); + return(-1); + } + /* All the output amplitude control registers for all channels are in sequence with two channels per reg + starting with channel 11-10 ending with 1-0 thus 6 conscecutive regs*/ + chn = 0; + reg = higherReg; + for (i=6; i>0; i--){ + if (mpod_read(dev, mpid, reg, &val)){ + printf("ERROR: MPOD can't read the %s register on i2c bus\n", idChain); + return(-1); + } + msb = val/16; + lsb = val & 0x0f; + // store the codes to pass to the user + res[chn] =lsb; + res[chn+1]=msb; + chn=chn+2; + reg = reg-1; + } + *data=res; + mpod_pageSelect(dev, mpid , 0); + return(0); +} +/*****************************************************************************************//** + * \fn int mpod_readPatQuartSingle(int dev, int mpid, int channel, int *code, unsigned *places, char *idChain) + * \brief Function to get the RX output amplitude control of one channel of a minipod + * + * \param mpid : the target RX minipod component 0, 2, 4 and 6 (RX) + * \param channel : the channel to read + * \param data : a pointer at which the function will put the returned code value. + * \param places : an array giving the register/places pairs for all channels + * \param idChain : an identification chain to put in error message + * \return 0 success, -1 error + *//****************************************************************************************/ +static int mpod_readPatQuartSingle(int dev, int mpid, int channel, int *code, quartPlace *places, char *idChain){ + int reg, qval; + unsigned val; + + mpod_pageSelect(dev, mpid , 1) ; + reg = places[channel].reg; + if (mpod_read(dev, mpid, reg, &val)){ + printf("ERROR: MPOD can't read %s register on i2c bus\n", idChain); + return(-1); + } + // test low quarter is used and extract the proper quarter + qval = (places[channel].quart==0) ? val & 0x0f : val/16; + // qval = ((*places)[channel][1]==0) ? val & 0x0f : val/16; + *code=qval; + mpod_pageSelect(dev, mpid , 0); + return(0); +} +/*****************************************************************************************//** + * \fn int mpod_writePatQuartMulti(int dev, int mpid, unsigned *data, int higherReg, char *idChain) + + * \brief Function general to write the 12 channels 4 bits codes of a minipod when they are + * stored 2 by 2 (msb/lsb) in 6 registers (reverse order higher channel in lower registers) + * + * It is used to factorize code for VOD, deamphasis and equalization read/write global or single + * + * \param mpid: the target RX minipod component 0, 2, 4 and 6 + * \param data: a pointer to an array of 12 code values ordered from channel 0 to 11 + * \return 0 success, -1 error + *//****************************************************************************************/ +static int mpod_writePatQuartMulti(int dev, int mpid, int *data, int higherReg, char *idChain){ + int i, val, chn, reg; + + mpod_pageSelect(dev, mpid, 1) ; + /* All the output amplitude control registers for all channels are in sequence with two channels per reg + starting with channel 11-10 ending with 1-0 thus 6 conscecutive regs*/ + reg = higherReg; + chn = 0; + for (i=6; i>0; i--){ + val = (data[chn+1]<<4) + data[chn]; + if (mpod_write(dev, mpid, reg, val)){ + printf("ERROR: can't write the RX %s register on i2c bus", idChain); + return(-1); + } + chn = chn+2; + reg = reg-1; + } + mpod_pageSelect(dev, mpid , 0); + return(0); +} +/***************************************************************************************************//** + * \fn int mpod_writePatQuartSingle(int dev, int mpid, int channel, int code, quartPlaces *places, char *idChain) + * \brief Function to set the RX output amplitude control of the a channel of a minipod + * + * Note this function is not efficient but we dont care we keep it simple! + * + * \param mpid : the target RX minipod component 0, 2, 4 and 6 + * \param channel : the channel to set the value + * \param places : the array describing the places of all channel and registers/codes associations + * \param code : the code value to write (0 to 7) + * \param idChain : the string to identify the function in error messages + * \return 0 success, -1 error + *//***************************************************************************************************/ +static int mpod_writePatQuartSingle(int dev, int mpid, int channel, int code, quartPlace *places, char *idChain){ + + int val, reg; + unsigned curData; + + mpod_pageSelect(dev, mpid , 1); + reg = places[channel].reg; + if (mpod_read(dev, mpid, reg, &curData)){ + printf("ERROR: MPOD can't read the %s register on i2c bus\n", idChain); + return(-1); + } + if (places[channel].quart==0) {// test if low quarter is used + val = curData & 0xf0; //nullify used quarter + val = val | code; + } + else { + val = curData & 0xf; //nullify used quarter + val = val | (code<<4); + } + if (mpod_write(dev, mpid, reg, val)){ + printf("ERROR: MPOD can't write the RX %s register on i2c bus\n", idChain); + return(-1); + } + mpod_pageSelect(dev, mpid , 0); + return(0); +} +/*****************************************************************************************//** + * \fn void mpod_printVOD(int dev, int mpid, unsigned *data) + * \brief Function to print the RX output amplitude control of the 12 channels of a minipod + * + * \param mpid: the target RX minipod component 0, 2, 4 and 6 (RX) + * \param data: a pointer at which the function receive an array with 12 code valuesb to print + + *//****************************************************************************************/ +static void mpod_printVOD(int dev, int mpid, int *data){ + int i; + if (!mpod_scriptMode){ + printf("VOD output amplitude for minipod %d board %d\n", mpid, dev); + printf("---------------------------------------------\n"); + printf(" chn ! code! Min ! Nominal ! Max ! Units !\n"); + printf("---------------------------------------------\n"); + } + for (i=0; i<12; i++){ + if (!mpod_scriptMode) + printf(" %3d ! %3d ! %3d ! %3d ! %3d ! mVppd !\n", i, data[i], + mpod_ampControlCodes[data[i]][0], mpod_ampControlCodes[data[i]][1], mpod_ampControlCodes[data[i]][2]); + else + printf("%3d,%3d,%3d,%3d,%3d,", i, data[i], + mpod_ampControlCodes[data[i]][0], mpod_ampControlCodes[data[i]][1], mpod_ampControlCodes[data[i]][2]); + } + if (!mpod_scriptMode) + printf("------------------------------------------\n"); + else + printf("\n"); +} +/*****************************************************************************************//** + * \fn void mpod_printVODSingle(int dev, int mpid, int channel, int code) + * \brief Function to print the RX output amplitude control of one channel of a minipod + * + * \param mpid : the target RX minipod component 0, 2, 4 and 6 (RX) + * \param channel : the channel to print + * \param data : the code value of this channel to print. + * \return 0 success, -1 error + *//****************************************************************************************/ +static void mpod_printVODSingle(int dev, int mpid, int channel, int code){ + if (!mpod_scriptMode){ + printf("VOD output amplitude for minipod %d channel %d board %d\n", mpid, channel, dev); + printf("------------------------------------------\n"); + printf(" chn ! code! Min ! Nominal ! Max ! Units !\n"); + printf("------------------------------------------\n"); + } + if (!mpod_scriptMode) + printf(" %3d ! %3d ! %3d ! %3d ! %3d ! mVppd !\n", channel, code, + mpod_ampControlCodes[code][0], mpod_ampControlCodes[code][1], mpod_ampControlCodes[code][2]); + else + printf("%3d,%3d,%3d,%3d,%3d,", channel, code, + mpod_ampControlCodes[code][0], mpod_ampControlCodes[code][1], mpod_ampControlCodes[code][2]); + if (!mpod_scriptMode) + printf("------------------------------------------\n"); + else + printf("\n"); +} +/*****************************************************************************************//** + * \fn int mpod_readVOD(int dev, int mpid, unsigned **data) + * \brief Function to get the RX output amplitude control of the 12 channels of a minipod + * + * \param mpid: the target RX minipod component 0, 2, 4 and 6 (RX) + * \param data: a pointer at which the function will put an allocated array of 12 code values + * (chn 0 to 11) that the user will have to freed after use. + * \return 0 success, -1 error + *//****************************************************************************************/ +int mpod_readVOD(int dev, int mpid, int **data){ + char subject[] = "VOD amplitude control"; + + // check RX + if (!(mpod_isRX(mpid))){ + printf("ERROR: minpod %d is not an RX\n", mpid); + return(-1); + }; + // get the data + if (mpod_readPatQuartMulti(dev, mpid, data, MPOD_RXVOD1, subject)==-1) + return(-1); + // print the data + mpod_printVOD(dev, mpid, *data); + return(0); +} + +/*****************************************************************************************//** + * \fn int mpod_getVOD(int dev, int mpid, unsigned *data) + * \brief Function to get the RX output amplitude control of the 12 channels of a minipod in python + * + * Function to avoid to have to manage dynamically allocated arrays in the python wrapper. + * + * \param mpid: the target RX minipod component 0, 2, 4 and 6 (RX) + * \param data: a pointer to an already allocated array of 12 code values + * (chn 0 to 11) that the user will have to freed after use. + * \return 0 success, -1 error + *//****************************************************************************************/ +int mpod_getVOD(int dev, int mpid, int *data){ + return mpod_get12IntData(dev, mpod_readVOD,mpid, data); +} +/*****************************************************************************************//** + * \fn int mpod_readVODSingle(int dev, int mpid, int channel, int *code) + * \brief Function to get the RX output amplitude control of one channel of a minipod + * + * \param mpid : the target RX minipod component 0, 2, 4 and 6 (RX) + * \param channel : the channel to read + * \param data : a pointer at which the function will put the returned code value. + * \return 0 success, -1 error + *//****************************************************************************************/ +int mpod_readVODSingle(int dev, int mpid, int channel, int *code){ + char subject[] = "VOD amplitude control"; + + // check RX + if (!(mpod_isRX(mpid))){ + printf("ERROR: minpod %d is not an RX\n", mpid); + return(-1); + }; + // get the data + if (mpod_readPatQuartSingle(dev, mpid, channel, code, mpod_vodQuarters, subject)==-1) + return(-1); + // print the data + mpod_printVODSingle(dev, mpid, channel, *code); + return(0); +} +/*****************************************************************************************//** + * \fn int mpod_writeVOD(int dev, int mpid, unsigned *data) + * \brief Function to set the RX output amplitude control of the 12 channels of a minipod + * + * \param mpid: the target RX minipod component 0, 2, 4 and 6 + * \param data: a pointer to an array of 12 code values ordered from channel 0 to 11 + * \return 0 success, -1 error + *//****************************************************************************************/ +int mpod_writeVOD(int dev, int mpid, int *data){ + char subject[] = "VOD amplitude control"; + + // check RX + if (!(mpod_isRX(mpid))){ + printf("ERROR: minpod %d is not an RX\n", mpid); + return(-1); + }; + // write the data + mpod_writePatQuartMulti(dev, mpid, data, MPOD_RXVOD1, subject); + return(0); +} +/*****************************************************************************************//** + * \fn int mpod_writeVODSingle(int dev, int mpid, int channel, int code) + * \brief Function to set the RX output amplitude control of the a channel of a minipod + * + * Note this function is not efficient but we dont care we keep it simple! + * + * \param mpid : the target RX minipod component 0, 2, 4 and 6 + * \param channel : the channel to set the value + * \param data : the code value to write (0 to 7) + * \return 0 success, -1 error + *//****************************************************************************************/ +int mpod_writeVODSingle(int dev, int mpid, int channel, int code){ + char subject[] = "VOD amplitude control"; + + // check RX + if (!(mpod_isRX(mpid))){ + printf("ERROR: minipod %d is not an RX\n", mpid); + return(-1); + }; + // check code + if (code>7){ + printf("ERROR: RX output amplitude control register code should be less than 0111b\n"); + return(-1); + } + // write the data + mpod_writePatQuartSingle(dev, mpid, channel, code, mpod_vodQuarters, subject); + return(0); +} +/*****************************************************************************************//** + * \fn void mpod_printDeamphasis(int dev, int mpid, unsigned *data) + * \brief Function to print the RX output deamphasis codes of the 12 channels of a minipod + * + * \param mpid: the target RX minipod component 0, 2, 4 and 6 (RX) + * \param data: a pointer at which the function receive an array with 12 code values to print + + *//****************************************************************************************/ +static void mpod_printDeamphasis(int dev, int mpid, int *data){ + int i; + if (!mpod_scriptMode){ + printf("output deamphasis for minipod %d board %d\n", mpid, dev); + printf("------------------------\n"); + printf(" chn ! code !Deamphasis!\n"); + printf("------------------------\n"); + } + for (i=0; i<12; i++){ + if (!mpod_scriptMode) + printf(" %3d ! %3d ! %3d%c !\n", i, data[i], (data[i]*100/7), '%'); + else + printf("%3d,%3d,%3d%c,", i, data[i], (data[i]*100/7), '%'); + } + if (!mpod_scriptMode) + printf("------------------------\n"); + else + printf("\n"); +} +/*****************************************************************************************//** + * \fn void mpod_printDeamphasisSingle(int dev, int mpid, int channel, int code) + * \brief Function to print the RX deamphasis code of one channel of a minipod + * + * \param mpid : the target RX minipod component 0, 2, 4 and 6 (RX) + * \param channel : the channel to print + * \param data : the code value of this channel to print. + * \return 0 success, -1 error + *//****************************************************************************************/ +static void mpod_printDeamphasisSingle(int dev, int mpid, int channel, int code){ + if (!mpod_scriptMode){ + printf("output deamphasis for minipod %d board %d\n", mpid, dev); + printf("------------------------\n"); + printf(" chn ! code !Deamphasis!\n"); + printf("------------------------\n"); + } + if (!mpod_scriptMode) + printf(" %3d ! %3d ! %3d%c !\n", channel, code, (code*100/7), '%'); + else + printf("%3d,%3d,%3d%c,", channel, code, (code*100/7), '%'); + if (!mpod_scriptMode) + printf("------------------------\n"); + else + printf("\n"); +} +/*****************************************************************************************//** + * \fn int mpod_readDeamphasis(int dev, int mpid, int **data) + * \brief Function to get the RX deamphasis control of the 12 channels of a minipod + * + * \param mpid: the target minipod component 0, 2, 4 or 6 + * \param data: a pointer at which the function will put an allocated array of 12 code values + * (chn 0 to 11) that the user will have to freed after use. + * \return 0 success, -1 error + *//****************************************************************************************/ +int mpod_readDeamphasis(int dev, int mpid, int **data){ + char subject[] = "Deamphasis control"; + + // check RX + if (!(mpod_isRX(mpid))){ + printf("ERROR: minpod %d is not an RX\n", mpid); + return(-1); + }; + // get the data + if (mpod_readPatQuartMulti(dev, mpid, data, MPOD_RXDEAMPH1, subject)==-1) + return(-1); + + // print the data + mpod_printDeamphasis(dev, mpid, *data); + return(0); +} +/*****************************************************************************************//** + * \fn int mpod_getDeamphasis(int dev, int mpid, int *data) + * \brief Function to get the RX deamphasis control of the 12 channels of a minipod in python + * + * Function developped for the python wrapper to avoid manipulation of dynamically allocated + * array of data in python. + * + * \param mpid: the target minipod component 0, 2, 4 or 6 + * \param data: a pointer to an already allocated array of 12 code values + * (chn 0 to 11) that the user will have to freed after use. + * \return 0 success, -1 error + *//****************************************************************************************/ +int mpod_getDeamphasis(int dev, int mpid, int *data){ + return mpod_get12IntData(dev, mpod_readDeamphasis,mpid, data); +} +/*****************************************************************************************//** + * \fn int mpod_readDeamphasisSingle(int dev, int mpid, int channel, int *code) + * \brief Function to get the RX deamphasis control of the one channel of a minipod + * + * \param mpid : the target minipod component 0, 2, 4 or 6 + * \param channel : the channel to read + * \param data : a pointer at which the function will put the read code value + * \return 0 success, -1 error + *//****************************************************************************************/ +int mpod_readDeamphasisSingle(int dev, int mpid, int channel, int *code){ + char subject[] = "Deamphasis control"; + + // check RX + if (!(mpod_isRX(mpid))){ + printf("ERROR: minpod %d is not an RX\n", mpid); + return(-1); + }; + // get the data + if (mpod_readPatQuartSingle(dev, mpid, channel, code, mpod_deamphQuarters, subject)==-1) + return(-1); + + // print the value + mpod_printDeamphasisSingle(dev, mpid, channel, *code); + return(0); +} +/*****************************************************************************************//** + * \fn int mpod_writeDeamphasis(int dev, int mpid, int *data) + * \brief Function to set the RX deamphasis control of the 12 channels of a minipod + * + * \param mpid: the target minipod component 0,2, 4 or 6 + * \param data: a pointer to an array of 11 code values ordered from channel 0 to 11 + * \return 0 success, -1 error + *//****************************************************************************************/ +int mpod_writeDeamphasis(int dev, int mpid, int *data){ + char subject[] = "Deamphasis control"; + + // check RX + if (!(mpod_isRX(mpid))){ + printf("ERROR: minpod %d is not an RX\n", mpid); + return(-1); + }; + // write the data + mpod_writePatQuartMulti(dev, mpid, data, MPOD_RXDEAMPH1, subject); + return(0); +} +/*****************************************************************************************//** + * \fn int mpod_writeDeamphasisSingle(int dev, int mpid, int channel, int code) + * \brief Function to set the RX deamphasis control of one channels of one minipod + * + * \param mpid : the target minipod component 0,2,4 or 6 + * \param channel : the target channel + * \param data : the code value to write + * \return 0 success, -1 error + *//****************************************************************************************/ +int mpod_writeDeamphasisSingle(int dev, int mpid, int channel, int code){ + char subject[] = "Deamphasis control"; + + // check RX + if (!(mpod_isRX(mpid))){ + printf("ERROR: minpod %d is not an RX\n", mpid); + return(-1); + } + // check code + if (code>7){ + printf("ERROR: RX deamphasis register code should be less than 0111b"); + return(-1); + } + mpod_writePatQuartSingle(dev, mpid, channel, code, mpod_deamphQuarters, subject); + return(0); +} +/*****************************************************************************************//** + * \fn void mpod_printEqualization(int dev, int mpid, unsigned *data) + * \brief Function to print the TX equalization codes of the 12 channels of a minipod + * + * \param mpid: the target TX minipod component 0, 2 and 6 (TX) + * \param data: a pointer at which the function receive an array with 12 code values to print + + *//****************************************************************************************/ +static int mpod_printEqualization(int dev, int mpid, int *data){ + int i; + if (!(mpod_isTX(mpid))){ + printf("ERROR: Equalization only available for TX minipods\n"); + return(-1); + }; + if (!mpod_scriptMode){ + printf("equalization for minipod %d borad %d\n", mpid, dev); + printf("-----------------------------------------------\n"); + printf(" chn ! code! peak !midband\t!peak<>midband!\n"); + printf("-----------------------------------------------\n"); + } + for (i=0; i<12; i++){ + if (!mpod_scriptMode) + printf(" %3d ! %3d ! %2.2f !%2.2f\t! %2.2f\t !\n", i, data[i], + mpod_equalizationCodes[data[i]][0], mpod_equalizationCodes[data[i]][1], mpod_equalizationCodes[data[i]][2]); + else + printf("%3d,%3d,%2.2f,%2.2f,%2.2f,", i, data[i], + mpod_equalizationCodes[data[i]][0], mpod_equalizationCodes[data[i]][1], mpod_equalizationCodes[data[i]][2]); + } + if (!mpod_scriptMode) + printf("-----------------------------------------------\n"); + else + printf("\n"); + return(0); +} +/*****************************************************************************************//** + * \fn void mpod_printEqualizationSingle(int dev, int mpid, int channel, int code) + * \brief Function to print the TX deamphasis code of one channel of a minipod + * + * \param mpid : the target TX minipod component 1, 3, 5 and 7 + * \param channel : the channel to print + * \param data : the code value of this channel to print. + * \return 0 success, -1 error + *//****************************************************************************************/ +static int mpod_printEqualizationSingle(int dev, int mpid, int channel, int code){ + if (!(mpod_isTX(mpid))){ + printf("ERROR: Equalization only available for TX minipods\n"); + return(-1); + }; + if (!mpod_scriptMode){ + printf("equalization for minipod %d board %d\n", mpid, dev); + printf("-----------------------------------------------\n"); + printf(" chn ! code! peak !midband\t!peak<>midband!\n"); + printf("-----------------------------------------------\n"); + } + if (!mpod_scriptMode) + printf(" %3d ! %3d ! %2.2f !%2.2f\t! %2.2f\t !\n", channel, code, + mpod_equalizationCodes[code][0], mpod_equalizationCodes[code][1], mpod_equalizationCodes[code][2]); + else + printf("%3d,%3d,%2.2f,%2.2f,%2.2f,", channel, code, + mpod_equalizationCodes[code][0], mpod_equalizationCodes[code][1], mpod_equalizationCodes[code][2]); + if (!mpod_scriptMode) + printf("-----------------------------------------------\n"); + else + printf("\n"); + return(0); +} +/*****************************************************************************************//** + * \fn int mpod_readEqualization(int dev, int mpid, int **data) + * \brief Function to get the TX Equalization control of the 12 channels of a minipod + * + * \param mpid: the target minipod component 0, 2 or 4 + * \param data: a pointer at which the function will put an allocated array of 12 code values + * (chn 0 to 11) that the user will have to freed after use. + * \return 0 success, -1 error + *//****************************************************************************************/ +int mpod_readEqualization(int dev, int mpid, int **data){ + char subject[] = "equalization control"; + + // check TX + if (!(mpod_isTX(mpid))){ + printf("ERROR: minpod %d is not a TX\n", mpid); + return(-1); + } + // get the data + if (mpod_readPatQuartMulti(dev, mpid, data, MPOD_TXEQUALZ1, subject)==-1) + return(-1); + + // print the data + mpod_printEqualization(dev, mpid, *data); + return(0); +} +/*****************************************************************************************//** + * \fn int mpod_getEqualization(int dev, int mpid, int *data) + * \brief Function to get the TX Equalization control of the 12 channels of a minipod in python + * + * Function developped for the python wrapping to prevent the exchange of a dynamically allocated + * array that should be free after use. + + * \param mpid: the target minipod component 0, 2 or 4 + * \param data: a pointer to an already allocated array of 12 code values + * + * \return 0 success, -1 error + *//****************************************************************************************/ +int mpod_getEqualization(int dev, int mpid, int *data){ + return mpod_get12IntData(dev, mpod_readEqualization ,mpid, data); +} + +/*****************************************************************************************//** + * \fn int mpod_readEqualizationSingle(int dev, int mpid, int channel, int *code) + * \brief Function to get the TX equalization control of the one channel of a minipod + * + * \param mpid : the target minipod component 0, 2 or 4 + * \param channel : the channel to read + * \param data : a pointer at which the function will put the read code value + * \return 0 success, -1 error + *//****************************************************************************************/ +int mpod_readEqualizationSingle(int dev, int mpid, int channel, int *code){ + char subject[] = "Equalization control"; + + // check TX + if (!(mpod_isTX(mpid))){ + printf("ERROR: minpod %d is not an TX\n", mpid); + return(-1); + }; + // get the data + if (mpod_readPatQuartSingle(dev, mpid, channel, code, mpod_equalzQuarters, subject)==-1) + return(-1); + + // print the value + mpod_printEqualizationSingle(dev, mpid, channel, *code); + return(0); +} +/*****************************************************************************************//** + * \fn int mpod_writeEqualization(int dev, int mpid, int *data) + * \brief Function to set the TX Equalization control of the 12 channels of a minipod + * + * \param mpid: the target minipod component 0,2 or 4 + * \param data: a pointer to an array of 12 code values ordered from channel 0 to 11 + * \return 0 success, -1 error + *//****************************************************************************************/ +int mpod_writeEqualization(int dev, int mpid, int *data){ + char subject[] = "Equalization control"; + // check TX + if (!(mpod_isTX(mpid))){ + printf("ERROR: minpod %d is not an TX\n", mpid); + return(-1); + } + // write the data + mpod_writePatQuartMulti(dev, mpid, data, MPOD_TXEQUALZ1, subject); + return(0); +} +/*****************************************************************************************//** + * \fn int mpod_writeEqualizationSingle(int dev, int mpid, int channel, int code) + * \brief Function to set the TX equalization control of one channels of one minipod + * + * \param mpid : the target minipod component 0,2 or 4 + * \param channel : the target channel + * \param data : the code value to write + * \return 0 success, -1 error + *//****************************************************************************************/ +int mpod_writeEqualizationSingle(int dev, int mpid, int channel, int code){ + char subject[] = "Equalization control"; + + // check TX + if (!(mpod_isTX(mpid))){ + printf("ERROR: minpod %d is not an TX\n", mpid); + return(-1); + } + // check code + if (code>7){ + printf("ERROR: TX deamphasis register code should be less than 0111b"); + return(-1); + } + + mpod_writePatQuartSingle(dev, mpid, channel, code, mpod_equalzQuarters, subject); + return(0); +} +#ifdef MAIN_MINIPOD +/*==============================*/ +/* main test program to execute */ +/*==============================*/ +int main(int argc, char **argv){ + int i, mp, vcc, dur; + float *fdata = 0; + int *data, *data2; + int testVOD[] ={0x04,0x4,0x4,0x4,0x4,0x4,0x4,0x04,0x4,0x4,0x4,0x4}; + int testCodes[] ={0x01,0x2,0x3,0x4,0x5,0x6,0x7,0x1,0x2,0x3,0x4,0x5}; + + + /* ATTENTION CHECK THE necessary bus clock init setting is done in the driver */ + if (mpod_init(0, 125000000, 100000)) + exit(2); + + ///#I2C_PageSelect $targetDevice 1 + if (mpod_pageSelect(0, 3, 1)==-1) exit(2); + ///#I2C_PageSelect $targetDevice 0 + if (mpod_pageSelect(0, 3, 0)==-1) exit(2); + + + /// ========================== VENDOR DATA ========================== + for (mp=0; mp<6; mp++) { + if (mpod_dumpVendorData(0,mp)==-1){ + printf("\nERROR: Can't print vendor data for minipod %d\n\n", mp); + } + } + /// ========================== SQUELCH ========================== + mpod_squelchDumpAll(0,0); + mpod_squelchDisableAll(0, 0, 0); + mpod_squelchDumpAll(0, 0); + mpod_squelchDisableAll(0, 0, 1); + mpod_squelchDumpAll(0, 0); + mpod_squelchDisable(0, 0 , 2 , 0); + mpod_squelchDisable(0, 0 , 9 , 0); + mpod_squelchDumpAll(0, 0); + mpod_squelchDisable(0, 0 , 2 , 1); + mpod_squelchDisable(0, 0 , 9 , 1); + + mpod_internalTempDumpAll(0); + + + /// ========================== I2C_Internal33Vcc 3 ========================== + if (mpod_internal33Vcc(0, 0, 3, &vcc)) + exit(2); + else { + printf("\tTEST Got 3.3 Vcc %d\n", vcc); + } + /// ========================== I2C_Internal25Vcc 3 ========================== + if (mpod_internal25Vcc(0, 3, &vcc)) + exit(2); + else { + printf("\tTEST Got 2.5 Vcc %d\n", vcc); + } + + /// ========================== I2C_lightInput 2 ========================== + if (mpod_lightInput(0, 2, &fdata)) + exit(2); + else { + printf("\tTEST Got optical power\n"); + for (i=0;i<12;i++) + printf("\tTEST data[%d]=%2.2f dBm\n", i, fdata[i]); + free(fdata); + } + for (mp=0; mp<6; mp++){ + if (mpod_lightInput(0, mp, &fdata)) + exit(2); + } + for (mp=0; mp<6; mp++){ + mpod_elapsedPowerOn(0, mp, &dur); + } + + // ========================== VOD ========================== + // read store current values + printf("READ-STORE CURRENT VOD\n"); + for (mp=0; mp<6; mp++){ + if (!(mp%2)) continue; + if (mpod_readVOD(0, mp, &data)) + exit(2); + else { + for (i=0;i<12;i++) + printf("\tTEST vod[%d]=%d ", i, data[i]); + printf("\n"); + } + } + // put new values + printf("WRITE NEW VOD\n"); + for (mp=0; mp<6; mp++){ + if (!(mp%2)) continue; + mpod_writeVOD(0, mp, testVOD); + } + // print to check + printf("READ CHECK NEW VOD\n"); + for (mp=0; mp<6; mp++){ + if (!(mp%2)) continue; + if (mpod_readVOD(0, mp, &data2)) + exit(2); + else { + for (i=0;i<12;i++) + printf("\tTEST vod[%d]=%d ", i, data2[i]); + printf("\n"); + free(data2); + } + } + // restore saved values + printf("READ CHECK NEW VOD\n"); + for (mp=0; mp<6; mp++){ + if (!(mp%2)) continue; + mpod_writeVOD(0, mp, data); + } + free(data); + // check again + printf("RESTORE STORED VOD\n"); + for (mp=0; mp<6; mp++){ + if (!(mp%2)) continue; + if (mpod_readVOD(0, mp, &data2)) + exit(2); + else { + for (i=0;i<12;i++) + printf("\tTEST vod[%d]=%d ", i, data2[i]); + printf("\n"); + free(data2); + } + } + // ========================== DEAMPHASIS =========================== + // read store current values + printf("DUMP CURENT DEAMPHASIS\n"); + for (mp=0; mp<6; mp++){ + if (!(mp%2)) continue; + if (mpod_readDeamphasis(0, mp, &data)) + exit(2); + else { + for (i=0;i<12;i++) + printf("\tTEST deamp[%d]=%d ", i, data[i]); + printf("\n"); + } + } + // put new values + printf("WRITE NEW DEAMPHASIS\n"); + for (mp=0; mp<6; mp++){ + if (!(mp%2)) continue; + mpod_writeDeamphasis(0, mp, testCodes); + } + // print to check + printf("READ TO CHECK DEAMPHASIS\n"); + for (mp=0; mp<6; mp++){ + if (!(mp%2)) continue; + if (mpod_readDeamphasis(0, mp, &data2)) + exit(2); + else { + for (i=0;i<12;i++) + printf("\tTEST deamp[%d]=%d ", i, data2[i]); + printf("\n"); + free(data2); + } + } + // restore saved values + printf("RESTORE OLD DEAMPHASIS\n"); + for (mp=0; mp<6; mp++){ + if (!(mp%2)) continue; + mpod_writeDeamphasis(0, mp, data); + } + free(data); + // check again + printf("READ TO CHECK AGAIN DEAMPHASIS\n"); + for (mp=0; mp<6; mp++){ + if (!(mp%2)) continue; + if (mpod_readDeamphasis(0, mp, &data2)) + exit(2); + else { + for (i=0;i<12;i++) + printf("\tTEST deamp[%d]=%d ", i, data2[i]); + printf("\n"); + free(data2); + } + } + + // ========================== EQUALIZATION ========================== + // read store current values + printf("DUMP CURENT EQUALIZATION\n"); + for (mp=0; mp<6; mp++){ + if (mp%2) continue; + if (mpod_readEqualization(0, mp, &data)) + exit(2); + else { + for (i=0;i<12;i++) + printf("\tTEST deamp[%d]=%d ", i, data[i]); + printf("\n"); + } + } + // put new values + printf("WRITE NEW EQUALIZATION\n"); + for (mp=0; mp<6; mp++){ + if (mp%2) continue; + mpod_writeEqualization(0, mp, testCodes); + } + // print to check + printf("READ TO CHECK EQUALIZATION\n"); + for (mp=0; mp<6; mp++){ + if (mp%2) continue; + if (mpod_readEqualization(0, mp, &data2)) + exit(2); + else { + for (i=0;i<12;i++) + printf("\tTEST deamp[%d]=%d ", i, data2[i]); + printf("\n"); + free(data2); + } + } + // restore saved values + printf("RESTORE OLD EQUALIZATION\n"); + for (mp=0; mp<6; mp++){ + if (mp%2) continue; + mpod_writeEqualization(0, mp, data); + } + free(data); + // check again + printf("READ TO CHECK AGAIN EQUALIZATION\n"); + for (mp=0; mp<6; mp++){ + if (mp%2) continue; + if (mpod_readEqualization(0, mp, &data2)) + exit(2); + else { + for (i=0;i<12;i++) + printf("\tTEST deamp[%d]=%d ", i, data2[i]); + printf("\n"); + free(data2); + } + } + +return(0); +} +#endif + + diff --git a/Pcie40Libraries/avagoMinipodCtrl.h b/Pcie40Libraries/avagoMinipodCtrl.h new file mode 100644 index 0000000..273c966 --- /dev/null +++ b/Pcie40Libraries/avagoMinipodCtrl.h @@ -0,0 +1,235 @@ +/**--------------------------------------------------------------------------------------------- +* \file avagoMinipodCtrl.h +* +* \brief This file contains the user driver to control the 6 AVAGO miniPOD of the AMC40 board. +* +* \author PYD : Pierre-Yves Duval +* \version 0.1 +* \date 17/4/2012 + +-------------------------------------------------------------------------------------------------*/ + +/*----------------------------------------------------------------------------------------------- +* PYD : 17/4/2012 initial version +* PYD : 12/6/2015 Several i2c bus implemented for PCIe40 +*----------------------------------------------------------------------------------------------- +*/ + +#define MPOD_DBG 0 /*!<debug flag */ +#define MPOD_TEST 0 /*!<test flag */ + +#define MPOD_ERRORSTAT 2 /*!<index of data nor ready, intl, LOS, fault status*/ +#define MPOD_LOSREG1 9 /*!<index of LOS reg for channel 11 downto 8 (reg low quarter)*/ +#define MPOD_LOSREG2 10 /*!<index of LOS reg for channel 7 downto 0 */ +#define MPOD_FAULTREG1 11 /*!<index of TX FAULT reg for channel 11 downto 8 (reg low quarter)*/ +#define MPOD_FAULTREG2 12 /*!<index of TX FAULT reg for channel 7 downto 0 */ +#define MPOD_INTEMPMSB 28 /*!<index of internal temperature monitor MSB*/ +#define MPOD_INTEMPLSB 29 /*!<index of internal temperature monitor LSB*/ +#define MPOD_33VCCMSB 32 /*!<index of 3.3 Vcc monitor MSB*/ +#define MPOD_33VCCLSB 33 /*!<index of 3.3 Vcc monitor LSB*/ +#define MPOD_25VCCMSB 34 /*!<index of 2.5 Vcc monitor MSB*/ +#define MPOD_25VCCLSB 35 /*!<index of 2.5 Vcc monitor LSB*/ + +/* FOR TX component ONLY on page OOh */ +#define MPOD_BIASCURMSB11 40 /*!<index of TX Current BIAS monitor MSB fot channel 11*/ +#define MPOD_BIASCURLSB11 41 /*!<index of TX Current BIAS monitor LSB fot channel 11*/ +#define MPOD_BIASCURMSB10 42 /*!<index of TX Current BIAS monitor MSB fot channel 10*/ +#define MPOD_BIASCURLSB10 43 /*!<index of TX Current BIAS monitor LSB fot channel 10*/ +#define MPOD_BIASCURMSB09 44 /*!<index of TX Current BIAS monitor MSB fot channel 09*/ +#define MPOD_BIASCURLSB09 45 /*!<index of TX Current BIAS monitor LSB fot channel 09*/ +#define MPOD_BIASCURMSB08 46 /*!<index of TX Current BIAS monitor MSB fot channel 08*/ +#define MPOD_BIASCURLSB08 47 /*!<index of TX Current BIAS monitor LSB fot channel 08*/ +#define MPOD_BIASCURMSB07 48 /*!<index of TX Current BIAS monitor MSB fot channel 07*/ +#define MPOD_BIASCURLSB07 49 /*!<index of TX Current BIAS monitor LSB fot channel 07*/ +#define MPOD_BIASCURMSB06 50 /*!<index of TX Current BIAS monitor MSB fot channel 06*/ +#define MPOD_BIASCURLSB06 51 /*!<index of TX Current BIAS monitor LSB fot channel 06*/ +#define MPOD_BIASCURMSB05 52 /*!<index of TX Current BIAS monitor MSB fot channel 05*/ +#define MPOD_BIASCURLSB05 53 /*!<index of TX Current BIAS monitor LSB fot channel 05*/ +#define MPOD_BIASCURMSB04 54 /*!<index of TX Current BIAS monitor MSB fot channel 04*/ +#define MPOD_BIASCURLSB04 55 /*!<index of TX Current BIAS monitor LSB fot channel 04*/ +#define MPOD_BIASCURMSB03 56 /*!<index of TX Current BIAS monitor MSB fot channel 03*/ +#define MPOD_BIASCURLSB03 57 /*!<index of TX Current BIAS monitor LSB fot channel 03*/ +#define MPOD_BIASCURMSB02 58 /*!<index of TX Current BIAS monitor MSB fot channel 02*/ +#define MPOD_BIASCURLSB02 59 /*!<index of TX Current BIAS monitor LSB fot channel 02*/ +#define MPOD_BIASCURMSB01 60 /*!<index of TX Current BIAS monitor MSB fot channel 01*/ +#define MPOD_BIASCURLSB01 61 /*!<index of TX Current BIAS monitor LSB fot channel 01*/ +#define MPOD_BIASCURMSB00 62 /*!<index of TX Current BIAS monitor MSB fot channel 00*/ +#define MPOD_BIASCURLSB00 63 /*!<index of TX Current BIAS monitor LSB fot channel 00*/ + +#define MPOD_LIGHTOUTMSB11 64 /*!<index of TX Light Output monitor MSB fot channel 11*/ +#define MPOD_LIGHTOUTLSB11 65 /*!<index of TX Light Output monitor LSB fot channel 11*/ +#define MPOD_LIGHTOUTMSB10 66 /*!<index of TX Light Output monitor MSB fot channel 10*/ +#define MPOD_LIGHTOUTLSB10 67 /*!<index of TX Light Output monitor LSB fot channel 10*/ +#define MPOD_LIGHTOUTMSB09 68 /*!<index of TX Light Output monitor MSB fot channel 09*/ +#define MPOD_LIGHTOUTLSB09 69 /*!<index of TX Light Output monitor LSB fot channel 09*/ +#define MPOD_LIGHTOUTMSB08 70 /*!<index of TX Light Output monitor MSB fot channel 08*/ +#define MPOD_LIGHTOUTLSB08 71 /*!<index of TX Light Output monitor LSB fot channel 08*/ +#define MPOD_LIGHTOUTMSB07 72 /*!<index of TX Light Output monitor MSB fot channel 07*/ +#define MPOD_LIGHTOUTLSB07 73 /*!<index of TX Light Output monitor LSB fot channel 07*/ +#define MPOD_LIGHTOUTMSB06 74 /*!<index of TX Light Output monitor MSB fot channel 06*/ +#define MPOD_LIGHTOUTLSB06 75 /*!<index of TX Light Output monitor LSB fot channel 06*/ +#define MPOD_LIGHTOUTMSB05 76 /*!<index of TX Light Output monitor MSB fot channel 05*/ +#define MPOD_LIGHTOUTLSB05 77 /*!<index of TX Light Output monitor LSB fot channel 05*/ +#define MPOD_LIGHTOUTMSB04 78 /*!<index of TX Light Output monitor MSB fot channel 04*/ +#define MPOD_LIGHTOUTLSB04 79 /*!<index of TX Light Output monitor LSB fot channel 04*/ +#define MPOD_LIGHTOUTMSB03 80 /*!<index of TX Light Output monitor MSB fot channel 03*/ +#define MPOD_LIGHTOUTLSB03 81 /*!<index of TX Light Output monitor LSB fot channel 03*/ +#define MPOD_LIGHTOUTMSB02 82 /*!<index of TX Light Output monitor MSB fot channel 02*/ +#define MPOD_LIGHTOUTLSB02 83 /*!<index of TX Light Output monitor LSB fot channel 02*/ +#define MPOD_LIGHTOUTMSB01 84 /*!<index of TX Light Output monitor MSB fot channel 01*/ +#define MPOD_LIGHTOUTLSB01 85 /*!<index of TX Light Output monitor LSB fot channel 01*/ +#define MPOD_LIGHTOUTMSB00 86 /*!<index of TX Light Output monitor MSB fot channel 00*/ +#define MPOD_LIGHTOUTLSB00 87 /*!<index of TX Light Output monitor LSB fot channel 00*/ + +/* FOR RX component ONLY on page OOh */ +#define MPOD_OPPOWERMSB11 64 /*!<index of RX optical input optical power monitor MSB fot channel 11*/ +#define MPOD_OPPOWERLSB11 65 /*!<index of RX optical input optical power monitor LSB fot channel 11*/ +#define MPOD_OPPOWERMSB10 66 /*!<index of RX optical input optical power monitor MSB fot channel 10*/ +#define MPOD_OPPOWERLSB10 67 /*!<index of RX optical input optical power monitor LSB fot channel 10*/ +#define MPOD_OPPOWERMSB09 68 /*!<index of RX optical input optical power monitor MSB fot channel 09*/ +#define MPOD_OPPOWERLSB09 69 /*!<index of RX optical input optical power monitor LSB fot channel 09*/ +#define MPOD_OPPOWERMSB08 70 /*!<index of RX optical input optical power monitor MSB fot channel 08*/ +#define MPOD_OPPOWERLSB08 71 /*!<index of RX optical input optical power monitor LSB fot channel 08*/ +#define MPOD_OPPOWERMSB07 72 /*!<index of RX optical input optical power monitor MSB fot channel 07*/ +#define MPOD_OPPOWERLSB07 73 /*!<index of RX optical input optical power monitor LSB fot channel 07*/ +#define MPOD_OPPOWERMSB06 74 /*!<index of RX optical input optical power monitor MSB fot channel 06*/ +#define MPOD_OPPOWERLSB06 75 /*!<index of RX optical input optical power monitor LSB fot channel 06*/ +#define MPOD_OPPOWERMSB05 76 /*!<index of RX optical input optical power monitor MSB fot channel 05*/ +#define MPOD_OPPOWERLSB05 77 /*!<index of RX optical input optical power monitor LSB fot channel 05*/ +#define MPOD_OPPOWERMSB04 78 /*!<index of RX optical input optical power monitor MSB fot channel 04*/ +#define MPOD_OPPOWERLSB04 79 /*!<index of RX optical input optical power monitor LSB fot channel 04*/ +#define MPOD_OPPOWERMSB03 80 /*!<index of RX optical input optical power monitor MSB fot channel 03*/ +#define MPOD_OPPOWERLSB03 81 /*!<index of RX optical input optical power monitor LSB fot channel 03*/ +#define MPOD_OPPOWERMSB02 82 /*!<index of RX optical input optical power monitor MSB fot channel 02*/ +#define MPOD_OPPOWERLSB02 83 /*!<index of RX optical input optical power monitor LSB fot channel 02*/ +#define MPOD_OPPOWERMSB01 84 /*!<index of RX optical input optical power monitor MSB fot channel 01*/ +#define MPOD_OPPOWERLSB01 85 /*!<index of RX optical input optical power monitor LSB fot channel 01*/ +#define MPOD_OPPOWERMSB00 86 /*!<index of RX optical input optical power monitor MSB fot channel 00*/ +#define MPOD_OPPOWERLSB00 87 /*!<index of RX optical input optical power monitor LSB fot channel 00*/ + +#define MPOD_ELAPSEREGMSB 88 /*!<index of elapsed operating time MSB in 2 hours units*/ +#define MPOD_ELAPSEREGLSB 88 /*!<index of elapsed operating time LSB in 2 hours units*/ +#define MPOD_SQUELCHREG1 94 /*!<index of squelch reg for channel 11 downto 8 (reg low quarter)*/ +#define MPOD_SQUELCHREG2 95 /*!<index of squelch reg for channel 7 downto 0 */ +#define MPOD_PAGEREG 127 /*!<page selection register */ +#define MPOD_VENDORNAMEREG 152 /*!<index of the register with the first byte of the name of the vendor in ASCII*/ +#define MPOD_VENDOROUIREG 168 /*!<index of the register with the first byte of the OUI as hexa values*/ +#define MPOD_VENDORPARTREG 171 /*!<index of the register with the first byte of the part number of the vendor in ASCII*/ +#define MPOD_VENDORREVREG 187 /*!<index of the register with the first byte of the revision number of the vendor in ASCII*/ +#define MPOD_VENDORSERREG 189 /*!<index of the register with the first byte of the serial number of the vendor in ASCII*/ +#define MPOD_VENDORDATEREG 205 /*!<index of the register with the first byte of the date of the vendor in ASCII*/ + +/* for TX and RX on page 00h */ +#define MPOD_RESET 91 /*!<index of register to reset all registers to factory values */ +#define MPOD_CHDISABLE1 92 /*!<index of DISABLE reg for channel 11 downto 8 (reg low quarter)*/ +#define MPOD_CHDISABLE2 93 /*!<index of DISABLE reg for channel 7 downto 0 */ +//PYD +/* for TX and RX on page 01h */ +#define MPOD_POLARFLIP1 226 /*!<index of DISABLE reg for channel 11 downto 8 (reg low quarter)*/ +#define MPOD_POLARFLIP2 227 /*!<index of DISABLE reg for channel 7 downto 0 */ +//PYD +/* for TX only on page 00h */ +#define MPOD_MARGINACT1 99 /*!<index of Margin Activation reg for channel 11 downto 8 (reg low quarter)*/ +#define MPOD_MARGINACT2 100 /*!<index of Margin Activation reg for channel 7 downto 0 */ + +/* FOR RX component ONLY on page O1h */ +#define MPOD_RXVOD6 228 /*!<index of RX output amplitude control VOD for channels 11 and 10*/ +#define MPOD_RXVOD5 229 /*!<index of RX output amplitude control VOD for channels 9 and 8*/ +#define MPOD_RXVOD4 230 /*!<index of RX output amplitude control VOD for channels 7 and 6*/ +#define MPOD_RXVOD3 231 /*!<index of RX output amplitude control VOD for channels 5 and 4*/ +#define MPOD_RXVOD2 232 /*!<index of RX output amplitude control VOD for channels 3 and 2*/ +#define MPOD_RXVOD1 233 /*!<index of RX output amplitude control VOD for channels 1 and 0*/ +/* FOR TX component ONLY on page O1h */ +#define MPOD_TXEQUALZ6 228 /*!<index of RX output equalization control for channels 11 and 10*/ +#define MPOD_TXEQUALZ5 229 /*!<index of RX output equalization control for channels 9 and 8*/ +#define MPOD_TXEQUALZ4 230 /*!<index of RX output equalization control for channels 7 and 6*/ +#define MPOD_TXEQUALZ3 231 /*!<index of RX output equalization control for channels 5 and 4*/ +#define MPOD_TXEQUALZ2 232 /*!<index of RX output equalization control for channels 3 and 2*/ +#define MPOD_TXEQUALZ1 233 /*!<index of RX output equalization control for channels 1 and 0*/ + +/* FOR RX component ONLY on page O1h */ +#define MPOD_RXDEAMPH6 234 /*!<index of RX output deamphasis control for channels 11 and 10*/ +#define MPOD_RXDEAMPH5 235 /*!<index of RX output deamphasis control for channels 9 and 8*/ +#define MPOD_RXDEAMPH4 236 /*!<index of RX output deamphasis control for channels 7 and 6*/ +#define MPOD_RXDEAMPH3 237 /*!<index of RX output deamphasis control for channels 5 and 4*/ +#define MPOD_RXDEAMPH2 238 /*!<index of RX output deamphasis control for channels 3 and 2*/ +#define MPOD_RXDEAMPH1 239 /*!<index of RX output deamphasis control for channels 1 and 0*/ + + +#define MPOD_NBVENDORNAME 15 /*!<size in register of the vendor name "AVAGO"*/ +#define MPOD_NBVENDOROUI 3 /*!<size in register of the vendor OUI (IEEE ID) "OOh 17h 6Ah" for AVAGO*/ +#define MPOD_NBVENDORPART 16 /*!<size in register of the vendor part number in ascii "AFBR-811FN1Z"*/ +#define MPOD_NBVENDORREV 2 /*!<size in register of the vendor revision number in ASCII: coded with space (20h)*/ +#define MPOD_NBVENDORSER 16 /*!<size in register of the vendor serial number in ASCII*/ +#define MPOD_NBVENDORDATE 8 /*!<size in register of the vendor date code YYYYMMDD (ASCII)*/ + +#ifdef MPOCPP +extern "C" { +#endif + +/* public functions */ +int mpod_setMode (int mode); +int mpod_setTextMode (int mode); +int mpod_exists (int mpid); +int mpod_init (int dev, unsigned inCLK, unsigned SCLfreq); +void mpod_getInit (int dev, unsigned *inCLK, unsigned *SCLfreq); +int mpod_isTX (int mpid); +int mpod_isRX (int mpid); +int mpod_dumpErrStatus (int dev, int mpid); +int mpod_dumpErrStatusAll(int dev); +int mpod_dumpVendorData (int dev, int mpid); +int mpod_getVendorName (int dev, int mpid, char **bloc); +int mpod_getVendorOUI (int dev, int mpid, char **bloc); +int mpod_getVendorPartNumber (int dev, int mpid, char **bloc); +int mpod_getVendorRevNumber (int dev, int mpid, char **bloc); +int mpod_getVendorDate (int dev, int mpid, char **bloc); +int mpod_getVendorSerialNumber(int dev, int mpid, char **bloc); +int mpod_squelchDisable (int dev, int mpid , int channel , int disable); +int mpod_squelchDisableAll (int dev, int mpid, int disable); +int mpod_squelchDumpAll (int dev, int mpid); +int mpod_losDumpAll (int dev, int mpid); +int mpod_faultDumpAll (int dev, int mpid); +int mpod_internalTemp (int dev, int mpid, int *temp); +int mpod_internalTempDumpAll(int dev); +int mpod_internal33Vcc (int dev, int mpid, int *vcc); +int mpod_internal33VccDumpAll(int dev); +int mpod_internal25Vcc (int dev, int mpid, int *vcc); +int mpod_internal25VccDumpAll(int dev); +int mpod_biasCurrent (int dev, int mpid, float **data); +int mpod_getBiasCurrent (int dev, int mpid, float *data); +int mpod_lightOutput (int dev, int mpid, float **data); +int mpod_getLightOutput (int dev, int mpid, float *data); +int mpod_lightInput (int dev, int mpid, float **data); +int mpod_getlightInput (int dev, int mpid, float *data); +int mpod_elapsedPowerOn (int dev, int mpid, int *dur); +int mpod_reset (int dev, int mpid); +int mpod_channelDisable (int dev, int mpid, int channel, int flag); +int mpod_channelDisDumpAll (int dev, int mpid); +//PYD +int mpod_polarityFlip (int dev, int mpid, int channel, int flag); +int mpod_channelPolarFlipDumpAll(int dev, int mpid); +//PYD +int mpod_marginActivation (int dev, int mpid, int channel, int flag); +int mpod_marginActDumpAll (int dev, int mpid); + +int mpod_readVOD (int dev, int mpid, int **data); +int mpod_getVOD (int dev, int mpid, int *data); +int mpod_readVODSingle (int dev, int mpid, int channel, int *code); +int mpod_writeVOD (int dev, int mpid, int *data); +int mpod_writeVODSingle (int dev, int mpid, int channel, int code); + +int mpod_readDeamphasis (int dev, int mpid, int **data); +int mpod_getDeamphasis (int dev, int mpid, int *data); +int mpod_readDeamphasisSingle (int dev, int mpid, int channel, int *code); +int mpod_writeDeamphasis (int dev, int mpid, int *data); +int mpod_writeDeamphasisSingle(int dev, int mpid, int channel, int code); + +int mpod_readEqualization (int dev, int mpid, int **data); +int mpod_getEqualization (int dev, int mpid, int *data); +int mpod_readEqualizationSingle (int dev, int mpid, int channel, int *code); +int mpod_writeEqualization (int dev, int mpid, int *data); +int mpod_writeEqualizationSingle(int dev, int mpid, int channel, int code); + +#ifdef MPOCPP +} +#endif -- GitLab