Skip to content

Commit

Permalink
Merge branch 'master' into dev_zynqmon_path
Browse files Browse the repository at this point in the history
  • Loading branch information
pkotamnives authored Jun 30, 2023
2 parents 0435b16 + bc04d3f commit 26f1476
Show file tree
Hide file tree
Showing 17 changed files with 286 additions and 470 deletions.
11 changes: 7 additions & 4 deletions common/power_ctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,6 @@ struct gpio_pin_t oks[] = {
// REV 2
//
// ------------------------------------------
// add here
// if you update this you need to update N_PS_ENABLES
static const struct gpio_pin_t enables[] = {
{ EN_F1_INT, "EN_F1_INT", 1},
Expand All @@ -87,7 +86,11 @@ static const struct gpio_pin_t enables[] = {
{ EN_F2_AVTT, "EN_F2_AVTT", 5},
};

//if you update this you need to update N_PS_OKS too
// if you update this you need to update N_PS_OKS too
// note we do _not_ include the PG for the 4V0 supply, though it exists.
// this is because the supply is turned on automatically at L2
// but only enabled for the fireflies at L6. At L6 we don't actually
// turn on the supplies, but instead enable them for the fireflies.
const
struct gpio_pin_t oks[N_PS_OKS] = {
{ PG_F1_INT_A, "PG_F1_INT_A", 1},
Expand All @@ -102,7 +105,7 @@ struct gpio_pin_t oks[N_PS_OKS] = {
{ PG_F2_AVCC, "PG_F2_AVCC", 4},
{ PG_F1_AVTT, "PG_F1_AVTT", 5},
{ PG_F2_AVTT, "PG_F2_AVTT", 5},
{ PG_4V0, "PG_4V0", 6}, // enable_3v8(true/false) won't change PG_4V0. Only within 10s after 4.0V off, PG_4V0 can be 0x0.
//{ PG_4V0, "PG_4V0", 6}, // enable_3v8(true/false) won't change PG_4V0. Only within 10s after 4.0V off, PG_4V0 can be 0x0.
};

#else
Expand Down Expand Up @@ -156,7 +159,7 @@ bool disable_ps(void)
bool all_ready = true;
for (int o = 0; o < N_PS_OKS; ++o) {
if (oks[o].priority >= prio) {
int8_t val = read_gpio_pin(oks[o].pin_number);
uint8_t val = read_gpio_pin(oks[o].pin_number);
if (val == 1) { // all supplies are supposed to be off now
all_ready = false;
states[o] = PWR_UNKNOWN;
Expand Down
12 changes: 2 additions & 10 deletions common/power_ctl.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,10 @@ void setPSStatus(int i, enum ps_state theState);
#define PS_OKS_F1_MASK_L2 0x0030U // these two pins are common to VU and KU
#define PS_OKS_F1_MASK_L4 0x0300U
#define PS_OKS_F1_MASK_L5 0x0C00U
#define PS_OKS_F1_MASK_L6 0x0000U // no 4v0 pin in REV1
#define PS_OKS_F2_MASK_L1 0x000CU
#define PS_OKS_F2_MASK_L2 PS_OKS_F1_MASK_L2
#define PS_OKS_F2_MASK_L4 0x00C0U
#define PS_OKS_F2_MASK_L5 0x3000U
#define PS_OKS_F2_MASK_L6 0x0000U // no 4v0 pin in REV1

#elif defined(REV2) // Rev 2
// -----------------------------------------------------
Expand All @@ -83,11 +81,11 @@ void setPSStatus(int i, enum ps_state theState);
// Number of enable and power good/OK pins

#define N_PS_ENABLES 10
#define N_PS_OKS 13
#define N_PS_OKS 12
#define PS_OKS_MASK ((1U << N_PS_OKS) - 1)
#define PS_OKS_F1_MASK 0x543U
#define PS_OKS_F2_MASK 0xA8CU
#define PS_OKS_GEN_MASK 0x1030U // includes 4v0 pin
#define PS_OKS_GEN_MASK 0x030U
#define PS_ENS_MASK ((1U << N_PS_ENABLES) - 1)
#define PS_ENS_GEN_MASK 0x00CU
#define PS_ENS_F1_MASK 0x151U
Expand All @@ -101,17 +99,11 @@ void setPSStatus(int i, enum ps_state theState);
#define PS_OKS_F1_MASK_L3 0x040U
#define PS_OKS_F1_MASK_L4 0x100U
#define PS_OKS_F1_MASK_L5 0x400U
#define PS_OKS_F1_MASK_L6 0x1000U // this one pin is common to F1 and F2
#define PS_OKS_F2_MASK_L1 0x00CU
#define PS_OKS_F2_MASK_L2 PS_OKS_F1_MASK_L2
#define PS_OKS_F2_MASK_L3 0x080U
#define PS_OKS_F2_MASK_L4 0x200U
#define PS_OKS_F2_MASK_L5 0x800U
#define PS_OKS_F2_MASK_L6 PS_OKS_F1_MASK_L6

//#error "Missing Rev 2 PS masks"
#else
#error "Must define either Rev1 or Rev2"
#endif // REV 2

bool turn_on_ps(uint16_t);
Expand Down
6 changes: 5 additions & 1 deletion common/utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ static const char *ebuf_errstrings[] = {
"I2C error",
"Power Failure CLEAR",
"Volt High (GEN FPGA1 FPGA2)",
"Clock Init failed",
};
#define EBUF_N_ERRSTRINGS (sizeof(ebuf_errstrings) / sizeof(ebuf_errstrings[0]))

Expand Down Expand Up @@ -197,9 +198,12 @@ int errbuffer_get_messagestr(const uint32_t word, char *m, size_t s)
case EBUF_I2C:
copied += snprintf(m + copied, s - copied, " (dev = %c)", (char)errdata);
break;
case EBUF_CLKINIT_FAILURE:
copied += snprintf(m + copied, s - copied, " ");
break;
default:
if (errcode > EBUF_WITH_DATA) {
copied += snprintf(m + copied, s - copied, "%d", errdata);
copied += snprintf(m + copied, s - copied, "0x%02x", errdata);
}
break;
}
Expand Down
1 change: 1 addition & 0 deletions common/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ uint64_t read_eeprom_multi(uint32_t addr);
#define EBUF_I2C 15
#define EBUF_PWR_FAILURE_CLR 16
#define EBUF_VOLT_HIGH 17
#define EBUF_CLKINIT_FAILURE 18

// Restart Reasons, values of reset cause (RESC) register,
// at 0x5c offset in TM4C1290NCPDT
Expand Down
167 changes: 69 additions & 98 deletions projects/cm_mcu/AlarmUtilities.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

#include "common/log.h"
#include "common/pinsel.h"
#include <assert.h>
#include <math.h>

///////////////////////////////////////////////////////////
//
Expand Down Expand Up @@ -172,119 +174,86 @@ uint32_t getVoltAlarmStatus(void)
}
// check the current voltage status.
// returns +1 for warning, +2 or higher for error
// these flags represent positions into thestruct ADC_Info_t ADCs[] array in
// the ADCMonitorTask.c
#ifdef REV1
#define VALM_BASE_MASK 0x00025U // management powers, e.g. 12V and M3V3
#define VALM_GEN_MASK 0x0001AU // common powers
#define VALM_F1_MASK 0xCCC80U // F1-specific
#define VALM_F2_MASK 0x33340U // F2-specific
#define VALM_ALL_MASK (VALM_BASE_MASK | VALM_GEN_MASK | VALM_F1_MASK | VALM_F2_MASK)
#define VALM_HIGHEST_V_CH 19 // highest channel that contains a voltage, 0 based counting
#elif REV2
#define VALM_BASE_MASK 0x003U // management powers, e.g. 12V and M3V3
#define VALM_GEN_MASK 0x001CU // common powers
#define VALM_F1_MASK 0x01E0U // F1-specific
#define VALM_F2_MASK 0x1E00U // F2-specific
#define VALM_ALL_MASK (VALM_BASE_MASK | VALM_GEN_MASK | VALM_F1_MASK | VALM_F2_MASK)
#define VALM_HIGHEST_V_CH 12 // highest channel that contains a voltage, 0 based counting
#endif // REV2
int VoltStatus(void)
{

// compile-time sanity check on the flags being unique.
// I need the +1 in the 1<xx since the highest channel is 0-based counting.
static_assert((VALM_BASE_MASK ^ VALM_GEN_MASK ^ VALM_F1_MASK ^ VALM_F2_MASK) == ((1 << (VALM_HIGHEST_V_CH + 1)) - 1), "VALM masks not unique");

bool f1_enable = isFPGAF1_PRESENT();
bool f2_enable = isFPGAF2_PRESENT();

#ifndef REV2 // REV1
uint8_t GEN_VOLTAGE_MASK = 0x3f; // 0b111111 by default
#else // REV2
uint8_t GEN_VOLTAGE_MASK = 0x1f; // 0b11111 by default
#endif // REV 2

int retval = 0;
status_V = 0x0U;
uint8_t gen_bitmask = 0;
uint8_t fpga1_bitmask = 0;
uint8_t fpga2_bitmask = 0;
uint8_t is_alarm_volt = 0;

// microcontroller and general power

if (getPowerControlState() != POWER_ON) {
#ifndef REV2 // REV1
GEN_VOLTAGE_MASK = 0x5; // 0b000101 only allows other powers off except M3V3 and 12V
#else // REV2
GEN_VOLTAGE_MASK = 0x3; // 0b00011 only allows other powers off except M3V3 and 12V
#endif // REV 2
}

#ifdef REV2
while (getADCvalue(ADC_INFO_GEN_VCC_4V0_CH) < 0.01f) { // somehow the initial value of VCC 4V0 is 0 after reboot and can screw up the logic below
vTaskDelay(pdMS_TO_TICKS(10)); // delay 10 ms
}
#endif

for (int ch = ADC_INFO_GEN_VCC_INIT_CH; ch < ADC_INFO_GEN_VCC_FIN_CH + 1; ++ch) {

float threshold = getAlarmVoltageThres();
float now_value = getADCvalue(ch);
float excess = (now_value - getADCtargetValue(ch)) / getADCtargetValue(ch);
int tens, frac;
float_to_ints(excess * 100, &tens, &frac);
if (excess > 0.0f) {
is_alarm_volt = 1;
excess_volt = excess * 100;
excess_volt_which_ch = ch;
}
// change what we do, if power is on or not.
enum power_system_state currPsState = getPowerControlState();

if ((excess > threshold && excess > 0.0f) || (excess * -1.0f > threshold && excess < 0.0f)) { // if this ADC voltage is greater/lower than a target value by getAlarmVoltageThres()*100%
gen_bitmask += (1 << (ch - ADC_INFO_GEN_VCC_INIT_CH)); // first to last bit corresponds to status of low to high ADC voltage channel of mcu/general
is_alarm_volt = 2;
log_debug(LOG_ALM, "alarm volt at ADC ch : %02d now %02d.%02d %% off target\r\n", ch, tens, frac); // over voltage among one of fpga power supplies by +/- getAlarmVoltageThres()*100% of its threshold
}
if (!((currPsState == POWER_ON) || (currPsState == POWER_OFF))) { // in flux. Skip.
return 0;
}

if (is_alarm_volt > 0) {
retval++;
if (is_alarm_volt == 2) {
status_V |= ALM_STAT_GEN_OVERVOLT;
++retval;
// set up mask for which channels to worry about
uint32_t ch_mask = VALM_BASE_MASK; // always true
if (currPsState == POWER_ON) {
ch_mask |= VALM_GEN_MASK; // common power
if (f1_enable) {
ch_mask |= VALM_F1_MASK;
}
}

currentVoltStatus[GEN] = gen_bitmask & GEN_VOLTAGE_MASK; // applies a mask with power-off exceptions

if (retval > 0)
return retval;
else
retval = 0;

is_alarm_volt = 0;
status_V = 0x0U;

int n_fpga_half_ch = (ADC_INFO_FPGA_VCC_FIN_CH - ADC_INFO_FPGA_VCC_INIT_CH + 1) / 2;
int ADC_INFO_FPGA2_VCC_INIT_CH = n_fpga_half_ch + ADC_INFO_FPGA_VCC_INIT_CH;
for (int ch = ADC_INFO_FPGA_VCC_INIT_CH; ch < ADC_INFO_FPGA_VCC_FIN_CH + 1; ++ch) {
if ((!f1_enable) || (!f2_enable && ch > (ADC_INFO_FPGA2_VCC_INIT_CH - 1))) // check if fpga1/2 is on the board. currently fpga1 takes the first half of adc outputs in this indexing
break;
float threshold = getAlarmVoltageThres();
float now_value = getADCvalue(ch);
float excess = (now_value - getADCtargetValue(ch)) / getADCtargetValue(ch);
int tens, frac;
float_to_ints(excess * 100, &tens, &frac);
if (excess > 0.0f) {
is_alarm_volt = 1;
excess_volt = excess * 100;
excess_volt_which_ch = ch;
if (f2_enable) {
ch_mask |= VALM_F2_MASK;
}
if (ch > (ADC_INFO_FPGA2_VCC_INIT_CH - 1)) {
if ((excess > threshold && excess > 0.0f) || (excess * -1.0f > threshold && excess < 0.0f)) { // if this ADC voltage is greater/lower than a target value by getAlarmVoltageThres()*100%
fpga2_bitmask += (1 << (ch - ADC_INFO_FPGA2_VCC_INIT_CH)); // first to last bit corresponds to status of low to high ADC voltage channel of fpga2
is_alarm_volt = 2;
log_debug(LOG_ALM, "alarm volt at ADC ch : %02d now +/- %02d.%02d %% off target\r\n", ch, tens, frac); // over voltage among one of fpga power supplies by +/-getAlarmVoltageThres()*100% of its threshold
}
}
// Loop over ADC values.
const float threshold = getAlarmVoltageThres();
uint32_t ch_alm_mask = 0x0U;
for (int i = 0; i < VALM_HIGHEST_V_CH; ++i) {
// check if the current channel contains a voltage measurement we care about
if (!(ch_mask & (0x1U << i))) {
continue; // if not, continue to then ext loop iteration
}
else {
if ((excess > threshold && excess > 0.0f) || (excess * -1.0f > threshold && excess < 0.0f)) { // if this ADC voltage is greater/lower than a target value by getAlarmVoltageThres()*100%
fpga1_bitmask += (1 << (ch - ADC_INFO_FPGA_VCC_INIT_CH)); // first to last bit corresponds to status of low to high ADC voltage channel of fpga2
is_alarm_volt = 2;
log_debug(LOG_ALM, "alarm volt at ADC ch : %02d now +/- %02d.%02d %% off target\r\n", ch, tens, frac); // over voltage among one of fpga power supplies by +/-getAlarmVoltageThres()*100% of its threshold
}
float target_value = getADCtargetValue(i);
float now_value = getADCvalue(i);
float excess = (now_value - target_value) / target_value;

if (ABS(excess) > threshold) {
ch_alm_mask |= (0x1U << i); // mark bit for failing supply
int tens, frac;
float_to_ints(excess * 100, &tens, &frac);
log_debug(LOG_ALM, "VoltAlm: %s: %02d.%02d %% off target\r\n", getADCname(i), tens, frac);
}
}

if (is_alarm_volt > 0) {
retval++;
if (is_alarm_volt == 2) {
status_V |= ALM_STAT_FPGA_OVERVOLT;
++retval;
}
status_V = 0x0U;
if (ch_alm_mask & (VALM_BASE_MASK | VALM_GEN_MASK)) {
status_V |= ALM_STAT_GEN_OVERVOLT;
++retval;
}
if (ch_alm_mask & VALM_F1_MASK) {
status_V |= ALM_STAT_FPGA1_OVERVOLT;
++retval;
}
if (ch_alm_mask & VALM_F2_MASK) {
status_V |= ALM_STAT_FPGA2_OVERVOLT;
++retval;
}

currentVoltStatus[FPGA1] = fpga1_bitmask;
currentVoltStatus[FPGA2] = fpga2_bitmask;

return retval;
}
Expand All @@ -293,8 +262,10 @@ void VoltErrorLog(void)
{
int tens, frac;
float_to_ints(excess_volt, &tens, &frac);
log_warn(LOG_ALM, "Voltage high: status: 0x%04x at ADC ch %02d now +%02d.%02d %% off\r\n",
status_V, excess_volt_which_ch, tens, frac);
if (excess_volt > 2.0f) {
log_warn(LOG_ALM, "Voltage high: status: 0x%04x at ADC ch %02d now +%02d.%02d %% off\r\n",
status_V, excess_volt_which_ch, tens, frac);
}
errbuffer_volt_high((uint8_t)currentVoltStatus[GEN], (uint8_t)currentVoltStatus[FPGA1], (uint8_t)currentVoltStatus[FPGA2]); // add voltage status as a data field in eeprom rather than its value
}

Expand Down
Loading

0 comments on commit 26f1476

Please sign in to comment.