Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hotfix for issues running on Rev1 #146

Merged
merged 17 commits into from
Sep 30, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions projects/cm_mcu/CommandLineTask.c
Original file line number Diff line number Diff line change
Expand Up @@ -587,7 +587,9 @@ static struct command_t commands[] = {
{"alm", alarm_ctl, "args: (clear|status|settemp #)\r\nGet or clear status of alarm task.\r\n",
-1},
{"bootloader", bl_ctl, "Call the boot loader\r\n", 0},
#ifdef REV2
{"clkmon", clkmon_ctl, "Displays a table showing the clock chips' statuses given the clock chip id option\r\n", 1},
#endif // REV2
{"clock", clock_ctl,
"args: (1|2)\r\nReset (1) or program the clock synthesizer to 156.25 MHz (2).\r\n", 1},
{"eeprom_info", eeprom_info, "Prints information about the EEPROM.\r\n", 0},
Expand Down
2 changes: 1 addition & 1 deletion projects/cm_mcu/InitTask.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ void InitTask(void *parameters)
ROM_SysCtlResetCauseClear(r);
errbuffer_put(EBUF_RESTART, restart_reason);
log_info(LOG_SERVICE, "REC register=0x%08x\r\n", restart_reason);
init_registers_ff(); // initalize I/O expander for fireflies -- with FF monitoring via I2C in other threads, it grabs semaphore inside

// wait for 3.3V power to come up. Wait indefinitely.
// in Rev1 the clocks cannot be accessed before the 3.3 V is on.
Expand All @@ -40,6 +39,7 @@ void InitTask(void *parameters)
vTaskDelay(pdMS_TO_TICKS(1000));
}
#endif // REV1
init_registers_ff(); // initalize I/O expander for fireflies -- with FF monitoring via I2C in other threads, it grabs semaphore inside
init_registers_clk(); // initalize I/O expander for clocks
log_info(LOG_SERVICE, "Clock I/O expander initialized\r\n");
#ifdef REV2
Expand Down
120 changes: 98 additions & 22 deletions projects/cm_mcu/LocalTasks.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,15 @@ struct dev_moni2c_addr_t ff_moni2c_addrs[NFIREFLIES] = {
{"V12 12 Tx GTY", FF_I2CMUX_2_ADDR, 4, 0x50}, //
{"V12 12 Rx GTY", FF_I2CMUX_2_ADDR, 5, 0x54}, //
};

struct arg_moni2c_ff_t ff_moni2c_arg[NFIREFLY_ARG] = {
{"FFL12", &ffl12_f1_args, 0, 0, 6}, //
{"FFLDAQ", &ffldaq_f1_args, 6, 0, 3}, //
{"FFL12", &ffl12_f1_args, 9, 6, 2}, //
{"FFLDAQ", &ffldaq_f2_args, 11, 0, 10}, //
{"FFL12", &ffl12_f2_args, 21, 0, 4}, //
};

#elif defined(REV2)
// -------------------------------------------------
//
Expand Down Expand Up @@ -97,25 +106,43 @@ struct dev_moni2c_addr_t ff_moni2c_addrs[NFIREFLIES] = {
{"F2_7 4 XCVR", FF_I2CMUX_2_ADDR, 2, 0x50}, //

};

struct arg_moni2c_ff_t ff_moni2c_arg[NFIREFLY_ARG] = {
{"FFL12", &ffl12_f1_args, 0, 0, 6}, //
{"FFLDAQ", &ffldaq_f1_args, 6, 0, 4}, //
{"FFL12", &ffl12_f2_args, 10, 0, 6}, //
{"FFLDAQ", &ffldaq_f2_args, 16, 0, 4}, //
};
#else
#error "Define either Rev1 or Rev2"
#endif

// FFDAQ arguments for monitoring i2c task of 4-channel firefly ports connected to FPGA1

#ifdef REV1
struct dev_moni2c_addr_t ffldaq_f1_moni2c_addrs[NFIREFLIES_DAQ_F1] = {
{"K04 4 XCVR GTY", FF_I2CMUX_2_ADDR, 0, 0x50}, //
{"K05 4 XCVR GTY", FF_I2CMUX_2_ADDR, 1, 0x50}, //
{"K06 4 XCVR GTY", FF_I2CMUX_2_ADDR, 2, 0x50}, //
};
#elif defined(REV2)
struct dev_moni2c_addr_t ffldaq_f1_moni2c_addrs[NFIREFLIES_DAQ_F1] = {
{"F1_4 4 XCVR", FF_I2CMUX_1_ADDR, 2, 0x50}, //
{"F1_5 4 XCVR", FF_I2CMUX_2_ADDR, 0, 0x50}, //
{"F1_6 4 XCVR", FF_I2CMUX_2_ADDR, 1, 0x50}, //
{"F1_7 4 XCVR", FF_I2CMUX_2_ADDR, 2, 0x50}, //
};
#else
#error "Define either Rev1 or Rev2"
#endif

struct sm_command_t sm_command_ffldaq_f1[] = {
{1, 0x00, 0x02, 1, "FF_STATUS_REG", 0xff, "", PM_STATUS},
{1, 0x00, 0x16, 1, "FF_TEMPERATURE", 0xff, "C", PM_STATUS},
{1, 0x00, 0x02, 2, "FF_STATUS_REG", 0xff, "", PM_STATUS},
{1, 0x00, 0x16, 2, "FF_TEMPERATURE", 0xff, "C", PM_STATUS},
{1, 0x00, 0x03, 1, "FF_LOS_ALARM", 0xff, "", PM_STATUS},
{1, 0x00, 0x05, 1, "FF_CDR_LOL_ALARM", 0xff, "", PM_STATUS},

};

uint16_t ffldaq_f1_values[NSUPPLIES_FFLDAQ_F1 * NCOMMANDS_FFLDAQ_F1];

struct MonitorI2CTaskArgs_t ffldaq_f1_args = {
Expand All @@ -138,22 +165,34 @@ struct MonitorI2CTaskArgs_t ffldaq_f1_args = {

// register maps for IT-DTC Fireflies 12-ch part -- future will be CERN-B but currently is 14Gbps ECUO
struct sm_command_t sm_command_fflit_f1[] = {
{1, 0x00, 0x02, 1, "FF_STATUS_REG", 0xff, "", PM_STATUS},
{1, 0x00, 0x16, 1, "FF_TEMPERATURE", 0xff, "C", PM_STATUS},
{2, 0x00, 0x07, 2, "FF_LOS_ALARM", 0xffff, "", PM_STATUS},
{2, 0x00, 0x14, 2, "FF_CDR_LOL_ALARM", 0xffff, "", PM_STATUS},
{1, 0x00, 0x02, 2, "FF_STATUS_REG", 0xff, "", PM_STATUS},
{1, 0x00, 0x16, 2, "FF_TEMPERATURE", 0xff, "C", PM_STATUS},
{2, 0x00, 0x07, 1, "FF_LOS_ALARM", 0xffff, "", PM_STATUS},
{2, 0x00, 0x14, 1, "FF_CDR_LOL_ALARM", 0xffff, "", PM_STATUS},

};
// register maps for OT-DTC Fireflies 12-ch part -- 25Gbps ECUO (no connected devices to test as of 08.04.22)
// **commands below have not been tested yet**
struct sm_command_t sm_command_fflot_f1[] = {
{1, 0x00, 0x02, 1, "FF_STATUS_REG", 0xff, "", PM_STATUS},
{1, 0x00, 0x16, 1, "FF_TEMPERATURE", 0xff, "C", PM_STATUS},
{2, 0x00, 0x07, 2, "FF_LOS_ALARM", 0xffff, "", PM_STATUS},
{2, 0x00, 0x14, 2, "FF_CDR_LOL_ALARM", 0xffff, "", PM_STATUS},
{1, 0x00, 0x02, 2, "FF_STATUS_REG", 0xff, "", PM_STATUS},
{1, 0x00, 0x16, 2, "FF_TEMPERATURE", 0xff, "C", PM_STATUS},
{2, 0x00, 0x07, 1, "FF_LOS_ALARM", 0xffff, "", PM_STATUS},
{2, 0x00, 0x14, 1, "FF_CDR_LOL_ALARM", 0xffff, "", PM_STATUS},

};

#ifdef REV1
struct dev_moni2c_addr_t ffl12_f1_moni2c_addrs[NFIREFLIES_IT_F1] = {
{"K01 12 Tx GTH", FF_I2CMUX_1_ADDR, 0, 0x50}, //
{"K01 12 Rx GTH", FF_I2CMUX_1_ADDR, 1, 0x54}, //
{"K02 12 Tx GTH", FF_I2CMUX_1_ADDR, 2, 0x50}, //
{"K02 12 Rx GTH", FF_I2CMUX_1_ADDR, 3, 0x54}, //
{"K03 12 Tx GTH", FF_I2CMUX_1_ADDR, 4, 0x50}, //
{"K03 12 Rx GTH", FF_I2CMUX_1_ADDR, 5, 0x54}, //
{"K07 12 Tx GTY", FF_I2CMUX_2_ADDR, 3, 0x50}, //
{"K07 12 Rx GTY", FF_I2CMUX_2_ADDR, 4, 0x54}, //
};
#elif defined(REV2)
struct dev_moni2c_addr_t ffl12_f1_moni2c_addrs[NFIREFLIES_IT_F1] = {
{"F1_1 12 Tx",
FF_I2CMUX_1_ADDR, 0, 0x50}, //
Expand All @@ -163,6 +202,9 @@ struct dev_moni2c_addr_t ffl12_f1_moni2c_addrs[NFIREFLIES_IT_F1] = {
{"F1_3 12 Tx", FF_I2CMUX_2_ADDR, 3, 0x50}, //
{"F1_3 12 Rx", FF_I2CMUX_2_ADDR, 4, 0x54}, //
};
#else
#error "Define either Rev1 or Rev2"
#endif

uint16_t ffl12_f1_values[NSUPPLIES_FFL12_F1 * NCOMMANDS_FFL12_F1];

Expand All @@ -183,17 +225,33 @@ struct MonitorI2CTaskArgs_t ffl12_f1_args = {
};

// FFDAQV arguments for monitoring i2c task of 4-channel firefly ports connected to FPGA2

#ifdef REV1
struct dev_moni2c_addr_t ffldaq_f2_moni2c_addrs[NFIREFLIES_DAQ_F2] = {
{"V01 4 XCVR GTY", FF_I2CMUX_1_ADDR, 0, 0x50}, //
{"V02 4 XCVR GTY", FF_I2CMUX_1_ADDR, 1, 0x50}, //
{"V03 4 XCVR GTY", FF_I2CMUX_1_ADDR, 2, 0x50}, //
{"V04 4 XCVR GTY", FF_I2CMUX_1_ADDR, 3, 0x50}, //
{"V05 4 XCVR GTY", FF_I2CMUX_1_ADDR, 4, 0x50}, //
{"V06 4 XCVR GTY", FF_I2CMUX_1_ADDR, 5, 0x50}, //
{"V07 4 XCVR GTY", FF_I2CMUX_2_ADDR, 0, 0x50}, //
{"V08 4 XCVR GTY", FF_I2CMUX_2_ADDR, 1, 0x50}, //
{"V09 4 XCVR GTY", FF_I2CMUX_2_ADDR, 2, 0x50}, //
{"V10 4 XCVR GTY", FF_I2CMUX_2_ADDR, 3, 0x50}, //
};
#elif defined(REV2)
struct dev_moni2c_addr_t ffldaq_f2_moni2c_addrs[NFIREFLIES_DAQ_F2] = {
{"F2_4 4 XCVR", FF_I2CMUX_1_ADDR, 2, 0x50}, //
{"F2_5 4 XCVR", FF_I2CMUX_2_ADDR, 0, 0x50}, //
{"F2_6 4 XCVR", FF_I2CMUX_2_ADDR, 1, 0x50}, //
{"F2_7 4 XCVR", FF_I2CMUX_2_ADDR, 2, 0x50}, //
};
#else
#error "Define either Rev1 or Rev2"
#endif

struct sm_command_t sm_command_ffldaq_f2[] = {
{1, 0x00, 0x02, 1, "FF_STATUS_REG", 0xff, "", PM_STATUS},
{1, 0x00, 0x16, 1, "FF_TEMPERATURE", 0xff, "C", PM_STATUS},
{1, 0x00, 0x02, 2, "FF_STATUS_REG", 0xff, "", PM_STATUS},
{1, 0x00, 0x16, 2, "FF_TEMPERATURE", 0xff, "C", PM_STATUS},
{1, 0x00, 0x03, 1, "FF_LOS_ALARM", 0xff, "", PM_STATUS},
{1, 0x00, 0x05, 1, "FF_CDR_LOL_ALARM", 0xff, "", PM_STATUS},

Expand All @@ -220,22 +278,30 @@ struct MonitorI2CTaskArgs_t ffldaq_f2_args = {

// register maps for IT-DTC Fireflies 12-ch part -- future will be CERN-B but currently is 14Gbps ECUO
struct sm_command_t sm_command_fflit_f2[] = {
{1, 0x00, 0x02, 1, "FF_STATUS_REG", 0xff, "", PM_STATUS},
{1, 0x00, 0x16, 1, "FF_TEMPERATURE", 0xff, "C", PM_STATUS},
{2, 0x00, 0x07, 2, "FF_LOS_ALARM", 0xffff, "", PM_STATUS},
{2, 0x00, 0x14, 2, "FF_CDR_LOL_ALARM", 0xffff, "", PM_STATUS},
{1, 0x00, 0x02, 2, "FF_STATUS_REG", 0xff, "", PM_STATUS},
{1, 0x00, 0x16, 2, "FF_TEMPERATURE", 0xff, "C", PM_STATUS},
{2, 0x00, 0x07, 1, "FF_LOS_ALARM", 0xffff, "", PM_STATUS},
{2, 0x00, 0x14, 1, "FF_CDR_LOL_ALARM", 0xffff, "", PM_STATUS},

};
// register maps for OT-DTC Fireflies 12-ch part -- 25Gbps ECUO (no connected devices to test as of 08.04.22)
// **commands below have not been tested yet**
struct sm_command_t sm_command_fflot_f2[] = {
{1, 0x00, 0x02, 1, "FF_STATUS_REG", 0xff, "", PM_STATUS},
{1, 0x00, 0x16, 1, "FF_TEMPERATURE", 0xff, "C", PM_STATUS},
{2, 0x00, 0x07, 2, "FF_LOS_ALARM", 0xffff, "", PM_STATUS},
{2, 0x00, 0x14, 2, "FF_CDR_LOL_ALARM", 0xffff, "", PM_STATUS},
{1, 0x00, 0x02, 2, "FF_STATUS_REG", 0xff, "", PM_STATUS},
{1, 0x00, 0x16, 2, "FF_TEMPERATURE", 0xff, "C", PM_STATUS},
{2, 0x00, 0x07, 1, "FF_LOS_ALARM", 0xffff, "", PM_STATUS},
{2, 0x00, 0x14, 1, "FF_CDR_LOL_ALARM", 0xffff, "", PM_STATUS},

};

#ifdef REV1
struct dev_moni2c_addr_t ffl12_f2_moni2c_addrs[NFIREFLIES_IT_F2] = {
{"V11 12 Tx GTY", FF_I2CMUX_1_ADDR, 6, 0x50}, //
{"V11 12 Rx GTY", FF_I2CMUX_1_ADDR, 7, 0x54}, //
{"V12 12 Tx GTY", FF_I2CMUX_2_ADDR, 4, 0x50}, //
{"V12 12 Rx GTY", FF_I2CMUX_2_ADDR, 5, 0x54}, //
};
#elif defined(REV2)
struct dev_moni2c_addr_t ffl12_f2_moni2c_addrs[NFIREFLIES_IT_F2] = {
{"F2_1 12 Tx", FF_I2CMUX_1_ADDR, 0, 0x50}, //
{"F2_1 12 Rx", FF_I2CMUX_1_ADDR, 1, 0x54}, //
Expand All @@ -244,6 +310,9 @@ struct dev_moni2c_addr_t ffl12_f2_moni2c_addrs[NFIREFLIES_IT_F2] = {
{"F2_3 12 Tx", FF_I2CMUX_2_ADDR, 3, 0x50}, //
{"F2_3 12 Rx", FF_I2CMUX_2_ADDR, 4, 0x54}, //
};
#else
#error "Define either Rev1 or Rev2"
#endif

uint16_t ffl12_f2_values[NSUPPLIES_FFL12_F2 * NCOMMANDS_FFL12_F2];

Expand Down Expand Up @@ -438,6 +507,7 @@ void getFFpart()

// checking the FF 12-ch part connected to FPGA1 (need to check from Rx devices (i.e devices[odd]))
uint8_t data1;

data1 = 0x1U << ffl12_f1_args.devices[3].mux_bit;
log_debug(LOG_MONI2C, "Mux set to 0x%02x\r\n", data1);
int rmux = apollo_i2c_ctl_w(ffl12_f1_args.i2c_dev, ffl12_f1_args.devices[3].mux_addr, 1, data1);
Expand Down Expand Up @@ -963,6 +1033,8 @@ void init_registers_ff()

// =====================================================
// CMv1 Schematic 4.06 I2C VU7P OPTICS
while (xSemaphoreTake(ffldaq_f2_args.xSem, (TickType_t)10) == pdFALSE)
;

// 5a) U103 inputs vs. outputs (I2C address 0x20 on I2C channel #3)
// All signals are inputs.
Expand Down Expand Up @@ -995,6 +1067,10 @@ void init_registers_ff()
apollo_i2c_ctl_w(3, 0x72, 1, 0x04);
apollo_i2c_ctl_reg_w(3, 0x22, 1, 0x06, 1, 0xff); // 11111111 [P07..P00]
apollo_i2c_ctl_reg_w(3, 0x22, 1, 0x07, 1, 0xf0); // 11110000 [P17..P10]
xSemaphoreGive(ffldaq_f2_args.xSem);

while (xSemaphoreTake(ffldaq_f1_args.xSem, (TickType_t)10) == pdFALSE)
;

// 7b) U6 default output values (I2C address 0x22 on I2C channel #3)
// The outputs on P10 and P11 should default to "1".
Expand Down
46 changes: 29 additions & 17 deletions projects/cm_mcu/MonitorI2CTask.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,6 @@

void Print(const char *str);

// break out of loop, releasing semaphore if we have it

#define release_break() \
{ \
xSemaphoreGive(args->xSem); \
break; \
}

// read-only accessor functions for Firefly names and values.

bool getFFch_low(uint8_t val, int channel)
Expand Down Expand Up @@ -86,9 +78,9 @@ void MonitorI2CTask(void *parameters)
// wait for the power to come up
vTaskDelayUntil(&(args->updateTick), pdMS_TO_TICKS(2500));

int IsCLK = (strstr(args->name, "CLK") != NULL); // the instance is of CLK-device type
int IsFF12 = (strstr(args->name, "FF12") != NULL); // the instance is of FF 12-ch part type
// int IsFFDAQ = (strstr(args->name, "FFDAQ") != NULL); //the instance is of FF 4-ch part type (DAQ links) -- not being used currently
int IsCLK = (strstr(args->name, "CLK") != NULL); // the instance is of CLK-device type
int IsFF12 = (strstr(args->name, "FF12") != NULL); // the instance is of FF 12-ch part type
int IsFFDAQ = (strstr(args->name, "FFDAQ") != NULL); // the instance is of FF 4-ch part type (DAQ links) -- not being used currently

// reset the wake time to account for the time spent in any work in i2c tasks

Expand All @@ -105,10 +97,30 @@ void MonitorI2CTask(void *parameters)
// -------------------------------
for (int ps = 0; ps < args->n_devices; ++ps) {

if (!IsCLK) { // Fireflies need to be checked if the links are connected or not
int offsetFF12 = 1 - IsFF12;
if (!isEnabledFF(ps + (offsetFF12 * (NFIREFLIES_IT_F1)) + ((args->i2c_dev - I2C_DEVICE_F1) * (-1) * (NFIREFLIES_F2)))) // skip the FF if it's not enabled via the FF config
continue;
if (!IsCLK) { // Fireflies need to be checked if the links are connected or not
if (args->i2c_dev == I2C_DEVICE_F1) { // FPGA #1
#ifdef REV1
int NFIREFLIES_IT_F1_P1 = NFIREFLIES_IT_F1 - 2;
if (!isEnabledFF((IsFFDAQ * (ps + NFIREFLIES_IT_F1_P1)) + (IsFF12 * (ps < NFIREFLIES_IT_F1 - 3) * (ps)) + (IsFF12 * (ps > NFIREFLIES_IT_F1 - 3) * (ps + NFIREFLIES_DAQ_F1)))) // skip the FF if it's not enabled via the FF config
continue;
#elif defined(REV2)
if (!isEnabledFF((IsFFDAQ * (ps + NFIREFLIES_IT_F1)) + (IsFF12 * (ps)))) // skip the FF if it's not enabled via the FF config
continue;
#else
#error "Define either Rev1 or Rev2"
#endif
}
if (args->i2c_dev == I2C_DEVICE_F2) { // FPGA #2
#ifdef REV1
if (!isEnabledFF(NFIREFLIES_F1 + (IsFFDAQ * (ps)) + (IsFF12 * (ps + NFIREFLIES_DAQ_F2)))) // skip the FF if it's not enabled via the FF config
continue;
#elif defined(REV2)
if (!isEnabledFF(NFIREFLIES_F1 + (IsFFDAQ * (ps + NFIREFLIES_IT_F2)) + (IsFF12 * (ps)))) // skip the FF if it's not enabled via the FF config
continue;
#else
#error "Define either Rev1 or Rev2"
#endif
}
args->updateTick = xTaskGetTickCount();
}

Expand Down Expand Up @@ -139,7 +151,7 @@ void MonitorI2CTask(void *parameters)
int res = apollo_i2c_ctl_w(args->i2c_dev, args->devices[ps].mux_addr, 1, data);
if (res != 0) {
log_warn(LOG_MONI2C, "Mux write error %s, break (instance=%s,ps=%d)\r\n", SMBUS_get_error(res), args->name, ps);
release_break();
break;
}

// Read I2C registers/commands
Expand All @@ -163,7 +175,7 @@ void MonitorI2CTask(void *parameters)
log_warn(LOG_MONI2C, "%s read Error %s, break (ps=%d)\r\n",
args->commands[c].name, SMBUS_get_error(res), ps);
args->sm_values[index] = 0xffff;
release_break();
break;
}
else {
args->sm_values[index] = (uint16_t)masked_output;
Expand Down
16 changes: 16 additions & 0 deletions projects/cm_mcu/MonitorI2CTask.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,19 +42,35 @@ struct MonitorI2CTaskArgs_t {
UBaseType_t stack_size; // stack size of task
};

#ifndef REV2
#define NSUPPLIES_FFLDAQ_F1 (3)
#else // REV2
#define NSUPPLIES_FFLDAQ_F1 (4)
#endif // REV 2
#define NCOMMANDS_FFLDAQ_F1 4 // number of commands
#define NPAGES_FFLDAQ_F1 1 // number of pages on the 4-channel firefly ports

#ifndef REV2
#define NSUPPLIES_FFL12_F1 (8)
#else // REV1
#define NSUPPLIES_FFL12_F1 (6)
#endif // REV 2
#define NCOMMANDS_FFL12_F1 4 // number of commands
#define NPAGES_FFL12_F1 1 // number of pages on the 12-channel firefly ports

#ifndef REV2
#define NSUPPLIES_FFLDAQ_F2 (10)
#else // REV1
#define NSUPPLIES_FFLDAQ_F2 (4)
#endif // REV 2
#define NCOMMANDS_FFLDAQ_F2 4 // number of commands
#define NPAGES_FFLDAQ_F2 1 // number of pages on the 4-channel firefly ports

#ifndef REV2
#define NSUPPLIES_FFL12_F2 (4)
#else // REV1
#define NSUPPLIES_FFL12_F2 (6)
#endif // REV 2
#define NCOMMANDS_FFL12_F2 4 // number of commands
#define NPAGES_FFL12_F2 1 // number of pages on the 12-channel firefly ports

Expand Down
Loading