Skip to content

Commit

Permalink
Add temperature readout, basic hybrid config.
Browse files Browse the repository at this point in the history
  • Loading branch information
bl0x committed Aug 10, 2022
1 parent 4045165 commit 069e1c7
Show file tree
Hide file tree
Showing 5 changed files with 155 additions and 47 deletions.
21 changes: 13 additions & 8 deletions apps/srscli/main.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include <stdio.h>
#include <fec.h>
#include <udp_socket.h>

int
main(int argc, char *argv[])
Expand Down Expand Up @@ -28,28 +29,32 @@ main(int argc, char *argv[])

fec_write_set_mask(fec);

fec_i2c_read_adc(fec, 0);
fec_i2c_read_adc(fec, 1);
fec_i2c_read_adc(fec, 2);

{
uint32_t fw;
fw = fec_do_read_hybrid_firmware(fec);
printf("hybrid firmware = 0x%08x\n\n", fw);
printf("hybrid firmware = 0x%08x\n", fw);
}
{
uint32_t pos;
pos = fec_do_read_geo_pos(fec);
printf("hybrid geo pos = 0x%08x\n\n", pos);
printf("hybrid geo pos = 0x%08x\n", pos);
}
{
uint32_t id[4];
fec->hybrid_index = 4;
fec->hybrid_index = 0;
fec_do_read_id_chip(fec, id);
printf("hybrid id = 0x%08x:%08x:%08x:%08x\n\n",
printf("hybrid id = 0x%08x:%08x:%08x:%08x\n",
id[0], id[1], id[2], id[3]);
}

/*
* fec->config.debug = 1;
* fec->socket->config.debug = 1;
*/
fec_write_configure_hybrid(fec);

fec_do_read_adc(fec, 2);

/*
* does not work with all FEC firmwares.
* not with CLOCK_SOURCE > 1
Expand Down
50 changes: 36 additions & 14 deletions include/fec.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,24 @@

#include <stdint.h>

#define FEC_DEFAULT_FEC_PORT 6007
#define FEC_DEFAULT_VMMAPP_PORT 6600
#define FEC_DEFAULT_DVMI2C_PORT 6601
#define FEC_DEFAULT_I2C_PORT 6604
#define FEC_DEFAULT_FEC_PORT 6007
#define FEC_DEFAULT_FEC_SYS_PORT 6023
#define FEC_DEFAULT_VMMAPP_PORT 6600
#define FEC_DEFAULT_DVMI2C_PORT 6601
#define FEC_DEFAULT_S6_PORT 6602
#define FEC_DEFAULT_VMMASIC_PORT 6603
#define FEC_DEFAULT_I2C_PORT 6604
#define FEC_DEFAULT_DAQ_PORT 6606

#define FEC_DEFAULT_IP "10.0.0.2"

#define FEC_CMD_WRITE 0xaa
#define FEC_CMD_READ 0xbb
#define FEC_CMD_TYPE_LIST 0xaa
#define FEC_CMD_TYPE_PAIRS 0xaa
#define FEC_CMD_LENGTH 0xffff
#define FEC_CMD_WRITE 0xaa
#define FEC_CMD_READ 0xbb
#define FEC_CMD_TYPE_LIST 0xaa
#define FEC_CMD_TYPE_PAIRS 0xaa
#define FEC_CMD_LENGTH 0xffff

#define FEC_ADC_CH_TEMPERATURE 2

#define HYBRID_ADC_TDO 0
#define HYBRID_ADC_PDO 1
Expand All @@ -35,6 +42,13 @@ struct FecConfig
uint32_t tp_offset;
uint32_t tp_latency;
uint32_t tp_number;
uint32_t tp_skew;
uint32_t tp_width;
uint32_t tp_polarity;
uint32_t ckbc_skew;
uint32_t ckbc;
uint32_t ckdt;
int debug;
};

enum FecState
Expand All @@ -51,6 +65,7 @@ struct Fec
uint32_t packet_counter;
uint8_t hybrid_map;
uint8_t hybrid_index;
uint8_t adc_channel;
const uint8_t *hybrid_index_map;
enum FecState state;
struct I2C
Expand Down Expand Up @@ -99,14 +114,14 @@ void fec_prepare_send_buffer(struct Fec *, uint8_t, uint8_t, uint16_t);
#define FEC_READ(name, port) \
int fec_read_##name(struct Fec *self) \
{ \
printf("fec_read_" #name "\n"); \
if (self->config.debug == 1) {printf("fec_read_" #name "\n");} \
return fec_rw(self, port, &fec_prepare_##name, &fec_decode_##name); \
}

#define FEC_WRITE(name, port) \
int fec_write_##name(struct Fec *self) \
{ \
printf("fec_write_" #name "\n"); \
if (self->config.debug == 1) {printf("fec_write_" #name "\n");} \
return fec_rw(self, port, &fec_prepare_##name, &fec_decode_##name); \
}

Expand All @@ -118,8 +133,11 @@ void fec_prepare_send_buffer(struct Fec *, uint8_t, uint8_t, uint16_t);
self->i2c.address = i2c_address; \
self->i2c.reg = reg_value; \
self->i2c.data = data; \
printf("fec_i2c_" #name "[hybrid=%d,addr=0x%x,reg=0x%x,data=0x%x]\n", \
self->hybrid_index, i2c_address, reg_value, data); \
if (self->config.debug == 1) { \
printf("fec_i2c_" #name \
"[hybrid=%d,addr=0x%x,reg=0x%x,data=0x%x]\n", \
self->hybrid_index, i2c_address, reg_value, data); \
} \
rc = fec_rw(self, port, &fec_prepare_i2c_##name, \
&fec_decode_i2c_##name); \
assert(rc == 0); \
Expand All @@ -130,7 +148,9 @@ void fec_prepare_send_buffer(struct Fec *, uint8_t, uint8_t, uint16_t);
int fec_i2c_##name(struct Fec *self, int sequence) \
{ \
self->i2c.sequence = sequence; \
printf("fec_i2c_" #name "[sequence=%d]\n", sequence); \
if (self->config.debug == 1) { \
printf("fec_i2c_" #name "[sequence=%d]\n", sequence); \
} \
return fec_rw(self, port, &fec_prepare_i2c_##name, \
&fec_decode_i2c_##name); \
}
Expand All @@ -153,6 +173,7 @@ FEC_WRITE_FUNCTION_DECL(reset);
FEC_WRITE_FUNCTION_DECL(acq_on);
FEC_WRITE_FUNCTION_DECL(acq_off);
FEC_WRITE_FUNCTION_DECL(set_mask);
FEC_WRITE_FUNCTION_DECL(configure_hybrid);
FEC_I2C_SEQ_FUNCTION_DECL(read_adc);
FEC_I2C_FUNCTION_DECL(write);
FEC_I2C_FUNCTION_DECL(read8);
Expand All @@ -166,3 +187,4 @@ void fec_do_powercycle_hybrids(struct Fec *);
uint32_t fec_do_read_hybrid_firmware(struct Fec *);
uint32_t fec_do_read_geo_pos(struct Fec *);
void fec_do_read_id_chip(struct Fec *, uint32_t *);
void fec_do_read_adc(struct Fec *, uint8_t);
1 change: 1 addition & 0 deletions include/udp_socket.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ struct UdpSocketConfig
in_port_t port;
struct sockaddr_in remote;
unsigned int receive_timeout_usec;
int debug;
};

struct UdpSocket
Expand Down
112 changes: 92 additions & 20 deletions src/fec.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ fec_new()
fec->packet_counter = 0;
fec->hybrid_map = 0;
fec->hybrid_index = 0;
fec->adc_channel = 0;
fec->state = FEC_STATE_FRESH;

fec_default_config(fec);
Expand Down Expand Up @@ -47,6 +48,7 @@ void
fec_default_config(struct Fec *self)
{
self->config.debug_data_format = 0;
self->config.debug = 0;
self->config.latency_reset = 47;
self->config.latency_data_max = 4087;
self->config.latency_data_error = 8;
Expand All @@ -55,6 +57,14 @@ fec_default_config(struct Fec *self)
self->config.tp_latency = 65;
self->config.tp_number = 1;
self->config.clock_source = 2;
/* from fec_config_module.cpp */
self->config.ckdt = 3;
self->config.ckbc = 2;
self->config.ckbc_skew = 0;
/* hybrid */
self->config.tp_skew = 0;
self->config.tp_width = 0;
self->config.tp_polarity = 0;
}

int
Expand Down Expand Up @@ -146,6 +156,46 @@ fec_prepare_trigger_acq_constants(struct Fec *self)
free(array);
}

void
fec_prepare_configure_hybrid(struct Fec *self)
{
size_t len;
uint16_t hybrid_map = (1 << self->hybrid_index);
uint32_t *array;

if (self->config.clock_source == 3) {
uint32_t test_pulser_config;
uint32_t clock_bunch_counter_config;
uint32_t clock_data_config;

test_pulser_config = (self->config.tp_polarity << 7)
| (self->config.tp_width << 4)
| self->config.tp_skew;

clock_bunch_counter_config = (self->config.ckbc_skew << 4)
| self->config.ckbc;

clock_data_config = self->config.ckdt * 2;

len = 7;
array = util_fill_array32(len, 0,
2, test_pulser_config,
7, clock_bunch_counter_config,
5, clock_data_config);
} else {
len = 7;
array = util_fill_array32(len, 0,
2, self->config.tp_skew,
3, self->config.tp_width,
4, self->config.tp_polarity);
}

fec_prepare_send_buffer(self, FEC_CMD_WRITE, FEC_CMD_TYPE_PAIRS,
hybrid_map);
udp_sendbuf_push_array32(self->socket, array, len);
free(array);
}

/*
* note: communicating with a PCA9534 chip (8 bit I2C register)
* note: this does not work with all FEC firmwares.
Expand Down Expand Up @@ -209,7 +259,7 @@ void
fec_prepare_i2c_read_adc(struct Fec *self)
{
size_t len = 3;
uint8_t adc_channel = 0; /* TODO: Make configurable */
uint8_t adc_channel = self->adc_channel;
uint8_t i2c_address = 0x48 + (self->hybrid_index % 2);
uint8_t hybrid_bit = self->hybrid_index_map[self->hybrid_index];
uint8_t hybrid_map = (1 << hybrid_bit);
Expand Down Expand Up @@ -306,6 +356,7 @@ FEC_WRITE(trigger_acq_constants, FEC_DEFAULT_VMMAPP_PORT)
FEC_WRITE(acq_on, FEC_DEFAULT_VMMAPP_PORT)
FEC_WRITE(acq_off, FEC_DEFAULT_VMMAPP_PORT)
FEC_WRITE(set_mask, FEC_DEFAULT_VMMAPP_PORT)
FEC_WRITE(configure_hybrid, FEC_DEFAULT_S6_PORT)
FEC_I2C_SEQ(read_adc, FEC_DEFAULT_I2C_PORT)
FEC_I2C(write, FEC_DEFAULT_I2C_PORT)
FEC_I2C(read8, FEC_DEFAULT_I2C_PORT)
Expand Down Expand Up @@ -387,29 +438,30 @@ fec_decode_system_registers(struct Fec *self)
main_clock_status = ntohl(*(uint32_t *)(buf + 124));
firmware_reg = ntohl(*(uint32_t *)(buf + 140));

printf("firmware = 0x%08x\n", firmware);
printf("mac_vendor = 0x%08x\n", mac_vendor);
printf("mac_device = 0x%08x\n", mac_device);
printf("fec_ip = 0x%08x (%d.%d.%d.%d)\n", fec_ip,
printf("FEC System registers:\n");
printf(" firmware = 0x%08x\n", firmware);
printf(" mac_vendor = 0x%08x\n", mac_vendor);
printf(" mac_device = 0x%08x\n", mac_device);
printf(" fec_ip = 0x%08x (%d.%d.%d.%d)\n", fec_ip,
((uint8_t*)&fec_ip)[3],
((uint8_t*)&fec_ip)[2],
((uint8_t*)&fec_ip)[1],
((uint8_t*)&fec_ip)[0]);
printf("udp_data_port = 0x%04x (dec: %d)\n", udp_data, udp_data);
printf("udp_sc_port = 0x%04x (dec: %d)\n", udp_sc, udp_sc);
printf("udp_frame_delay = 0x%04x\n", udp_delay);
printf("date_flow_par = 0x%04x\n", date_flow);
printf("eth_ctrl_reg = 0x%04x\n", eth);
printf("sc_ctrl_reg = 0x%04x\n", sc_mode);
printf("daq_dest_ip = 0x%08x (%d.%d.%d.%d)\n", daq_ip,
printf(" udp_data_port = 0x%04x (dec: %d)\n", udp_data, udp_data);
printf(" udp_sc_port = 0x%04x (dec: %d)\n", udp_sc, udp_sc);
printf(" udp_frame_delay = 0x%04x\n", udp_delay);
printf(" date_flow_par = 0x%04x\n", date_flow);
printf(" eth_ctrl_reg = 0x%04x\n", eth);
printf(" sc_ctrl_reg = 0x%04x\n", sc_mode);
printf(" daq_dest_ip = 0x%08x (%d.%d.%d.%d)\n", daq_ip,
((uint8_t*)&daq_ip)[3],
((uint8_t*)&daq_ip)[2],
((uint8_t*)&daq_ip)[1],
((uint8_t*)&daq_ip)[0]);
printf("dtc_link_ctrl_reg = 0x%08x\n", dtc_link);
printf("main_clock_select_reg = 0x%08x\n", main_clock);
printf("main_clock_status = 0x%08x\n", main_clock_status);
printf("firmware_reg = 0x%08x\n", firmware_reg);
printf(" dtc_link_ctrl_reg = 0x%08x\n", dtc_link);
printf(" main_clock_select_reg = 0x%08x\n", main_clock);
printf(" main_clock_status = 0x%08x\n", main_clock_status);
printf(" firmware_reg = 0x%08x\n", firmware_reg);
}

FEC_DECODE_DEFAULT(trigger_acq_constants, 80)
Expand All @@ -419,14 +471,17 @@ FEC_DECODE_DEFAULT(acq_on, 24)
FEC_DECODE_DEFAULT(acq_off, 24)
FEC_DECODE_DEFAULT(set_mask, 24)
FEC_DECODE_DEFAULT(i2c_write, 24)
FEC_DECODE_DEFAULT(configure_hybrid, 40)

void
fec_decode_i2c_read8(struct Fec *self)
{
uint8_t value;
assert(self->socket->receivedlen == 24);
value = self->socket->recvbuf[23];
printf("register value (8-bit): %u (0x%02x)\n", value, value);
if (self->config.debug == 1) {
printf("register value (8-bit): %u (0x%02x)\n", value, value);
}
self->i2c.result = value;
}

Expand All @@ -436,7 +491,9 @@ fec_decode_i2c_read32(struct Fec *self)
uint32_t value;
assert(self->socket->receivedlen == 24);
value = ntohl(((uint32_t *)self->socket->recvbuf)[5]);
printf("register value (32-bit): %u (0x%08x)\n", value, value);
if (self->config.debug == 1) {
printf("register value (32-bit): %u (0x%08x)\n", value, value);
}
self->i2c.result = value;
}

Expand All @@ -449,7 +506,7 @@ fec_decode_i2c_read_adc(struct Fec *self)
if (self->i2c.sequence == 2) {
uint16_t adc_value = ntohs(
((uint16_t *)self->socket->recvbuf)[11]) >> 4;
printf("adc_value: %u\n", adc_value);
self->i2c.result = adc_value;
}

/*
Expand Down Expand Up @@ -493,7 +550,22 @@ fec_do_read_id_chip(struct Fec *self, uint32_t *id /* fixed len 4 */)
uint32_t data;
fec_i2c_write(self, 88, 0x80, 0);
data = fec_i2c_read32(self, 88, 0, n * 4);
printf("data = %08x\n", data);
/* printf("data = %08x\n", data); */
id[n - 1] = data;
}
}

void
fec_do_read_adc(struct Fec *self, uint8_t ch)
{
self->adc_channel = ch;
fec_i2c_read_adc(self, 0);
fec_i2c_read_adc(self, 1);
fec_i2c_read_adc(self, 2);

if (ch == FEC_ADC_CH_TEMPERATURE) {
float t = (float)(725 - self->i2c.result) / 1.85f;
printf("temperature = %.1f\n", t);
}
printf("adc value [%u] = %d\n", ch, self->i2c.result);
}
Loading

0 comments on commit 069e1c7

Please sign in to comment.