Git Product home page Git Product logo

cm_mcu's People

Contributors

dependabot[bot] avatar fatimayousuf avatar gwengardner avatar pkotamnives avatar pwittich avatar rzoucern avatar

Stargazers

 avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Forkers

hjgqx996 rimalroc

cm_mcu's Issues

Add CM ID info to EEPROM

Suggestion by Charlie.

  • utilities to read/write/lock(?) EEPROM registers with this information, see TM4C1290NCPDT data sheet
  • start with CLI interface
  • add to I2C slave for IPMC access

I think it is valuable to have the CM board serial number stored in memory and be available to the SM. I put a simple EEPROM on the I2C bus that connects to the SM for this purpose.

As I was thinking about how to program and access this memory, it occurred to me that using the MCU's own internal EEPROM (manual section 8.2.4) eliminates the need for this external chip.

So we need an MCU command that writes a command line value into the serial number address of the internal EEPROM. Part of the MCU startup code would be to retrieve this serial number and make it available to the SM over the I2C bus.

One could make this much more elaborate, and have information about which FPGAs and FireFlys ought to be available.

Add semaphore give/take where *apollo_i2c_ctl* is called

issue : the semaphore give/take for a right device has not been implemented properly in some modules that rely on apollo_i2c_ctl functions. For instance, the i2c_scan 2 and i2c_scan 4 have gone wild because it has tried to access a semaphore that is already taken by other modules.

% i2c_scan 2
2064034 MONI2C ERR MonitorI2CTask.c:176:PN_BASE read Error ADDR_ACK_ERROR, break (ps=0)
2064079 I2C ERR I2CCommunication.c:198:write fail PERIPHERAL_BUSY
2064079 MONI2C WRN MonitorI2CTask.c:153:Mux write error PERIPHERAL_BUSY, break (instance=CLKR0A,ps=0)
2064080 SRV INF MonitorI2CTask.c:191:stack (CLKR0) = 272(was 280)
2064082 MONI2C WRN MonitorI2CTask.c:153:Mux write error ADDR_ACK_ERROR, break (instance=CLKSI,ps=0)
2064105 MONI2C WRN MonitorI2CTask.c:153:Mux write error ADDR_ACK_ERROR, break (instance=CLKR0A,ps=0)
2064107 MONI2C WRN MonitorI2CTask.c:153:Mux write error ADDR_ACK_ERROR, break (instance=CLKSI,ps=0)
2064130 MONI2C WRN MonitorI2CTask.c:153:Mux write error ADDR_ACK_ERROR, break (instance=CLKR0A,ps=0)
2064145 MONI2C ERR MonitorI2CTask.c:166:SMBUS page failed ADDR_ACK_ERROR
SMBUS command failed  (setting page)
2064192 MONI2C WRN MonitorI2CTask.c:153:Mux write error ADDR_ACK_ERROR, break (instance=CLKR0A,ps=0)
2064194 MONI2C WRN MonitorI2CTask.c:153:Mux write error ADDR_ACK_ERROR, break (instance=CLKSI,ps=0)
2064217 MONI2C WRN MonitorI2CTask.c:153:Mux write error ADDR_ACK_ERROR, break (instance=CLKR0A,ps=0)
2064219 MONI2C WRN MonitorI2CTask.c:153:Mux write error ADDR_ACK_ERROR, break (instance=CLKSI,ps=0)
2064243 MONI2C ERR MonitorI2CTask.c:166:SMBUS page failed ADDR_ACK_ERROR
SMBUS command failed  (setting page)
2064254 MONI2C ERR MonitorI2CTask.c:176:REG_0x0D read Error ADDR_ACK_ERROR, break (ps=0)
2064256 MONI2C WRN MonitorI2CTask.c:153:Mux write error ADDR_ACK_ERROR, break (instance=CLKSI,ps=0)
i2c bus scan, device 2
0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f                                                                                                                                 
00:           3 --  5 -- -- -- -- -- -- -- -- -- --                                                                                                                                 
10: -- -- -- -- -- -- -- -- -- -- -- 1b -- 1d -- --                                                                                                                                 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --                                                                                                                                 
30: -- -- -- -- 34 -- 36 37 38 39 -- -- -- -- -- --                                                                                                                                 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --                                                                                                                                 
50: 50 -- 52 -- -- -- -- -- -- -- -- -- -- -- -- --                                                                                                                                 
60: -- -- -- -- -- -- -- -- -- 69 6a -- 6c -- -- --                                                                                                                                 
70: 70 -- -- -- -- -- -- 77                                                                                                                                                         
% 

solution: will have to search for all remaining modules that call i2c related functions in order to form a right semaphore pair corresponding to a device that tries to access it.
Also, we could have cleaned up the following left-over non-generalized semaphores as well.

[pk568@lnx231 cm_mcu]$ grep -r args.xSem projects/cm_mcu/                                                                                                                           projects/cm_mcu/commands/SensorControl.c:  SemaphoreHandle_t s = ffldaq_f1_args.xSem;
projects/cm_mcu/commands/SensorControl.c:    s = ffldaq_f2_args.xSem;
projects/cm_mcu/commands/SensorControl.c:  SemaphoreHandle_t s = ffldaq_f1_args.xSem;
projects/cm_mcu/commands/SensorControl.c:    s = ffldaq_f2_args.xSem;
projects/cm_mcu/commands/SensorControl.c:  while (xSemaphoreTake(dcdc_args.xSem, (TickType_t)10) == pdFALSE)
projects/cm_mcu/commands/SensorControl.c:  xSemaphoreGive(dcdc_args.xSem);

Additional CM sensors for CM type, revision and serial number

Is your feature request related to a problem? Please describe.
It is not related to a specific problem. But it would be really handy if there would be sensors from the Command Module (CM) describing the type, revision and serial number, which can be read out by the OpenIPMC. This would also make it possible to read out those values even if the Zynq is not booting.

Describe the solution you'd like
Ideally, since OpenIPMC supports numerical sensors, one CM sensor for each piece of information could be used:

CM Type: Maybe this can be represented as an enum. For example, 0 -> Cornell CM, 1 -> MPI CM
CM Revision: The CM revision number can be provided by this sensor.
CM Serial: The CM serial number can be provided by this sensor.

With these CM sensors, the goal would be to see three additional sensors in the output of the ipmitool sensor command.

Describe alternatives you've considered
One variation can be in the number of CM sensors to be added. It could be nice if there is a single CM sensor that represents all type, revision and serial information, but it is not clear how that can be easily encoded/decoded on the OpenIPMC side and displayed to the user.

Another alternative is to write these values to Zynq registers (which I believe most of it is already there), the downside would be then we won't be able to read these values if Zynq didn't boot.

Additional context
This is a rather low priority request, thanks for considering it and let us know if you have suggestions about this! I'll include @dgastler here as the original requester of the feature.

Store clock chip information on Rev2b eeprom and use it to initialize clocks

We need to store the programs for initializing the clocks on the board so that the clocks are loaded with programs by default.

This issue depends on issue #123 being completed.

At MCU reboot and when prompted via the CLI (and possibly via a register write) the clock chips will need to be programmed via I2C by the MCU. So we need to prepare for this.

Steps

  1. generate the data for the various clocking chips on the CM. (I think there are 5?) I think @CRStrohman or @rzouCERN need to do this
  2. program the data into the bigger external EEPROM on Rev2b
  3. create a function in the MCU that will read the data from the EEPROM and write it to the appropriate SiLabs chip
  4. Add this function to the initialization task after here
    log_info(LOG_SERVICE, "Clock I/O expander initialized\r\n");
  5. add a CLI interface to program the clocks

We might need more than one program for each clock interface, so we should allow for this both in how the data is stored in the EEPROM, how it is loaded by the MCU, and in the CLI interface

boot loader over ZYNQ UART

boot loader appears to no longer work when pointed at the ZYNQ UART. Strangely the CLI for forcing an update works fine over the ZYNQ UART.

F2 temperature unexpectedly zero on Apollo214

issue : the 4-ch FFs on FPGA#2 have zero temperatures (at least the one on Apollo214). This must be a bug in the FW after FF task is removed. The issue was not present with old FW with FF task.
how to reproduce : go to apollo214 and execute ff_temp with any latest MCU FW.
solution : not sure yet but it should have something to do with the MONI2C arguments for F2_* devices and how its values are stored.

Turn on/off CDR circuit on Firefly 4x XCVRs

Need to have a clean way of turning off the CDR circuit on the FF CLI

  • register on device is is 98 (hex 0x62), defaults to 0xFF. See pages 52 and 55 of the ECUO 25G x4 data sheet.
  • bottom nibble is for RX, top nibble is for Tx
  • defaults to on (0xff).

To turn off need to

  1. disable FF monitoring task
  2. set mux bits appopriately
  3. write value to register
  4. re-enable FF monitoring task

Mapping of names to mux to FF addresses is in FireflyTask.c

Need a programmatic and CLI (and I2C) interface.

Update power supply monitoring to distinguish between static and dynamic quantities

The power supply monitoring currently does not distinguish between readout of static quantities, such as configuration registers, and dynamic quantities, such as current, voltage, and temperature. The two tasks should be split and the static quantities read only once or infrequently (once/hour or something.) The code in question is the MonitorTask.

One solution might be to adjust the MonitorTask to take a frequency argument ; this would require that a semaphore be used to control access to the i2c controller (we already have to do this to avoid collisions with the snapshot command line task and also the LGA80D initialization in the PowerSupplyTask.

There would then be two monitor tasks for the power supplies (right now there is only one) with different arguments called.

reload MCU via boot loader in flash

Is your feature request related to a problem? Please describe.
We want to be able to reload the MCU firmware over UART1, which is the UART connected to the Zynq. while the TM4C1290NCPDT has a booatloader in the ROM, it is only connected to UART0. So we need to implement one in flash.

Describe the solution you'd like

  • update the MCU code to run a bootloader in flash memory/RAM. See TI documentation spmu301d as well as the TIVAWARE example codes in the Tivaware sources at examples/boards/ek-tm4c1294xl/boot_demo.
  • implement a boot loader to be run on Zynq. Suggest starting with sflash example in Tivaware 'tools' folder.
  • implement a CLI command to initiate firmware update.

Rationalize the use of how i2c registers are accessed

There are currently several different ways that I2C registers are accesssed in the code. It would be good to rationalize this to use only the interface that @rzouCERN created in I2CCommunication.c:

int apollo_i2c_ctl_set_dev(uint8_t base);
int apollo_i2c_ctl_r(uint8_t address, uint8_t nbytes, uint8_t data[4]);
int apollo_i2c_ctl_reg_r(uint8_t address, uint8_t reg_address, uint8_t nbytes, uint8_t data[4]);
int apollo_i2c_ctl_w(uint8_t address, uint8_t nbytes, uint8_t value);
int apollo_i2c_ctl_reg_w(uint8_t address, uint8_t reg_address, uint8_t nbytes, uint8_t packed_data);

These functions are wrappers around the code in common/smbus.c. There is a lot of duplicated code; putting these in wrappers ought to allow us to shrink the size of the executable.

Note that there is a separate set of (very similar) functions in LocalTasks.c, e.g.:

int apollo_pmbus_rw(tSMBus *smbus, volatile tSMBusStatus *smbus_status, bool read,
struct dev_i2c_addr_t *add, struct pm_command_t *cmd, uint8_t *value)

We should figure out if we can merge these two.

We will likely need to ensure that the following accesses are supported:

  • smbus access (LGA80D power supplies, Xilinx fpgas, in MonitorTask.c and in LocalTasks.c where the snapshot registers are manipulated and the LGA80D power supplies are initialized)
  • straight I2C access (firefly devices in FireflyTask.c) as well as all places where the I2C muxes are manipulated. The muxes in particular are accessed all over. Presumably this also covers the ClockSynth.c code.

It is not obvious to me that all of these accesses are supported in the above code, and we should check that we need separate function calls. In the common/smbus.c code there are different calls for SMBUS vs straight I2C interactions.

boot loader fallback/dual program

Bootloader should fall back to a known good version of the firmware

  1. store two programs in the flash (in addition to the boot loader
  2. figure out a spec on how the boot loader should choose which program to boot

Clean-up LocalTask.c

The issue : LocalTask.c is getting large and most of the stuff that makes it big is from firefly auxiliary functions.

The solution : We should separate FF-related functions and variables to another file.

monitoring task hangs uC if power supplies turned off

Describe the bug
Turning off the power supply via pwr off hangs the monitoring task in an infinite loop waiting for I2C commands to succeed. Hangs in infinite loop on call to I2CMasterBusy(). TM4C129x family has timeout for I2C which can be used.

  • Need to suspend the monitoring task (or just not check the power supplies) since the I2C mux chips are also turned off once the power supplies are turned off. vTaskSuspend in FreeRTOS. documentation here.

clkmon command reads into random memory

% clkmon 5
Monitoring SI clock with id : } 
REG_TABLE       REG_ADDR BIT_MASK  VALUE 
Invalid clock chip 5 , the clock id options are r0a:0, r0b:1, r1a:2, r1b:3 and r1c:4 
% 

It looks like the test for valid input is done after the input is used (in this case the clock number) and hence some array is accessed past its end. This can cause problems since the read will continue until it hits a '\0'.

Restart MCU

Add a CLI command that resets the MCU
Steps:
File refers to CommandLineTask.c

  • create a CLI_Command_Definition_t object with the command name, the help string, the name of the function to get called, and the number of parameters (probably 0 here)
  • create a function that gets called. the prototype has to be of the form BaseType_t command( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )
  • add code to register the command in vCommandLineTask(), something like this: FreeRTOS_CLIRegisterCommand(&command );

The command should call SysCtlReset() which is defined in driverlib/sysct.{h,c}.

Add received optical power monitoring from Samtec FF to the data sent to grafana

Add received optical power to the monitoring of the 4 channel transceivers and the 12 channel receivers.

Based on the data sheets, neither the 14 G 12 channel receiver nor the CERN-B receiver have this information available.

The 25 G 12 channel receiver appears to have the 12 channel registers on Upper page 0x1. The data is a 16 bit unsigned integer calibrated to 0.1 uW/LSB. "The low byte within each pair is the MSB." The data is laid out starting at address 206/207 through 228/229 for channel 11 to channel 0, respectively. Register is called RSSI. No further information in v3 of the data sheet (page 65).

The 25 G 4 channel transceivers appear to have this on page 0x0, with the same data format. The addresses are starting at 34/35 for Ch 1 and end at 40/41 for channel 4 (opposite order from the 12 channel part, and here 1-based numbering.) This is based on v1 of the data sheet, on page 52.

test clock synthesizer

We need to test the clock synthesizer chip. Sample code attached. Basic I2C reads and writes have been performed to the chip.
Si5340-RevD-Registers_no_amble.h.txt
Si5340-RevD-Registers.h.txt

From Charlie:

I have attached 2 configuration files exactly as they are generated by the SI labs "clock builder" program.

The difference is that the one named "..._no_amble" does not contain the pre-amble nor post-amble that must be sent to the chip. These missing chunks of settings are always the same, and a 300 milli-second delay is required after sending the pre-amble. You may decide that it would be easier to hard-code these into the MCU program, or you may decide to insert the delay wait after sending the pre-amble.

[...] I would not manipulate the output file from the clock builder [...]. I would us the file as generated and have my program that sends data to the MCU do the manipulation. [...]

The manipulation involves determining when the page changes and inserting a write of the new page to address 0x01. The data in the file fills an array of structures. The first data in the structure is a 16-bit address. If the high byte is different than the high byte of the previous address, use the value of the high byte to cause a page change. Always send the register number stored in the low byte of the address along with the corresponding data.

Add readout of more SamTec firefly registers to MCU firmware

Following additional readout should be added, to support work at BU. This is challenging because there are at least three different SamTec devices (4 channel transceivers @ 25 Gbps, 12 channel Tx and 12 channel Rx at 14 Gbps, and 12 channel Tx and Rx at 25 Gbps.) They have slightly different memory maps/register addresses.

  • LOS (loss of signal)
  • LOL (loss of lock for the CDR PLL)

For this part you need to

  • figure out the addresses of these registers on the various parts -- hopefully they are all the same on all parts, probably not. Read the data sheets for these
  • add the readout of these registers to the FireFlyTask (see also PR #74 )

These data should be sent to the Zynq for monitoring. For this part of the task we need the following.

clean up register maps

The I2C slave and the task that sends data to the Zynq has implicitly embedded in the code a memory map. This needs to be broken out and made more maintainable.

handle 3.8V for 25G Firefly

We need to provide an easier way to turn on the 3.V for the fireflies, and it also needs to be turned off before the 3.3V is turned off.

I2C slave to respond to the IPMC

Need to have an I2C slave to respond to the IPMC.

  • Todo:
  • general alarm / monitoring framework. Be able to report warning and alarm temps. Or just report the value and then let Zynq/IPMC do something? For standalone the MCU needs to be able to react.
  • figure out how to do the I2C slave -- model on the complicated signal handler that the SMBUS code uses
  • need a register map of what is presented to the IPMC and in what format
  • need to read out sysmon from FPGA registers to populate FPGA temperatures and voltages -- use PMBUS interface?
  • need to read out Fireflies and populate voltage and temperature registers there

I2C failures on MonitorTask not logged and result in stale values

Describe the bug
On apollo09 the SYSMON on the KU15P doesn't come up correctly when unprogrammed. The FPGA reports -280C on JTAG and the I2C transactions fail. the MCU just pushes the one valid reading it appears to get to the grafana/zynq, though, rather than marking the value as stale.

also the MonitorTask just uses SuppressedPrint to log the errors to the console. but unless you're logged in you cannot see the errors in any other way/

To Reproduce
Steps to reproduce the behavior:

  1. reboot MCU on apollo09
  2. watch

Expected behavior
Errors should be logged and no stale data sent to grafana/Zynq.

crash in errbuff_out

uint32_t num = strtoul(argv[1],NULL,10);
uint32_t arr[num];
uint32_t (*arrptr)[num]=&arr;
errbuffer_get(ebuf,num,arrptr);
copied += snprintf(m+copied, s-copied, "Entries in EEPROM buffer:\r\n");
int i=0, max=num;
while (i<max) {

I think there are two issues in this function

  1. here you are using a somewhat obscure feature of c called "variable length arrays" that depends on the stack size being big enough. On our little microcontroller it is probably safer to instead create a static array with some size (like 25 entries) and then if the argument asks for more than that limit the output to 25 entries and print an error message
  2. The buffer we write to m overruns its boundary when copied>SCRATCH_SIZE if you look at e.g. adc_ctl we handle this by returning pdTRUE when we are close to overrunning the buffer; the CLI tool will keep calling the function until all values have been copied. The signaling mechanism is the static variable whichadc which keeps track of where you are in the output loop.
    static BaseType_t adc_ctl(int argc, char ** argv)
    {
    int copied = 0, s = SCRATCH_SIZE;
    static int whichadc = 0;
    if ( whichadc == 0 ) {
    copied += snprintf(m+copied, s-copied, "ADC outputs\r\n");
    }
    for ( ; whichadc < 21; ++whichadc ) {
    float val = getADCvalue(whichadc);
    int tens = val;
    int frac = ABS((val-tens)*100.);
    copied += snprintf(m+copied, s-copied, "%14s: %02d.%02d\r\n", getADCname(whichadc), tens, frac);
    if ( (s-copied) < 20 && (whichadc < 20)) {
    ++whichadc;
    return pdTRUE;
    }
    }
    whichadc = 0;
    return pdFALSE;
    }

can you fix the second issue for sure and also check the other functions if they have this issue? I've been sloppy of not checking this for small functions...

uptime wraps too soon

Describe the bug
uptime seems to roll over after less than 1000 minutes (not clear about reason)

To Reproduce
Steps to reproduce the behavior:

  1. look at uptime
  2. it's never more than a few hundred minutes

It ought to be ok; TickType_t is AFAIK a signed 32 bit integer. The number is multiplied by some constants; hopefully the compiler avoids unneeded up- and down-multipliers. According to my estimate the overall scaling is (1000/100)*(1/60000). The tick rate is 100 Hz. So this should reduce to 1/6000, hopefully at compile time. Max is like 2x10^9 for a 32 bit signed integer, so the max number of minutes should be like 33k. What am I doing wrong here?

image

static BaseType_t uptime(int argc, char ** argv)
{
int s = SCRATCH_SIZE;
TickType_t now = pdTICKS_TO_MS( xTaskGetTickCount())/1000/60; // time in minutes
snprintf(m,s, "%s: MCU uptime %d minutes\r\n", argv[0], now);
return pdFALSE;
}

ff xmit on/off all doesn't work as expected

issue : @rzouCERN noticed a weird behavior of ff xmit on all and ff xmit off all commands with REV2 board (CM 203) on Apollo205. The current version is

% version
Version commit date 2022-09-20 22:51:22 -0400   (HEAD -> hotfix/rev1, origin/hotfix/rev1) v0.99.1-18-g823cacb-dirty
regular build 
built at 15:49:59, Sep 21 2022.

basically, the FFs seem to always be disabled. That could be explained by this line in the code (also for other places) that also exists in the master branch. This seems to skip the line(s) with "on" by exiting the scope too soon.

solution : fix this bug. However, even if this bug is fixed, I am still not sure what would be an onset of commands to test. I have tried writing/reading from the register 0x34 (Transmit Channel Disables) directly but got confused by the output that I would expect from turning on disabled transmit link:

% i2cwr 4 0x50 1 34  2 0                                                                                                
i2cwr: W to addr 0x50, reg 0x34, val=0x00000000 (2 bytes)                                                               
% i2crr 4 0x50 1 34 2                                                                                                   
i2cr: add: 0x50, reg 0x34: value 0x00000000 (2 bytes)                                                                   
% i2cwr 4 0x50 1 34  2 3ff                                                                                              
i2cwr: W to addr 0x50, reg 0x34, val=0x000003ff (2 bytes)                                                               
% i2crr 4 0x50 1 34 2                                                                                                   
i2cr: add: 0x50, reg 0x34: value 0x00000000 (2 bytes)

it should resemble the purpose of this code if it works, and I was not sure why we set 0x3ff as a value of this register when it's off when this value seems to flip 10 bits up rather than 8 bits of this register.

Support for time keeping

On Rev 2 there will be a 32 kHz oscillator for time keeping (needed for error logging.) I need to add a) a mechanism to set the clock, from the CLI and probably from an I2C slave, and b) the actual code for keeping time (presumably with a timer counter interrupt.)

Add additional alarm tasks

Right now there is a GenericAlarmTask with callbacks. The only implementation of that task is for temperature out of range.

We should probably consider an additional alarm task for voltages out of range, and current out of range.

error logger data format

Need to look at the error logger data format again; the 7 bits are not enough for the power supply mask. Options are

  • continuation code
  • rework data format

No way to load the EEPROM any more

Currently manual loading of the clocks or loading of the EEPROM won't work unless you stop the clock monitoring tasks. Need to think of a clean way to allow both.
Possible solutions:

  • interface to suspend the clock monitoring tasks
  • somehow come up with a clean way of using the semaphores from the CLI. Currently this won't work because the CLI commands are for a single i2c transaction and the state you need to save is up to 3 i2c transactions (set the i2c multiplexor, set the device page register, set the actual register you want to set.)

Assertion failures

CERN TIF board
error log output of SM05-mated MCU.

[...]
 00 00:00        1 Restart (EXT)(POR)
 00 09:01        1 Power On 
 00 00:00        1 Assertion failed (pc) 0x00 0x00 0xaf 0x8e
 00 00:00        1 Restart (SW)(EXT)(POR)
 01 03:43        1 Power On 
 08 14:38        1 Power Off - Manual 
 00 00:00        1 Restart (EXT)(POR)
 00 22:00        1 Power On 
 00 00:00        1 Power On 
 00 00:00        1 Restart (EXT)
 00 00:39        1 Power Off - Manual 
 00 00:39        1 Power On 
 00 00:00        1 Power On 
 00 00:00        1 Restart (EXT)
 00 00:00        1 Assertion failed (pc) 0x00 0x00 0xaf 0x8e
 00 00:00        1 Power On 
 00 00:00        1 Restart (SW)(EXT)
[...]
% version
Version v0.27 built at 17:48:35, Sep 11 2020.

pc = 0xaf8e

Monitor the status registers of the SI chips

Is your feature request related to a problem? Please describe.
SI5341 and SI5395 chips have status registers (LOS, OOF, etc) that we should monitor when the chips are being used.

For SI5341: see Table 4.5 : https://www.skyworksinc.com/-/media/Skyworks/SL/documents/public/reference-manuals/Si5341-40-D-RM.pdf

For SI5395: see Section 5.3: https://www.skyworksinc.com/-/media/SkyWorks/SL/documents/public/reference-manuals/si5395-94-92-family.pdf

For the sticky flags we should also write 0s to them at the end of programming.

redo interrupt handler for I2C/PMBUS

The interrupt handler is currently like 600 lines long and probably not reentrant, due to the calls to SMBusMasterIntProcess. This should be replaced by some sort of a signaling mechanism from the task to the I2C/SMBUS call.

Add commands to Firefly task and set startup behavior.

Add a few commands to the samtec firefly task.

  1. add recv disable command. The receivers can also be disabled (like the transmitters currently are) to save more power. On the ECU014 parts this is control bytes 54 and 55). Need to look it up on other parts.
  2. all firefly channels should be disabled by default to minimize the board power draw.
  3. add a command to read out the status bytes
    • do we want to alarm on errors on these status bytes

Some more background about the SamTec Firefly code and how the board is organized.

There are a few different types of Firefly devices on the command module.

  • 4 channel 25 G transceivers
  • 12 channel 14 G transmitters
  • 12 channel 14 G receivers
  • 12 channel 25 G transmitters
  • 12 channel 25 G receivers
    The 12 channel devices can be either the 25 G or 14 G speeds. The 4 channel transceivers are always 25 G. Each transceiver is connected to one of the two FPGAs.

The register maps are different on all these devices, so we have to be aware of what kind of a device we are talking about.

There are two separate I2C controllers used to control the Firefly modules: one to control those connected to the KU15P and one to control those connected to the VU7P. The I2C modules also sit behind I2C bus expanders since many of them have the same I2C address. The addressing for the devices is defined in this code location.

struct dev_i2c_addr_t ff_i2c_addrs[NFIREFLIES] = {
{"K01 12 Tx GTH", 0x70, 0, 0x50}, //
{"K01 12 Rx GTH", 0x70, 1, 0x54}, //
{"K02 12 Tx GTH", 0x70, 2, 0x50}, //
{"K02 12 Rx GTH", 0x70, 3, 0x54}, //
{"K03 12 Tx GTH", 0x70, 4, 0x50}, //
{"K03 12 Rx GTH", 0x70, 5, 0x54}, //
{"K04 4 XCVR GTY", 0x71, 0, 0x50}, //
{"K05 4 XCVR GTY", 0x71, 1, 0x50}, //
{"K06 4 XCVR GTY", 0x71, 2, 0x50}, //
{"K07 12 Tx GTY", 0x71, 3, 0x50}, //
{"K07 12 Rx GTY", 0x71, 4, 0x54}, //
{"V01 4 XCVR GTY", 0x70, 0, 0x50}, //
{"V02 4 XCVR GTY", 0x70, 1, 0x50}, //
{"V03 4 XCVR GTY", 0x70, 2, 0x50}, //
{"V04 4 XCVR GTY", 0x70, 3, 0x50}, //
{"V05 4 XCVR GTY", 0x70, 4, 0x50}, //
{"V06 4 XCVR GTY", 0x70, 5, 0x50}, //
{"V07 4 XCVR GTY", 0x71, 0, 0x50}, //
{"V08 4 XCVR GTY", 0x71, 1, 0x50}, //
{"V09 4 XCVR GTY", 0x71, 2, 0x50}, //
{"V10 4 XCVR GTY", 0x71, 3, 0x50}, //
{"V11 12 Tx GTY", 0x70, 6, 0x50}, //
{"V11 12 Rx GTY", 0x70, 7, 0x54}, //
{"V12 12 Tx GTY", 0x71, 4, 0x50}, //
{"V12 12 Rx GTY", 0x71, 5, 0x54}, //
};

The first field is a name; those devices that start with KU are connected to the Kintex KU15P and those that start with VU are connected to the VU7P.

Currently there are several different parts to the FireFlyTask.c code that do the following.

  • loop over all firefly devices and read out the registers that need to be monitored continuously
  • handle incoming messages, which can trigger individual registers read/write commands. The current list of commands that are handled are
    1. enable CDR register on one or all devices
    2. disable CDR register on one or all devices
    3. enable transmitters on one or all devices
    4. disable transmitter on one or all devices
    5. read or write an arbitrary control byte

Here is a proposed plan of action

  • Do the first task to disable receivers by modeling the code on the transmitter disable code.
    static int disable_transmit(bool disable, int num_ff) // todo: actually test this
    Trigger this code by the same messages for enable/disable as shown here:
    case FFLY_DISABLE_TRANSMITTER:
    disable_transmit(true, channel);
    break;
    case FFLY_ENABLE_TRANSMITTER:
    disable_transmit(false, channel);
    break;
    (Rename the FFLY_DISABLE_TRANSMITTER just as FFLY_DISABLE and similar for the enable.)
  • call the disable functions at the start of the task, before the infinite loop.
  • Extend the monitoring (which currently just reads out the temperature on each device) to include the status bytes.
    • figure out what status bytes are on each devices. If they are the same we are good. If they are different then we need to do something smarter.
    • adapt the code to go from monitoring only one piece of information to many
    • adapt the command line interface to make this data available
      • do we also need to send this to the Zynq?

Firefly register finer grained control

Goal:
Allow finer grained control of the samtec firefly devices.
Currently can only turn the transmitters on the lasers on or off en masse, or turn on and off the CDR circuitry en masse.

Would like two things to move forward:

  1. allow specification of a mask of some sort to only manipulate certain devices
  2. Expand the list of available commands
  3. Allow reading and writing of arbitrary registers

issue with TM4C ADC inputs 16-19

Describe the bug
ADC inputs 16-19 are bogus

To Reproduce
read out ADC inputs

** Tests:

@pwittich is exploring that the analog inputs that don’t work are the ones with with an alternate function for the UART that we use for the front panel communication. In order to select the analog pins a few things must be done.

  1. The pin must be selected as an analog input in the GPIO_AMSEL register. THIS IS OK
  2. The pin must be deselected as a digital input in the GPIO_DEN register. THIS IS OK
  3. The alternate function must be selected in the GPIO_AFSEL register (AF = alternate function.) Was wrong, set to 0xF.
  4. Which alternate function must be selected in the GPIO_PCTL register. The bit for the ADC inputs is the ‘analog or special function’ bit (?). Here for the 32 bits of the register each of the 8 bits of the GPIO bank are assigned 4 bits to control (see page 768 of the data sheet.) the definition of those 4 bits is described on page 1550 Table 25-5. It appears that bit 0 has to be set for this function: 0x1111.

@CRStrohman shorted the ADC inputs, one at a time, to either GND or 0.85 volts. I ran the "ADC" command each time and observed what, if anything, changed.

For all but 4 channels, the ADC reading of the shorted channel was either 0v or 0.85v, as expected. In addition, none of the other channels was influenced.

There were 4 channels where the reported value did not go to 0v nor 0.85v, but reported some other value. These 4 channels were 16, 17, 18, and 19. Also, these 4 channels were sometimes affected by changes on other channels.

Signal Name
VCC_3V3
ADC Channel
16
Normal readout
2.49
Readout when shorted to 0.0v
2.49
Readout when shorted to 0.85v
2.50
Notes

  1. When (chan 1) V_MGTY1_AVCC = 0.85v, VCC_3V3 reports 1.67v
  2. When (chan 0) V_MGTY1_AVTT = 0.85v, VCC_3V3 reports 3.32v

Signal Name
V_MGTY2_VCCAUX
ADC Channel
17
Normal readout
1.72
Readout when shorted to 0.0v
1.72
Readout when shorted to 0.85v
1.72
Notes

  1. When (chan 3) V_VCCINT = 0, V_MGTY2_VCCAUX reports 2.15v
  2. When (chan 2) V_MGTY1_VCCAUX = 0, V_MGTY2_VCCAUX reports 0.82v
  3. When (chan 2) V_MGTY1_VCCAUX = 0.85v, V_MGTY2_VCCAUX reports 1.24v

Signal Name
V_MGTY2_AVCC
ADC Channel
18
Normal Readout
1.24
Readout when shorted to 0.0v
1.21
Readout when shorted to 0.85v
1.24
Notes

  1. When (chan 4) K_MGTY_AVTT = 0.85v, V_MGTY2_AVCC reports 1.66v
  2. When (chan 5) K_MGTY_AVCC = 0.85v, V_MGTY2_AVCC reports 0.85v

Signal Name
V_MGTY2_AVTT
ADC Channel
19
Normal Readout
1.24
Readout when shorted to 0.0v
1.24
Readout when shorted to 0.85v
1.24
Notes

  1. When (chan 6) K_MGTY_VCCAUX = 0, V_MGTY2_AVTT reports 0.34v
  2. When (chan 7) VCC_1V8 = 0, V_MGTY2_AVTT reports 2.14v
  3. When (chan 6) K_MGTY_VCCAUX = 0.85v, V_MGTY2_AVTT reports 0.77v
  4. When (chan 7) VCC_1V8 = 0.85v, V_MGTY2_AVTT reports 1.72v

remove an eeprom-loading hardcode in initTask

issue : there is a hardcode in initTask for loading a clock config from eeprom to the CM board, while the detection of a garbage eeprom has been implemented here.

Maybe I forgot to remove this hardcode accordingly?

resolve: will try removing this hardcode and check if the detection of garbage eeprom will quit the initialization as expected.

rationalize CLI output

Cleanup CLI to make it easier to parse by computer programs.

Alternatively, implement I2C slave for this (can we have Zynq also be an I2C master?)

get ready for Rev 2

Need to get ready for Rev 2 of the CM. This issue is to track what needs to be done.

  1. different pinout needs to be adapted to
  2. different power supplies with more LGA80D
  3. switch soft UART to hard UART for Zynq comms path
  4. changes with firefly configurations

Update I2C programming interface to allow for the new larger EEPROM on Rev2b

Rev2b will have a larger EEPROM where the address is more than one byte. Need to adapt to this.

First pass might be to just change the commands here to allow for multi-byte addresses

int apollo_i2c_ctl_reg_r(uint8_t device, uint8_t address, uint8_t reg_address, uint8_t nbytes, uint8_t data[MAX_BYTES])

that is,

  1. change reg_address from a uint8_t to an array (like the data field)
  2. add an argument nbytes_addr similar to the nbytes field which counts how many address bytes there are
  3. change the code here to adapt to this
    tSMBusStatus r = SMBusMasterI2CWriteRead(smbus, address, &reg_address, 1, data, nbytes);
    if (r != SMBUS_OK) {
    retval = -1;
    }

    both the read and write reg functions will need to be adapted. I think 4 bytes of address is probably enough.
  4. adapt the CLI functions in
    BaseType_t i2c_ctl_reg_r(int argc, char **argv, char *m)
    for the new interface. Probably will not need to change the parsing of the input, just the backend
  5. adapt all other places where the relevant functions are used.

Data sheet for new EEPROM attached to this issue.

24CS512_EEPROM.pdf

There is a board with such an EEPROM available somewhere, @CRStrohman can tell us.

Detailed prescription from CRS:

I've attached the datasheet, and here is a quick summary of writing one
byte to a random address or reading one byte from a random address. I
don't think we can generate these sequences with the current commands.
There are also "page write" (page 16), "current address read" (page 20),
and "sequential read" (page 22).

Write one random byte (page 15):

  1. send START
  2. send device address byte
  3. wait for ACK
  4. send high address byte
  5. wait for ACK
  6. send low address byte
  7. wait for ACK
  8. send data byte
  9. wait for ACK
  10. send STOP
  11. EEPROM is unavailable for Twc (5 msec max)

Read one random byte (page 21):

  1. send START
  2. send device address byte
  3. wait for ACK
  4. send high address byte
  5. wait for ACK
  6. send low address byte
  7. wait for ACK
  8. send RESTART
  9. send device address
  10. wait for ACK
  11. read data byte
  12. send NACK (I think the picture on page 21 is wrong at this point)
  13. send STOP

We will probably want "page write" and "sequential read" for storing and
reading clock chip configuration data. The "page write" will probably
want a command-line function that is driven from the Zynq. The 5 msec
write cycle is incurred for either a single byte or an entire 128 byte
page. I don't think we need a command-line function for "sequential read".

Two CLIs from FP and Zynq

Current code allows to switch between the CLI on the front panel and the Zynq by changing two lines of code (CLI_UART in FreeRTOSConfig.h). It does require a recompile.

New idea is to have two CLIs running at the same time.

  • CLI should be independent of each other
  • communicate with tasks exclusively via queues or equivalent mechanism, i.e., hardware does not get manipulated by CLI directly. I think this is already the case, except maybe reading the DIP switch status.
  • pass the UART (for the output) and the queue (for the input from the UART interrupt) via the void *pvparameters argument for the CLI task
  • functions are not reentrant; can I assume that only one of the two CLIs will be active at any given time? In particular there is a single static buffer used in the CLI itself for handling the input and output. This probably will get screwed up if they are accessed at the same time.

Clean up CommandLineTask file

CommandLineTask.c is too long. Proposal is to figure out a logical split of the file into separate files. CommandLineTask.c should presumably hold the actual FreeRTOS task and the interface to the micro-read line library and the functions that implement the tasks should be split into a few separate files grouped by some logical principle

cmpwrup fails from time to time

When commands cmpwrdown cmpwerup are called, from time to time cmpwerup will fail with the message:
CM 1 failed to powered up in time

And PWR_GOOD appears to be 0.

To Reproduce

  1. Log in cms@apollo
  2. do 'BUTool.exe -a /opt/address_tables/connections.xml'
  3. do 'cmpwerdown' cmpwerup' multiple times until error appears

firefly task updates

Need to clean up the register list for the firefly task, and unify all accesses to firefly registers through the common interface of the accessor functions to enable the use of semaphores to be able to access the external I2C registers.

Snapshot clearall function

Is your feature request related to a problem? Please describe.
There are a lot of LGA80Ds on our board. The snapshot on each page of the device comes with a factory value that needs to be cleared first in order for it to work. It gets quite tedious to clear them up one by one.

Describe the solution you'd like
A snapshot all 1 function would be very helpful. It could also be helpful to be able to read them all at once with snapshot all 0.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.