Skip to content

Commit

Permalink
Add ipmi command to configure clock switch and save it in eeprom
Browse files Browse the repository at this point in the history
  • Loading branch information
gustavosr8 committed Sep 29, 2023
1 parent 0b6193a commit fe352ad
Show file tree
Hide file tree
Showing 19 changed files with 288 additions and 228 deletions.
24 changes: 24 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,3 +130,27 @@ Now you can use the typical GDB commands to inspect the program flow and variabl
(gdb) monitor reset halt # Resets the microcontroller and immediately halts
(gdb) monitor reset run # Resets the microcontroller and starts executing
(gdb) load # Reload the firmware into flash


## IPMI Custom Commands
The IPMI allow us to create custom commands according to the project needs. [ipmitool](https://codeberg.org/IPMITool/ipmitool) can be used to send the commands

### Clock switch configuration
It's possible to configure the clock switch. For the AFC v3.1 (ADN4604ASVZ) you can use the following scheme:
- **Port I/O (bit 7)**: Use it to configure the port as an input ('0') or output ('1'). Unused ports should be left configured as inputs;
- **Output Port Signal Source (bits 0 to 3)**: Select the input port for the respective output port.

For the AFC v4 (IDT 8V54816) you can use the following scheme:
- **Port I/O (bit 7)**: Use it to configure the port as an input ('0') or output ('1'). Unused ports should be left configured as inputs;
- **Termination On/Off (bit 6)**: Use to set the internal termination. '0' is off (high-impedance), '1' is on (100 $\Omega$)
- **Polarity (bit 5)**: Set the channel polarity. '0' for inverted, '1' for non-inverted
- **Output Port Signal Source (bits 0 to 3)**: Select the input port for the respective output port.


The command to write the configuration is the above:

ipmitool -I lan -H mch_host_name -A none -T 0x82 -m 0x20 -t (112 + num_slot*2) raw 0x32 0x03 <configuration_array_in_hex>

To read the actual configuration, use:

ipmitool -I lan -H mch_host_name -A none -T 0x82 -m 0x20 -t (112 + num_slot*2) raw 0x32 0x04
5 changes: 5 additions & 0 deletions modules/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ if (";${TARGET_MODULES};" MATCHES ";FRU;")
set(MODULES_FLAGS "${MODULES_FLAGS} -DMODULE_FRU")
endif()

if (";${TARGET_MODULES};" MATCHES ";CLOCK_CONFIG;")
set(PROJ_SRCS ${PROJ_SRCS} ${MODULE_PATH}/clock_config.c )
set(MODULES_FLAGS "${MODULES_FLAGS} -DMODULE_CLOCK_CONFIG")
endif()

if (";${TARGET_MODULES};" MATCHES ";EEPROM_24XX02;")
set(PROJ_SRCS ${PROJ_SRCS} ${MODULE_PATH}/eeprom_24xx02.c )
set(MODULES_FLAGS "${MODULES_FLAGS} -DMODULE_EEPROM_24XX02")
Expand Down
62 changes: 0 additions & 62 deletions modules/adn4604.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,73 +34,11 @@
/* Project Includes */
#include "port.h"
#include "adn4604.h"
#include "adn4604_usercfg.h"
#include "i2c.h"
#include "i2c_mapping.h"

adn_connect_map_t con;

void adn4604_init( void )
{
uint16_t out_enable_flag = {
ADN4604_EN_OUT_0 << 0 |
ADN4604_EN_OUT_1 << 1 |
ADN4604_EN_OUT_2 << 2 |
ADN4604_EN_OUT_3 << 3 |
ADN4604_EN_OUT_4 << 4 |
ADN4604_EN_OUT_5 << 5 |
ADN4604_EN_OUT_6 << 6 |
ADN4604_EN_OUT_7 << 7 |
ADN4604_EN_OUT_8 << 8 |
ADN4604_EN_OUT_9 << 9 |
ADN4604_EN_OUT_10 << 10 |
ADN4604_EN_OUT_11 << 11 |
ADN4604_EN_OUT_12 << 12 |
ADN4604_EN_OUT_13 << 13 |
ADN4604_EN_OUT_14 << 14 |
ADN4604_EN_OUT_15 << 15
};

/* Disable UPDATE' pin by pulling it GPIO_LEVEL_HIGH */
gpio_set_pin_state( PIN_PORT(GPIO_ADN_UPDATE), PIN_NUMBER(GPIO_ADN_UPDATE), GPIO_LEVEL_HIGH );

/* There's a delay circuit in the Reset pin of the clock switch, we must wait until it clears out */
while( gpio_read_pin( PIN_PORT(GPIO_ADN_RESETN), PIN_NUMBER(GPIO_ADN_RESETN) ) == 0 ) {
vTaskDelay( 50 );
}

/* Configure the interconnects */
con.out0 = ADN4604_CFG_OUT_0;
con.out1 = ADN4604_CFG_OUT_1;
con.out2 = ADN4604_CFG_OUT_2;
con.out3 = ADN4604_CFG_OUT_3;
con.out4 = ADN4604_CFG_OUT_4;
con.out5 = ADN4604_CFG_OUT_5;
con.out6 = ADN4604_CFG_OUT_6;
con.out7 = ADN4604_CFG_OUT_7;
con.out8 = ADN4604_CFG_OUT_8;
con.out9 = ADN4604_CFG_OUT_9;
con.out10 = ADN4604_CFG_OUT_10;
con.out11 = ADN4604_CFG_OUT_11;
con.out12 = ADN4604_CFG_OUT_12;
con.out13 = ADN4604_CFG_OUT_13;
con.out14 = ADN4604_CFG_OUT_14;
con.out15 = ADN4604_CFG_OUT_15;

adn4604_xpt_config( ADN_XPT_MAP0_CON_REG, con );

/* Enable desired outputs */
for ( uint8_t i = 0; i < 16; i++ ) {
if ( ( out_enable_flag >> i ) & 0x1 ) {
adn4604_tx_control( i, TX_ENABLED );
}
}

adn4604_active_map( ADN_XPT_MAP0 );

adn4604_update();
}

void adn4604_tx_control( uint8_t output, uint8_t tx_mode )
{
uint8_t i2c_addr, i2c_interf;
Expand Down
8 changes: 0 additions & 8 deletions modules/adn4604.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,14 +112,6 @@ enum adn4604_tx_ctl {
TX_ENABLED
};

/**
* @brief Initializes the ADN4604 Clock switch hardware
*
* This IC starts with a pre-defined configuration provided by the board port in the adn4604_usercfg.h file.
* The current port status may be changed with OEM IPMI commands.
*/
void adn4604_init( void );

/**
* @brief Sets the output status
*
Expand Down
26 changes: 26 additions & 0 deletions modules/clock_config.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#include "clock_config.h"

uint8_t clock_config[16];

/*
* Function to configure the clock switch via ipmi.
* The configuration is sent as an array in the data field.
*
*/
IPMI_HANDLER(ipmi_custom_cmd_write_clock_config, NETFN_CUSTOM, IPMI_CUSTOM_CMD_WRITE_CLOCK_CONFIG, ipmi_msg *req, ipmi_msg *rsp)
{
memcpy(clock_config, req->data, req->data_len);
payload_send_message(FRU_AMC, PAYLOAD_MESSAGE_CLOCK_CONFIG);
rsp->completion_code = IPMI_CC_OK;
}


/*
* Function to read the clock switch configuration via ipmi.
*/
IPMI_HANDLER(ipmi_custom_cmd_read_clock_config, NETFN_CUSTOM, IPMI_CUSTOM_CMD_READ_CLOCK_CONFIG, ipmi_msg *req, ipmi_msg *rsp)
{
rsp->data_len = 16;
memcpy(rsp->data, clock_config, rsp->data_len);
rsp->completion_code = IPMI_CC_OK;
}
7 changes: 7 additions & 0 deletions modules/clock_config.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#include <stdint.h>
#include <string.h>
#include "ipmi.h"
#include "fru.h"
#include "payload.h"

extern uint8_t clock_config[16];
2 changes: 2 additions & 0 deletions modules/ipmi.h
Original file line number Diff line number Diff line change
Expand Up @@ -468,6 +468,8 @@
*/
#define IPMI_CUSTOM_CMD_MMC_GET_FREE_HEAP 0x01
#define IPMI_CUSTOM_CMD_GET_GIT_HASH 0x02
#define IPMI_CUSTOM_CMD_WRITE_CLOCK_CONFIG 0x03
#define IPMI_CUSTOM_CMD_READ_CLOCK_CONFIG 0x04
/**
* @}
*/
Expand Down
2 changes: 2 additions & 0 deletions port/board/afc-bpm/v3_1/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ endif()
#List all modules used by this board
set(TARGET_MODULES
"FRU"
"CLOCK_CONFIG"
"PAYLOAD"
"SDR"
"SCANSTA1101"
Expand All @@ -18,6 +19,7 @@ set(TARGET_MODULES
"DAC_AD84XX"
"EEPROM_AT24MAC"
"EEPROM_24XX64"
"EEPROM_24XX02"
"HOTSWAP_SENSOR"
"LM75"
"MAX6642"
Expand Down
63 changes: 0 additions & 63 deletions port/board/afc-bpm/v3_1/adn4604_usercfg.h

This file was deleted.

Loading

0 comments on commit fe352ad

Please sign in to comment.