Tool/software:
I am trying to configure the DS320PR810 redriver through SMBus using an MCU programmed to write to the memory addresses of the redriver's registers.
I have 2 redrivers, one for each direction that are configured to have addresses using the EQ/ADDR pins with (L0, L0) for one and (L1, L1) for the other.
So there are actually 2 sets of addresses in each of them. The memory address mode that they operate with is 8bit from what I read.
I just defined some constants in the C code for the addresses and various configuration values and then I use them in the MCU C functions for communicating with the redriver.
In my case, there is more loss in a direction, from GPU to CPU and for the other way around, CPU to GPU there is less loss and I just want it to act as a basic signal conditioning without anything fancy.
Bellow is the code for configuring the redrivers, and I am curious if I need to configure anything else besides what is written bellow and if the code seems alright. Also, I could not find enough information about the EQ profiles and which ones should I use. I guess this is based on the medium used for transmission of the pcie signal, in my case being cable + PCB
I am assuming that each channel has a unique address and from that address I have the same offsets that I need to write to across all channels. For example, if I want to write to channel 0 the eq settings, I would need to write to the channel_0_Address + eq_offset_address.
Also, I saw that some registers have reserved bits so I am not doing anything with them but I am writing 0 to them, maybe I should first read the values from registers with reserved bits and only change the ones that I need, writing back to the register the previous read value with only the changed bits that I am interested in.
#include "main.h"
#include <stdio.h>
#include <string.h>
#include <stm32f0xx_hal_i2c.h>
extern I2C_HandleTypeDef hi2c2;
#define CPU_GPU_0_3_ADDR_I2C 0x18
#define CPU_GPU_4_7_ADDR_I2C 0x19
#define GPU_CPU_0_3_ADDR_I2C 0x22
#define GPU_CPU_4_7_ADDR_I2C 0x23
#define CHANNEL_0_REGISTER 0x00
#define CHANNEL_1_REGISTER 0x20
#define CHANNEL_2_REGISTER 0x40
#define CHANNEL_3_REGISTER 0x60
#define CHANNEL_4_REGISTER 0x00
#define CHANNEL_5_REGISTER 0x20
#define CHANNEL_6_REGISTER 0x40
#define CHANNEL_7_REGISTER 0x60
#define EQ_CONTROL_REGISTER_OFFSET 0x01
#define EQ_CONTROL_EQ_STAGE1_BYPASS 0x80
#define EQ_CONTROL_EQ_STAGE1_3 0x40
#define EQ_CONTROL_EQ_STAGE1_2 0x20
#define EQ_CONTROL_EQ_STAGE1_1 0x10
#define EQ_CONTROL_EQ_STAGE1_0 0x08
#define EQ_CONTROL_EQ_STAGE2_2 0x04
#define EQ_CONTROL_EQ_STAGE2_1 0x02
#define EQ_CONTROL_EQ_STAGE2_0 0x01
#define EQ_GAIN_FLAT_GAIN_REGISTER_OFFSET 0x03
#define EQ_PROFILE_3 0x40
#define EQ_PROFILE_2 0x20
#define EQ_PROFILE_1 0x10
#define EQ_PROFILE_0 0x08
#define FLAT_GAIN_2 0x04
#define FLAT_GAIN_1 0x02
#define FLAT_GAIN_0 0x01
#define RX_DETECT_CONTROL_REGISTER_OFFSET 0x04
#define MR_RX_DET_MAN 0x04 //force always detect
#define EN_RX_DET_COUNT 0x02 //enable additional rx detect polling
#define SEL_RX_DET_COUNT 0x01 //enable additional rx detect 0 = 2 valid detections, 1 = 3 additional valid detections
#define BIAS_REGISTER_OFFSET 0x06
#define BIAS_CURRENT_2 0x20
#define BIAS_CURRENT_1 0x10
#define BIAS_CURRENT_0 0x08
static void initialize_channel_eq(uint16_t redriver_address, uint16_t channel_register_address, uint8_t eq_index) {
HAL_I2C_Mem_Write_IT(&hi2c2, redriver_address, channel_register_address + EQ_CONTROL_REGISTER_OFFSET, I2C_MEMADD_SIZE_8BIT, &eq_index, 1);
}
static void initialize_channel_rx_detect(uint16_t redriver_address, uint16_t channel_register_address, uint8_t rx_detect) {
HAL_I2C_Mem_Write_IT(&hi2c2, redriver_address, channel_register_address + RX_DETECT_CONTROL_REGISTER_OFFSET, I2C_MEMADD_SIZE_8BIT, &rx_detect, 1);
}
static void initialize_channel_bias(uint16_t redriver_address, uint16_t channel_register_address, uint8_t bias) {
HAL_I2C_Mem_Write_IT(&hi2c2, redriver_address, channel_register_address + BIAS_REGISTER_OFFSET, I2C_MEMADD_SIZE_8BIT, &bias, 1);
}
static void initialize_channel_eq_profile(uint16_t redriver_address, uint16_t channel_register_address, uint8_t eq_profile) {
HAL_I2C_Mem_Write_IT(&hi2c2, redriver_address, channel_register_address + EQ_GAIN_FLAT_GAIN_REGISTER_OFFSET, I2C_MEMADD_SIZE_8BIT, &eq_profile, 1);
}
static void initialize_gpu_cpu_redriver()
{
initialize_channel_eq(GPU_CPU_0_3_ADDR_I2C, CHANNEL_0_REGISTER, EQ_CONTROL_EQ_STAGE2_2 | EQ_CONTROL_EQ_STAGE1_2);
initialize_channel_eq(GPU_CPU_0_3_ADDR_I2C, CHANNEL_1_REGISTER, EQ_CONTROL_EQ_STAGE2_2 | EQ_CONTROL_EQ_STAGE1_2);
initialize_channel_eq(GPU_CPU_0_3_ADDR_I2C, CHANNEL_2_REGISTER, EQ_CONTROL_EQ_STAGE2_2 | EQ_CONTROL_EQ_STAGE1_2);
initialize_channel_eq(GPU_CPU_0_3_ADDR_I2C, CHANNEL_3_REGISTER, EQ_CONTROL_EQ_STAGE2_2 | EQ_CONTROL_EQ_STAGE1_2);
initialize_channel_eq(GPU_CPU_4_7_ADDR_I2C, CHANNEL_4_REGISTER, EQ_CONTROL_EQ_STAGE2_2 | EQ_CONTROL_EQ_STAGE1_1);
initialize_channel_eq(GPU_CPU_4_7_ADDR_I2C, CHANNEL_5_REGISTER, EQ_CONTROL_EQ_STAGE2_2 | EQ_CONTROL_EQ_STAGE1_1);
initialize_channel_eq(GPU_CPU_4_7_ADDR_I2C, CHANNEL_6_REGISTER, EQ_CONTROL_EQ_STAGE2_2 | EQ_CONTROL_EQ_STAGE1_1);
initialize_channel_eq(GPU_CPU_4_7_ADDR_I2C, CHANNEL_7_REGISTER, EQ_CONTROL_EQ_STAGE2_2 | EQ_CONTROL_EQ_STAGE1_1);
initialize_channel_rx_detect(GPU_CPU_0_3_ADDR_I2C, CHANNEL_0_REGISTER, EN_RX_DET_COUNT | SEL_RX_DET_COUNT);
initialize_channel_rx_detect(GPU_CPU_0_3_ADDR_I2C, CHANNEL_1_REGISTER, EN_RX_DET_COUNT | SEL_RX_DET_COUNT);
initialize_channel_rx_detect(GPU_CPU_0_3_ADDR_I2C, CHANNEL_2_REGISTER, EN_RX_DET_COUNT | SEL_RX_DET_COUNT);
initialize_channel_rx_detect(GPU_CPU_0_3_ADDR_I2C, CHANNEL_3_REGISTER, EN_RX_DET_COUNT | SEL_RX_DET_COUNT);
initialize_channel_rx_detect(GPU_CPU_4_7_ADDR_I2C, CHANNEL_4_REGISTER, EN_RX_DET_COUNT | SEL_RX_DET_COUNT);
initialize_channel_rx_detect(GPU_CPU_4_7_ADDR_I2C, CHANNEL_5_REGISTER, EN_RX_DET_COUNT | SEL_RX_DET_COUNT);
initialize_channel_rx_detect(GPU_CPU_4_7_ADDR_I2C, CHANNEL_6_REGISTER, EN_RX_DET_COUNT | SEL_RX_DET_COUNT);
initialize_channel_rx_detect(GPU_CPU_4_7_ADDR_I2C, CHANNEL_7_REGISTER, EN_RX_DET_COUNT | SEL_RX_DET_COUNT);
initialize_channel_bias(GPU_CPU_0_3_ADDR_I2C, CHANNEL_0_REGISTER, BIAS_CURRENT_0);
initialize_channel_bias(GPU_CPU_0_3_ADDR_I2C, CHANNEL_1_REGISTER, BIAS_CURRENT_0);
initialize_channel_bias(GPU_CPU_0_3_ADDR_I2C, CHANNEL_2_REGISTER, BIAS_CURRENT_0);
initialize_channel_bias(GPU_CPU_0_3_ADDR_I2C, CHANNEL_3_REGISTER, BIAS_CURRENT_0);
initialize_channel_bias(GPU_CPU_4_7_ADDR_I2C, CHANNEL_4_REGISTER, BIAS_CURRENT_0);
initialize_channel_bias(GPU_CPU_4_7_ADDR_I2C, CHANNEL_5_REGISTER, BIAS_CURRENT_0);
initialize_channel_bias(GPU_CPU_4_7_ADDR_I2C, CHANNEL_6_REGISTER, BIAS_CURRENT_0);
initialize_channel_bias(GPU_CPU_4_7_ADDR_I2C, CHANNEL_7_REGISTER, BIAS_CURRENT_0);
initialize_channel_eq_profile(GPU_CPU_0_3_ADDR_I2C, CHANNEL_0_REGISTER, EQ_PROFILE_3 | FLAT_GAIN_0 | FLAT_GAIN_2);
initialize_channel_eq_profile(GPU_CPU_0_3_ADDR_I2C, CHANNEL_1_REGISTER, EQ_PROFILE_3 | FLAT_GAIN_0 | FLAT_GAIN_2);
initialize_channel_eq_profile(GPU_CPU_0_3_ADDR_I2C, CHANNEL_2_REGISTER, EQ_PROFILE_3 | FLAT_GAIN_0 | FLAT_GAIN_2);
initialize_channel_eq_profile(GPU_CPU_0_3_ADDR_I2C, CHANNEL_3_REGISTER, EQ_PROFILE_3 | FLAT_GAIN_0 | FLAT_GAIN_2);
initialize_channel_eq_profile(GPU_CPU_4_7_ADDR_I2C, CHANNEL_4_REGISTER, EQ_PROFILE_3 | FLAT_GAIN_0 | FLAT_GAIN_2);
initialize_channel_eq_profile(GPU_CPU_4_7_ADDR_I2C, CHANNEL_5_REGISTER, EQ_PROFILE_3 | FLAT_GAIN_0 | FLAT_GAIN_2);
initialize_channel_eq_profile(GPU_CPU_4_7_ADDR_I2C, CHANNEL_6_REGISTER, EQ_PROFILE_3 | FLAT_GAIN_0 | FLAT_GAIN_2);
initialize_channel_eq_profile(GPU_CPU_4_7_ADDR_I2C, CHANNEL_7_REGISTER, EQ_PROFILE_3 | FLAT_GAIN_0 | FLAT_GAIN_2);
}
static void initialize_cpu_gpu_redriver()
{
initialize_channel_eq(CPU_GPU_0_3_ADDR_I2C, CHANNEL_0_REGISTER, EQ_CONTROL_EQ_STAGE2_0 | EQ_CONTROL_EQ_STAGE1_BYPASS);
initialize_channel_eq(CPU_GPU_0_3_ADDR_I2C, CHANNEL_1_REGISTER, EQ_CONTROL_EQ_STAGE2_0 | EQ_CONTROL_EQ_STAGE1_BYPASS);
initialize_channel_eq(CPU_GPU_0_3_ADDR_I2C, CHANNEL_2_REGISTER, EQ_CONTROL_EQ_STAGE2_0 | EQ_CONTROL_EQ_STAGE1_BYPASS);
initialize_channel_eq(CPU_GPU_0_3_ADDR_I2C, CHANNEL_3_REGISTER, EQ_CONTROL_EQ_STAGE2_0 | EQ_CONTROL_EQ_STAGE1_BYPASS);
initialize_channel_eq(CPU_GPU_4_7_ADDR_I2C, CHANNEL_4_REGISTER, EQ_CONTROL_EQ_STAGE2_0 | EQ_CONTROL_EQ_STAGE1_BYPASS);
initialize_channel_eq(CPU_GPU_4_7_ADDR_I2C, CHANNEL_5_REGISTER, EQ_CONTROL_EQ_STAGE2_0 | EQ_CONTROL_EQ_STAGE1_BYPASS);
initialize_channel_eq(CPU_GPU_4_7_ADDR_I2C, CHANNEL_6_REGISTER, EQ_CONTROL_EQ_STAGE2_0 | EQ_CONTROL_EQ_STAGE1_BYPASS);
initialize_channel_eq(CPU_GPU_4_7_ADDR_I2C, CHANNEL_7_REGISTER, EQ_CONTROL_EQ_STAGE2_0 | EQ_CONTROL_EQ_STAGE1_BYPASS);
initialize_channel_rx_detect(CPU_GPU_0_3_ADDR_I2C, CHANNEL_0_REGISTER, MR_RX_DET_MAN);
initialize_channel_rx_detect(CPU_GPU_0_3_ADDR_I2C, CHANNEL_1_REGISTER, MR_RX_DET_MAN);
initialize_channel_rx_detect(CPU_GPU_0_3_ADDR_I2C, CHANNEL_2_REGISTER, MR_RX_DET_MAN);
initialize_channel_rx_detect(CPU_GPU_0_3_ADDR_I2C, CHANNEL_3_REGISTER, MR_RX_DET_MAN);
initialize_channel_rx_detect(CPU_GPU_4_7_ADDR_I2C, CHANNEL_4_REGISTER, MR_RX_DET_MAN);
initialize_channel_rx_detect(CPU_GPU_4_7_ADDR_I2C, CHANNEL_5_REGISTER, MR_RX_DET_MAN);
initialize_channel_rx_detect(CPU_GPU_4_7_ADDR_I2C, CHANNEL_6_REGISTER, MR_RX_DET_MAN);
initialize_channel_rx_detect(CPU_GPU_4_7_ADDR_I2C, CHANNEL_7_REGISTER, MR_RX_DET_MAN);
initialize_channel_bias(CPU_GPU_0_3_ADDR_I2C, CHANNEL_0_REGISTER, BIAS_CURRENT_1);
initialize_channel_bias(CPU_GPU_0_3_ADDR_I2C, CHANNEL_1_REGISTER, BIAS_CURRENT_1);
initialize_channel_bias(CPU_GPU_0_3_ADDR_I2C, CHANNEL_2_REGISTER, BIAS_CURRENT_1);
initialize_channel_bias(CPU_GPU_0_3_ADDR_I2C, CHANNEL_3_REGISTER, BIAS_CURRENT_1);
initialize_channel_bias(CPU_GPU_4_7_ADDR_I2C, CHANNEL_4_REGISTER, BIAS_CURRENT_1);
initialize_channel_bias(CPU_GPU_4_7_ADDR_I2C, CHANNEL_5_REGISTER, BIAS_CURRENT_1);
initialize_channel_bias(CPU_GPU_4_7_ADDR_I2C, CHANNEL_6_REGISTER, BIAS_CURRENT_1);
initialize_channel_bias(CPU_GPU_4_7_ADDR_I2C, CHANNEL_7_REGISTER, BIAS_CURRENT_1);
initialize_channel_eq_profile(CPU_GPU_0_3_ADDR_I2C, CHANNEL_0_REGISTER, EQ_PROFILE_0 | FLAT_GAIN_0 | FLAT_GAIN_1);
initialize_channel_eq_profile(CPU_GPU_0_3_ADDR_I2C, CHANNEL_1_REGISTER, EQ_PROFILE_0 | FLAT_GAIN_0 | FLAT_GAIN_1);
initialize_channel_eq_profile(CPU_GPU_0_3_ADDR_I2C, CHANNEL_2_REGISTER, EQ_PROFILE_0 | FLAT_GAIN_0 | FLAT_GAIN_1);
initialize_channel_eq_profile(CPU_GPU_0_3_ADDR_I2C, CHANNEL_3_REGISTER, EQ_PROFILE_0 | FLAT_GAIN_0 | FLAT_GAIN_1);
initialize_channel_eq_profile(CPU_GPU_4_7_ADDR_I2C, CHANNEL_4_REGISTER, EQ_PROFILE_0 | FLAT_GAIN_0 | FLAT_GAIN_1);
initialize_channel_eq_profile(CPU_GPU_4_7_ADDR_I2C, CHANNEL_5_REGISTER, EQ_PROFILE_0 | FLAT_GAIN_0 | FLAT_GAIN_1);
initialize_channel_eq_profile(CPU_GPU_4_7_ADDR_I2C, CHANNEL_6_REGISTER, EQ_PROFILE_0 | FLAT_GAIN_0 | FLAT_GAIN_1);
initialize_channel_eq_profile(CPU_GPU_4_7_ADDR_I2C, CHANNEL_7_REGISTER, EQ_PROFILE_0 | FLAT_GAIN_0 | FLAT_GAIN_1);
}
void initialize_redrivers() {
HAL_I2C_IsDeviceReady(&hi2c2, CPU_GPU_0_3_ADDR_I2C, 1024, 1);
HAL_I2C_IsDeviceReady(&hi2c2, CPU_GPU_4_7_ADDR_I2C, 1024, 1);
HAL_I2C_IsDeviceReady(&hi2c2, GPU_CPU_0_3_ADDR_I2C, 1024, 1);
HAL_I2C_IsDeviceReady(&hi2c2, GPU_CPU_0_3_ADDR_I2C, 1024, 1);
initialize_gpu_cpu_redriver();
initialize_cpu_gpu_redriver();
}