KM3NeT CLB  2.0
KM3NeT CLB v2 Embedded Software
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
promis.c
1 /*
2  * KM3NeT CLB v2 Firmware
3  * ----------------------
4  *
5  * Copyright 2013 KM3NeT Collaboration
6  *
7  * All Rights Reserved.
8  *
9  *
10  * File : promis.c
11  * Created : 22 jan. 2014
12  * Author : Vincent van Beveren
13  */
14 #include "drv/i2c/promis.h"
15 
16 #include "util/macro.h"
17 #include <stdio.h>
18 #include "kernel/tm.h"
19 
20 #define PRMS_ID_DELAY_MS 2
21 
22 #define PRMS_REG_THR_DAC 0x00
23 #define PRMS_REG_HV_DAC 0x01
24 #define PRMS_REG_CMDSTS 0x02
25 #define PRMS_REG_ID 0x08
26 
27 #define PRMS_CMD_PROM_READ BIT(0)
28 #define PRMS_CMD_HV_ON_OFF BIT(2)
29 #define PRMS_CMD_CHAIN_TEST BIT(3)
30 #define PRMS_CMD_ANA_BUF BIT(6)
31 
32 static bool prmsRMWCmd(I2C_Device * dev, uint8_t addr, uint8_t val, uint8_t mask)
33 {
34  uint8_t regVal;
35  if (!i2cReadReg(dev, addr, PRMS_REG_CMDSTS, &regVal, sizeof(regVal))) return errRebase("Promis");
36  regVal = ((regVal & ~mask) | (val & mask));
37 
38  return i2cWriteReg(dev, addr, PRMS_REG_CMDSTS, &regVal, sizeof(regVal));
39 }
40 
41 bool prmsID(I2C_Device * dev, uint8_t addr, uint8_t * id)
42 {
43  // assumption: PMT just powered
44  uint8_t autoLoadId[3];
45  if (!i2cReadReg(dev, addr, PRMS_REG_ID, autoLoadId, 3)) return errRebase("Promis");
46 
47  // toggle the PMT read bit, forcing the state machine
48  // to re-read the PMT ID
49  if (!prmsRMWCmd(dev, addr, PRMS_CMD_PROM_READ, PRMS_CMD_PROM_READ)) return errRebase("Promis");
50  if (!prmsRMWCmd(dev, addr, 0, PRMS_CMD_PROM_READ)) return errRebase("Promis");
51 
52  // wait for at least 1.3ms (>2 in our case)
53  timeDelay(PRMS_ID_DELAY_MS);
54 
55  if (!i2cReadReg(dev, addr, PRMS_REG_ID, id, 3)) return errRebase("Promis");
56 
57  // swap first and last, since we read the LSByte first
58  uint8_t t = id[0];
59  id[0] = id[2];
60  id[2] = t;
61 
62  if (id[0] != autoLoadId[2] || id[1] != autoLoadId[1] || id[2] != autoLoadId[0])
63  return errSet(ERROR(E_PRMS_ID_FAULT));
64 
65  return true;
66 }
67 
68 bool prmsSetConfig(I2C_Device * dev, uint8_t addr, PrmsConfig * cfg)
69 {
70  uint8_t dacVals[2] = { cfg->threshold, cfg->highVolt };
71 
72  return i2cWriteReg(dev, addr, PRMS_REG_THR_DAC, dacVals, sizeof(dacVals));
73 }
74 
75 bool prmsGetConfig(I2C_Device * dev, uint8_t addr, PrmsConfig * cfg)
76 {
77  uint8_t dacVals[2];
78 
79  if (!i2cReadReg(dev, addr, PRMS_REG_THR_DAC, dacVals, sizeof(dacVals))) return errRebase("Promis");
80 
81  cfg->threshold = dacVals[0];
82  cfg->highVolt = dacVals[1];
83  return true;
84 }
85 bool prmsHighVolt(I2C_Device * dev, uint8_t addr, bool enable)
86 {
87  return prmsRMWCmd(dev, addr, (enable ? PRMS_CMD_HV_ON_OFF : 0), PRMS_CMD_HV_ON_OFF);
88 }
89 
90 bool prmsChainTest(I2C_Device * dev, uint8_t addr)
91 {
92  // set threshold DAC to 1.05V
93  uint8_t dacVal = PRMS_THRS_MV2DAC(1050);
94  if (!i2cWriteReg(dev, addr, PRMS_REG_THR_DAC, &dacVal, sizeof(dacVal))) return errRebase("Promis");
95 
96  // toggle CHAIN_TEST to 1
97  if (!prmsRMWCmd(dev, addr, PRMS_CMD_CHAIN_TEST,
98  PRMS_CMD_HV_ON_OFF | PRMS_CMD_CHAIN_TEST)) return errRebase("Promis");
99 
100  // toggle CHAIN_TEST to 0
101  return prmsRMWCmd(dev, addr, 0,
102  PRMS_CMD_HV_ON_OFF | PRMS_CMD_CHAIN_TEST);
103 }
104 
105 bool prmsStatus(I2C_Device * dev, uint8_t addr, PrmsStatus * status)
106 {
107  uint8_t cmdsts;
108  if (!i2cReadReg(dev, addr, PRMS_REG_CMDSTS, &cmdsts, sizeof(cmdsts))) return errRebase("Promis");
109  status->anaBuf = ( cmdsts & PRMS_CMD_ANA_BUF ) != 0;
110  status->highVoltOn = ( cmdsts & PRMS_CMD_HV_ON_OFF ) != 0;
111  return true;
112 }
Configuration struct.
Definition: promis.h:82
Status struct.
Definition: promis.h:90
bool prmsChainTest(I2C_Device *dev, uint8_t addr)
Executes a chain test.
Definition: promis.c:90
Structure defines OpenCores I2C Device.
Definition: dev_i2c.h:55
#define E_PRMS_ID_FAULT
PROMiS ID is not consistent.
Definition: promis.h:34
bool prmsID(I2C_Device *dev, uint8_t addr, uint8_t *id)
Returns the burned ID of the PROMiS device.
Definition: promis.c:41
void timeDelay(uint32_t msec)
Simple busy-wait delay.
Definition: tm.c:18
bool i2cReadReg(I2C_Device *dev, i2cAddr addr, uint8_t regNo, uint8_t *rd, int rdLen)
Reads from the I2C device register.
Definition: i2c.c:188
bool i2cWriteReg(I2C_Device *dev, i2cAddr addr, uint8_t regNo, uint8_t *wr, int wrLen)
Writes to the I2C device register.
Definition: i2c.c:247
bool prmsGetConfig(I2C_Device *dev, uint8_t addr, PrmsConfig *cfg)
Gets the configuration from the PROMiS device.
Definition: promis.c:75
uint8_t threshold
threshold DAC value
Definition: promis.h:83
bool anaBuf
Analog buffer.
Definition: promis.h:92
Simple timer functions.
static bool errRebase(const char *name)
Rebases the cause of the error message.
Definition: err.h:104
bool prmsSetConfig(I2C_Device *dev, uint8_t addr, PrmsConfig *cfg)
Sets the configuration on the PROMiS device.
Definition: promis.c:68
uint8_t highVolt
high voltage DAC value
Definition: promis.h:84
bool highVoltOn
High voltage on.
Definition: promis.h:91
This driver interfaces with the PROMiS PMT ASIC.
bool prmsHighVolt(I2C_Device *dev, uint8_t addr, bool enable)
Enables/Disables the high voltage.
Definition: promis.c:85
bool errSet(uint32_t code, const char *error, const char *name)
Sets an error.
#define ERROR(CODE,...)
Expands an error code to an error code with a description (if ERROR_W_DESCR is declared).
#define PRMS_THRS_MV2DAC(MV)
Converts a threshold value in milliVolts to the DAC value.
Definition: promis.h:45
Provides common macros.
bool prmsStatus(I2C_Device *dev, uint8_t addr, PrmsStatus *status)
Returns the status of the PROMiS device.
Definition: promis.c:105