Hi guys,
I using
keil uvisionV5.35.0.0
arm_compiler : V6.16
We are developing a project on STM32L071CZYx MCU. which has
flash memory: 192kB
RAM: 20KB
The code perfectly works when it is in separate project but we need to combine both the project.
In 1st project We have configured I2C1 has a slave. i have attached code for the irq_handler
void I2C1_IRQHandler(void) { I2C1->CR1 &= ~(I2C_CR1_RXIE |I2C_CR1_ADDRIE | I2C_CR1_STOPIE | I2C_CR1_TXIE); switch((I2C1->ISR &(I2C_ISR_STOPF | I2C_ISR_ADDR |I2C_ISR_RXNE | I2C_ISR_TXIS))) { case 0x08: //address match dev_addr = ((I2C1->ISR >> 16 ) & 0xFE); // assigning Recieved slave address if(I2C1->ISR & I2C_ISR_DIR) { // Slave address with Read bit if(i2c_state == I2C_GOT_CONTROL_WORD_ADDR) { i2c_state = I2C_REPEATED_START; } else { i2c_state = I2C_RD_STARTED; } __HAL_I2C_CLEAR_FLAG(&hi2c1,(I2C_FLAG_ADDR )); I2C1->CR1 |= (I2C_CR1_TXIE); // enabling Transmitter Interrupt //slave Tx } else { // Slave address with write bit i2c_pkt_length = 0; i2c_state = I2C_WR_STARTED; __HAL_I2C_CLEAR_FLAG(&hi2c1,I2C_FLAG_ADDR); I2C1->CR1 |= (I2C_CR1_RXIE); // stopIE is not required //slave Rx } break; case 0x04: //rx data for master if(i2c_state == I2C_WR_STARTED) { CW =I2C1->RXDR; word_addr = CW; i2c_state = I2C_GOT_CONTROL_WORD_ADDR; } else { i2cdatarx[i2c_pkt_length++] = I2C1->RXDR; i2c_state = I2C_DATA_STARTED; } __HAL_I2C_CLEAR_FLAG(&hi2c1,I2C_FLAG_RXNE); I2C1->CR1 |= (I2C_CR1_RXIE | I2C_CR1_ADDRIE | I2C_CR1_STOPIE); // enabling Rx address match and Stop interrupt break; case 0x20: // detected a stop if (dev_addr == 0xB0 ) { if (i2c_state == I2C_DATA_STARTED || i2c_state == I2C_GOT_CONTROL_WORD_ADDR) { F0_write(word_addr); } else { I2C1->ISR |= I2C_ISR_TXE;//Setting flushing the TX buffer for new data transfer } } else { if (i2c_state == I2C_DATA_STARTED || i2c_state == I2C_WR_STARTED) { if (mode == mFACTORY) { A0_write_FM(word_addr); // writting to sram and Eeprom } else { A0_write(word_addr); } } else { I2C1->ISR |= I2C_ISR_TXE;//Setting flushing the TX buffer for new data transfer } } i2c_state = I2C_IDLE; __HAL_I2C_CLEAR_FLAG(&hi2c1,I2C_FLAG_STOPF); I2C1->CR1 |= (I2C_CR1_ADDRIE); // enabling address match break; case 0x02: // Transmit has detected //i2cdatarx = I2C_read_F0(CW); if (dev_addr == 0xB0) { I2C1->TXDR = F0_Read(CW); } else { if (mode == 1) { I2C1->TXDR = A0_read_FM(CW); } else { I2C1->TXDR = A0_read(CW); } } __HAL_I2C_CLEAR_FLAG(&hi2c1,(I2C_FLAG_ADDR)); I2C1->CR1 |= (I2C_CR1_STOPIE | I2C_CR1_TXIE); break; } }
and 1st project alone uses :
==============================================================================
Total RO Size (Code + RO Data) 9188 ( 8.97kB) Total RW Size (RW Data + ZI Data) 3704 ( 3.62kB) Total ROM Size (Code + RO Data + RW Data) 9228 ( 9.01kB)
And the 2nd project alone uses:
stack memory : 10.5kB
Total RO Size (Code + RO Data) 146028 ( 142.61kB) Total RW Size (RW Data + ZI Data) 19440 ( 18.98kB) Total ROM Size (Code + RO Data + RW Data) 146188 ( 142.76kB)
and the combined code uses :
we have removed the 1280 bytes of global variable(array) and we got,
and even increase the stack memory to : 12kB
In the combined project code crashes when we include 1st projects I2C_IRQ_handler but without it works fine with polling method but we can't include all the required features in it. I have many method like increasing stack size and reducing global variable but nothing worked. I will be thankful if I get an information. and even attached an error pic.
Hey, did you have to implement the Driver_I2C.c manually ? Or did you just import the Driver_I2C.h file and it worked ?
Hi Gopal,you should trace back the instruction that caused HardfFault.You can either look into function hsc_dev_obj_init by looking into call stack, or you can inspect memory at 0x200045C0 and see what was the "return address" value when the HardFault happened.The content of the memory where SP points to should containing the following information in that particular order:R0R1R2R3R12LRreturn addressxPSRthe return address is either the address of the instruction that caused HardFault or the instruction after it depending on the type of the exception.Anyways, for more information you should search online for debugging of HardFault as there is a lot resources you can find on the matter online.Best regards, Milorad
R0
R1
R2
R3
R12
LR
return address
xPSR
Hi Uodami Thank you for reply,
I have add all the required files in the project folder.
Hi Milorad thanks for reply,
earlier I have resolved a hardfault issues by increasing a stack size in a present code.
hsc_dev_obj_init function is an customer given code basically there are 3 other .c file which are given by the customer and they even provide many C scripts for different modes, Baudrate and signaling types to configure datapath , this C scripts we need to call in Main function of the code so that we will be able to configure Module in defined mode, Baudrate and signaling types.
I have attached a one sample C script.
#include "hsc_api.h" #include <stdlib.h> #define STATUS_2_STR(status) status == HSC_OK ? "HSC_OK" : "HSC_ERROR" #define ARRAY_SIZE(array) ((uint8_t)(sizeof(array) / sizeof((array)[0]))) #define ARRAY_MASK(array) \ ({ \ int i, mask = 0; \ for (i = 0; i < ARRAY_SIZE(array); i++) \ mask |= 1 << array[i]; \ mask; \ }) uint32_t host_chns_0[] = {0, 1, 2, 3, 4, 5, 6, 7}; uint32_t line_chns_0[] = {0, 1, 2, 3, 4, 5, 6, 7}; uint8_t num_host_chns_0 = ARRAY_SIZE(host_chns_0); uint8_t num_line_chns_0 = ARRAY_SIZE(line_chns_0); hsc_bundle_rules_t rules; /** * * The following example describes the sequence configuration of example datapath * * @param bundle [I] - The bundle being accessed. * * @return HSC_OK on success, HSC_ERROR on failure */ hsc_status_t bundle_config_0(hsc_bundle_t *bundle) { /* * Below is the bundle rules configuration * * Channel is activated in bundle: * - Host TX channel [0, 1, 2, 3, 4, 5, 6, 7] * - Host RX channel [0, 1, 2, 3, 4, 5, 6, 7] * - Line TX channel [0, 1, 2, 3, 4, 5, 6, 7] * - Line RX channel [0, 1, 2, 3, 4, 5, 6, 7] */ uint32_t chn_idx; hsc_status_t status = HSC_OK; hsc_dev_t *dev = hsc_bundle_dev_get(bundle); /* Default the bundle rules based on the desired application */ if (hsc_dev_bundle_rules(dev, HSC_OPER_MODE_DUPLEX_RETIMER, &rules) == NULL) { HSC_CRIT("Failed construct the bundle rule\n"); return HSC_ERROR; } /* Setup the data rate on each channel */ hsc_bundle_rules_baud_rate_set(&rules, HSC_BAUD_RATE_25p78125G); hsc_bundle_rules_ieee_demap_enable(&rules, false); /* Use physical channels on the Line and host * The rules. Channel bitmask with an enable bit for each channel * to bind/associate with the bundle/bundle. */ /* Configure Host channel mask */ hsc_bundle_rules_chns_mask_set(&rules, HSC_INTF_HOST, ARRAY_MASK(host_chns_0)); /* Configure Line channel mask */ hsc_bundle_rules_chns_mask_set(&rules, HSC_INTF_LINE, ARRAY_MASK(line_chns_0)); /* Host have to operate in PAM/NRZ mode to get desired data rate per channel */ hsc_bundle_rules_signalling_set(&rules, HSC_INTF_HOST, HSC_SIGNAL_MODE_PAM); /* Line have to operate in PAM/NRZ mode to get desired data rate per channel */ hsc_bundle_rules_signalling_set(&rules, HSC_INTF_LINE, HSC_SIGNAL_MODE_PAM); /* Below is Host TX rules configuration information */ hsc_tx_rules_t *tx_rules = NULL; for (chn_idx = 0; chn_idx < num_host_chns_0; chn_idx++) { int16_t host_tx_taps[] = {-100, 700, -100, 0, 0, 0, 0}; /* Configure Host TX rules */ tx_rules = hsc_chn_tx_rules(&rules, host_chns_0[chn_idx], HSC_INTF_HTX); hsc_tx_rules_fir_taps_set(tx_rules, HSC_TX_LUT_3TAP, host_tx_taps); hsc_tx_rules_swing_set(tx_rules, HSC_TX_SWING_100p); hsc_tx_rules_eye_set(tx_rules, HSC_EYE_LEVEL_LOWER, 1000); hsc_tx_rules_eye_set(tx_rules, HSC_EYE_LEVEL_UPPER, 2000); hsc_tx_rules_gray_mapping_enable(tx_rules, true); hsc_tx_rules_dfe_precoder_enable(tx_rules, false); hsc_tx_rules_polarity_set(tx_rules, false); } /* Below is the line TX rules configuration information */ for (chn_idx = 0; chn_idx < num_line_chns_0; chn_idx++) { int16_t line_tx_taps[] ={-200, 700, -100, 0, 0, 0, 0}; /* Line TX rules */ tx_rules = hsc_chn_tx_rules(&rules, line_chns_0[chn_idx], HSC_INTF_LINE); hsc_tx_rules_fir_taps_set(tx_rules, HSC_TX_LUT_3TAP, line_tx_taps); hsc_tx_rules_swing_set(tx_rules, HSC_TX_SWING_100p); hsc_tx_rules_eye_set(tx_rules, HSC_EYE_LEVEL_LOWER, 1000); hsc_tx_rules_eye_set(tx_rules, HSC_EYE_LEVEL_UPPER, 2000); hsc_tx_rules_gray_mapping_enable(tx_rules, true); hsc_tx_rules_dfe_precoder_enable(tx_rules, false); hsc_tx_rules_polarity_set(tx_rules, false); } /* Below is the host RX rules configuration information */ hsc_rx_rules_t *rx_rules = NULL; hsc_rx_rules_advanced_t host_rx_adv_rules; for (chn_idx = 0; chn_idx < num_host_chns_0; chn_idx++) { /* Host RX rules */ rx_rules = hsc_chn_rx_rules(&rules, host_chns_0[chn_idx], HSC_INTF_HOST); //hsc_rx_rules_dsp_mode_set(rx_rules, HSC_DSP_MODE_DFE1_RC_DFE2); hsc_rx_rules_dsp_mode_set(rx_rules, HSC_DSP_MODE_SLC1_RC_SLC2); hsc_rx_rules_autoctle_enable(rx_rules, true); hsc_rx_rules_gray_mapping_enable(rx_rules, true); hsc_rx_rules_polarity_set(rx_rules, false); hsc_rx_rules_advanced_set(rx_rules, &host_rx_adv_rules); hsc_rx_rules_vga_tracking_enable(rx_rules, false); hsc_rx_rules_dfe_precoder_enable(rx_rules, false); hsc_rx_rules_scdr_enable(rx_rules, false); hsc_rx_rules_advanced_get(rx_rules, &host_rx_adv_rules); //host_rx_adv_rules.afe_trim = HSC_AFE_TRIM_AUTO; host_rx_adv_rules.afe_trim = HSC_AFE_TRIM_NEG_4dB; host_rx_adv_rules.mlsd_en = false; } /* Below is the line RX rules configuration information */ hsc_rx_rules_advanced_t line_rx_adv_rules; for (chn_idx = 0; chn_idx < num_line_chns_0; chn_idx++) { /* Line RX rules */ rx_rules = hsc_chn_rx_rules(&rules, line_chns_0[chn_idx], HSC_INTF_LINE); hsc_rx_rules_dsp_mode_set(rx_rules, HSC_DSP_MODE_DFE1_RC_DFE2); hsc_rx_rules_autoctle_enable(rx_rules, true); hsc_rx_rules_gray_mapping_enable(rx_rules, true); hsc_rx_rules_polarity_set(rx_rules, false); hsc_rx_rules_advanced_set(rx_rules, &line_rx_adv_rules); hsc_rx_rules_vga_tracking_enable(rx_rules, false); hsc_rx_rules_dfe_precoder_enable(rx_rules, false); hsc_rx_rules_scdr_enable(rx_rules, false); hsc_rx_rules_advanced_get(rx_rules, &line_rx_adv_rules); line_rx_adv_rules.afe_trim = HSC_AFE_TRIM_AUTO; line_rx_adv_rules.mlsd_en = false; } /* Initialize the bundle and tear down any resources that may * already be allocated.*/ status = hsc_bundle_init(bundle, &rules); HSC_NOTE("hsc_bundle_init: %s\n", STATUS_2_STR(status)); /* Bring the bundle up */ status |= hsc_bundle_start(bundle, &rules); HSC_NOTE("hsc_bundle_start: %s\n", STATUS_2_STR(status)); /* Show bundle rules configuration */ status |= hsc_bundle_rules_show(bundle); if (status != HSC_OK) { HSC_NOTE("Configure bundle: %s\n", STATUS_2_STR(status)); return HSC_ERROR; } return status; } /** * This sample program a teardown all configuration of current bundles * @param dev [I] - The device being accessed. * * @return HSC_OK on success, HSC_ERROR on failure */ static hsc_status_t bundles_teardown(hsc_dev_t *dev) { hsc_status_t status = HSC_OK; uint32_t bundle_id = 0; uint32_t max_bundle_nums = hsc_dev_num_bundles(dev); if (hsc_dev_bundle_rules(dev, HSC_OPER_MODE_DUPLEX_RETIMER, &rules) == NULL) { HSC_CRIT("Failed construct the bundle rule\n"); return HSC_ERROR; } /* Init all 16 bundles */ for (bundle_id = 0; bundle_id < max_bundle_nums; bundle_id++) { hsc_bundle_t bundle; hsc_dev_bundle(dev, bundle_id, &bundle); hsc_bundle_rules_chns_mask_set(&rules, HSC_INTF_HOST | HSC_INTF_LINE, 0); status |= hsc_bundle_init(&bundle, &rules); if (status != HSC_OK) { HSC_WARN("hsc_bundle_init bundle %d: FAILED\n", bundle_id); } } return status; } /** * This is the main wrapper method for the example. * * @param argc [I] - The number of input arguments in argv[] * @param argv [I] - The array of input arguments * * @return The return code to the OS (0 == success, anything else for failure) */ int retimer_106G_chester(void) { int rc = EXIT_SUCCESS; hsc_status_t status = HSC_OK; bool flag_wait_link_ready = false; bool flag_show_link_status = false; bool flag_i2c_enable = true; /* Device handle */ static hsc_dev_t device; /* Connect back to the GUI for register access */ //hsc_gui_connect(argc, argv); /* Construct */ if (hsc_dev(&device, 0 /* asic_id */) == NULL) { //hsc_gui_close(); return EXIT_FAILURE; } hsc_dev_i2c_access_enable(&device, flag_i2c_enable); /* Teardown all current active bundles */ bundles_teardown(&device); /* Configure for bundle 0 */ hsc_bundle_t bundle_0; uint32_t bundle_id_0 = 0; hsc_dev_bundle(&device, bundle_id_0, &bundle_0); status |= bundle_config_0(&bundle_0); flag_wait_link_ready = false; if (flag_wait_link_ready) { /* Wait for the bundle to be ready, timeout = 2s */ status |= hsc_bundle_link_ready_wait(&bundle_0, 2000*1000) == true ? HSC_OK : HSC_ERROR; HSC_NOTE("\nhsc_bundle_link_ready_wait: %s\n", STATUS_2_STR(status)); } flag_show_link_status = true; if (flag_show_link_status) { hsc_bundle_status_show(&bundle_0); } if(status != HSC_OK) { HSC_NOTE("Example failed\n"); rc = EXIT_FAILURE; } //hsc_gui_close(); return rc; }
In the above Script I need to call retimer_106G_chester() function in the main in order to configure Datapath.
So I thought of combining all the Scripts into one Script where modes,Baudrate and signaling types will be passed has an argument.
the main advantage of the combined script is through I2C we can change the mode,Baudrate and signaling types whenever we want.
#include "hsc_api.h" #include <stdlib.h> #define STATUS_2_STR(status) status == HSC_OK ? "HSC_OK" : "HSC_ERROR" #define ARRAY_SIZE(array) ((uint8_t)(sizeof(array) / sizeof((array)[0]))) #define ARRAY_MASK(array,size) \ ({ \ int i, mask = 0; \ for (i = 0; i < size; i++) \ mask |= 1 << array[i]; \ mask; \ }) uint32_t host_chns_0[] = {0, 1, 2, 3, 4, 5, 6, 7}; uint32_t line_chns_0[] = {0, 1, 2, 3, 4, 5, 6, 7}; uint8_t num_host_chns_0 = ARRAY_SIZE(host_chns_0); uint8_t num_line_chns_0 = ARRAY_SIZE(line_chns_0); hsc_bundle_rules_t rules; /** * * The following example describes the sequence configuration of example datapath * * @param bundle [I] - The bundle being accessed. * * @return HSC_OK on success, HSC_ERROR on failure */ hsc_status_t bundle_config_0(hsc_bundle_t *bundle, e_hsc_operational_mode mode, e_hsc_baud_rate baud_rate,e_hsc_signal_mode signalling) { /* * Below is the bundle rules configuration * * Channel is activated in bundle: * - Host TX channel [0, 1, 2, 3, 4, 5, 6, 7] * - Host RX channel [0, 1, 2, 3, 4, 5, 6, 7] * - Line TX channel [0, 1, 2, 3, 4, 5, 6, 7] * - Line RX channel [0, 1, 2, 3, 4, 5, 6, 7] */ uint32_t chn_idx; hsc_status_t status = HSC_OK; hsc_dev_t *dev = hsc_bundle_dev_get(bundle); /* Default the bundle rules based on the desired application */ if (hsc_dev_bundle_rules(dev,mode, &rules) == NULL) { //HSC_CRIT("Failed construct the bundle rule\n"); return HSC_ERROR; } /* Setup the data rate on each channel */ hsc_bundle_rules_baud_rate_set(&rules, baud_rate); hsc_bundle_rules_ieee_demap_enable(&rules, false); if (mode == HSC_OPER_SHALLOW_HOST_LOOPBACK || mode == HSC_OPER_MODE_HOST_PRBS) { num_line_chns_0 = 0; } else if (mode == HSC_OPER_MODE_LINE_PRBS || mode == HSC_OPER_SHALLOW_LINE_LOOPBACK ) { num_host_chns_0 = 0; } else { num_host_chns_0 = ARRAY_SIZE(host_chns_0); num_line_chns_0 = ARRAY_SIZE(line_chns_0); } /* Use physical channels on the Line and host * The rules. Channel bitmask with an enable bit for each channel * to bind/associate with the bundle/bundle. */ /* Configure Host channel mask */ hsc_bundle_rules_chns_mask_set(&rules, HSC_INTF_HOST, ARRAY_MASK(host_chns_0,num_host_chns_0)); /* Configure Line channel mask */ hsc_bundle_rules_chns_mask_set(&rules, HSC_INTF_LINE, ARRAY_MASK(line_chns_0,num_line_chns_0)); /* Host have to operate in PAM/NRZ mode to get desired data rate per channel */ hsc_bundle_rules_signalling_set(&rules, HSC_INTF_HOST, signalling); /* Line have to operate in PAM/NRZ mode to get desired data rate per channel */ hsc_bundle_rules_signalling_set(&rules, HSC_INTF_LINE, signalling); /* Below is Host TX rules configuration information */ hsc_tx_rules_t *tx_rules = NULL; for (chn_idx = 0; chn_idx < num_host_chns_0; chn_idx++) { int16_t host_tx_taps[] = {-50, 650, 0, 0, 0, 0, 0}; /* Configure Host TX rules */ tx_rules = hsc_chn_tx_rules(&rules, host_chns_0[chn_idx], HSC_INTF_HTX); hsc_tx_rules_fir_taps_set(tx_rules, HSC_TX_LUT_3TAP, host_tx_taps); hsc_tx_rules_swing_set(tx_rules, HSC_TX_SWING_100p); hsc_tx_rules_eye_set(tx_rules, HSC_EYE_LEVEL_LOWER, 1000); hsc_tx_rules_eye_set(tx_rules, HSC_EYE_LEVEL_UPPER, 2000); hsc_tx_rules_gray_mapping_enable(tx_rules, true); hsc_tx_rules_dfe_precoder_enable(tx_rules, false); hsc_tx_rules_polarity_set(tx_rules, false); } /* Below is the line TX rules configuration information */ for (chn_idx = 0; chn_idx < num_line_chns_0; chn_idx++) { int16_t line_tx_taps[] ={-50, 650, 0, 0, 0, 0, 0}; /* Line TX rules */ tx_rules = hsc_chn_tx_rules(&rules, line_chns_0[chn_idx], HSC_INTF_LINE); hsc_tx_rules_fir_taps_set(tx_rules, HSC_TX_LUT_3TAP, line_tx_taps); hsc_tx_rules_swing_set(tx_rules, HSC_TX_SWING_100p); hsc_tx_rules_eye_set(tx_rules, HSC_EYE_LEVEL_LOWER, 1000); hsc_tx_rules_eye_set(tx_rules, HSC_EYE_LEVEL_UPPER, 2000); hsc_tx_rules_gray_mapping_enable(tx_rules, true); hsc_tx_rules_dfe_precoder_enable(tx_rules, false); hsc_tx_rules_polarity_set(tx_rules, false); } /* Below is the host RX rules configuration information */ hsc_rx_rules_t *rx_rules = NULL; hsc_rx_rules_advanced_t host_rx_adv_rules; for (chn_idx = 0; chn_idx < num_host_chns_0; chn_idx++) { /* Host RX rules */ rx_rules = hsc_chn_rx_rules(&rules, host_chns_0[chn_idx], HSC_INTF_HOST); hsc_rx_rules_dsp_mode_set(rx_rules, HSC_DSP_MODE_SLC1); hsc_rx_rules_autoctle_enable(rx_rules, true); hsc_rx_rules_gray_mapping_enable(rx_rules, true); hsc_rx_rules_polarity_set(rx_rules, false); hsc_rx_rules_advanced_set(rx_rules, &host_rx_adv_rules); hsc_rx_rules_vga_tracking_enable(rx_rules, false); hsc_rx_rules_dfe_precoder_enable(rx_rules, false); hsc_rx_rules_scdr_enable(rx_rules, false); hsc_rx_rules_advanced_get(rx_rules, &host_rx_adv_rules); host_rx_adv_rules.afe_trim = HSC_AFE_TRIM_AUTO; host_rx_adv_rules.mlsd_en = false; } /* Below is the line RX rules configuration information */ hsc_rx_rules_advanced_t line_rx_adv_rules; for (chn_idx = 0; chn_idx < num_line_chns_0; chn_idx++) { /* Line RX rules */ rx_rules = hsc_chn_rx_rules(&rules, line_chns_0[chn_idx], HSC_INTF_LINE); hsc_rx_rules_dsp_mode_set(rx_rules, HSC_DSP_MODE_SLC1); hsc_rx_rules_autoctle_enable(rx_rules, true); hsc_rx_rules_gray_mapping_enable(rx_rules, true); hsc_rx_rules_polarity_set(rx_rules, false); hsc_rx_rules_advanced_set(rx_rules, &line_rx_adv_rules); hsc_rx_rules_vga_tracking_enable(rx_rules, false); hsc_rx_rules_dfe_precoder_enable(rx_rules, false); hsc_rx_rules_scdr_enable(rx_rules, false); hsc_rx_rules_advanced_get(rx_rules, &line_rx_adv_rules); line_rx_adv_rules.afe_trim = HSC_AFE_TRIM_AUTO; line_rx_adv_rules.mlsd_en = false; } /* Initialize the bundle and tear down any resources that may * already be allocated.*/ status = hsc_bundle_init(bundle, &rules); //HSC_NOTE("hsc_bundle_init: %s\n", STATUS_2_STR(status)); /* Bring the bundle up */ status |= hsc_bundle_start(bundle, &rules); //HSC_NOTE("hsc_bundle_start: %s\n", STATUS_2_STR(status)); if (status != HSC_OK) { //HSC_NOTE("Configure bundle: %s\n", STATUS_2_STR(status)); return HSC_ERROR; } return status; } /** * This sample program a teardown all configuration of current bundles * @param dev [I] - The device being accessed. * * @return HSC_OK on success, HSC_ERROR on failure */ static hsc_status_t bundles_teardown(hsc_dev_t *dev,e_hsc_operational_mode mode) { hsc_status_t status = HSC_OK; uint32_t bundle_id = 0; uint32_t max_bundle_nums = hsc_dev_num_bundles(dev); if (hsc_dev_bundle_rules(dev,mode, &rules) == NULL) { //HSC_CRIT("Failed construct the bundle rule\n"); return HSC_ERROR; } /* Init all 16 bundles */ for (bundle_id = 0; bundle_id < max_bundle_nums; bundle_id++) { hsc_bundle_t bundle; hsc_dev_bundle(dev, bundle_id, &bundle); hsc_bundle_rules_chns_mask_set(&rules, HSC_INTF_HOST | HSC_INTF_LINE, 0); status |= hsc_bundle_init(&bundle, &rules); if (status != HSC_OK) { //HSC_WARN("hsc_bundle_init bundle %d: FAILED\n", bundle_id); } } return status; } /** * The following example describes the sequence configuration of PRBS generator * * @param dev [I] - The device being accessed * @param intf [I] - Interface to be configured * * @return HSC_OK on success, HSC_ERROR on failure */ static hsc_status_t prbs_generator_config_0(hsc_bundle_t *bundle, e_hsc_intf intf,e_hsc_operational_mode mode) { hsc_status_t status = HSC_OK; uint32_t chn_idx; hsc_prbs_gen_rules_t host_gen_rules; hsc_prbs_gen_rules_t line_gen_rules; hsc_dev_t *dev = hsc_bundle_dev_get(bundle); if (mode == HSC_OPER_MODE_HOST_PRBS) { num_line_chns_0 = 0; } else if (mode == HSC_OPER_MODE_LINE_PRBS ) { num_host_chns_0 = 0; } else { num_host_chns_0 = ARRAY_SIZE(host_chns_0); num_line_chns_0 = ARRAY_SIZE(line_chns_0); } if (mode == HSC_OPER_MODE_DUAL_PRBS || mode == HSC_OPER_MODE_HOST_PRBS) { /* Construct host generator rules */ if (hsc_dev_prbs_gen_rules(dev, &host_gen_rules) == NULL) { //HSC_CRIT("Failed construct the host prbs gen rule\n"); return HSC_ERROR; } } if (mode == HSC_OPER_MODE_DUAL_PRBS || mode == HSC_OPER_MODE_LINE_PRBS) { /* Construct line generator rules */ if (hsc_dev_prbs_gen_rules(dev, &line_gen_rules) == NULL) { //HSC_CRIT("Failed construct the line prbs gen rule\n"); return HSC_ERROR; } } if (mode == HSC_OPER_MODE_DUAL_PRBS || mode == HSC_OPER_MODE_HOST_PRBS) { /* Below is Host PRBS generator rules configuration * Configure Host PRBS generator rules mode */ hsc_prbs_gen_rules_mode_set(&host_gen_rules, HSC_PRBS_MODE_COMBINED); /* Configure Host PRBS generator rules pattern */ hsc_prbs_gen_rules_pattern_set(&host_gen_rules, HSC_PRBS_PAT_PRBS31); /* Enable Host PRBS rules generator */ hsc_prbs_gen_rules_enable(&host_gen_rules, true); } if (mode == HSC_OPER_MODE_DUAL_PRBS || mode == HSC_OPER_MODE_LINE_PRBS) { /* Below is Line PRBS generator rules configuration * Configure Line PRBS generator rules mode */ hsc_prbs_gen_rules_mode_set(&line_gen_rules, HSC_PRBS_MODE_COMBINED); /* Configure Line PRBS generator rules pattern */ hsc_prbs_gen_rules_pattern_set(&line_gen_rules, HSC_PRBS_PAT_PRBS31); /* Enable Line PRBS rules generator */ hsc_prbs_gen_rules_enable(&line_gen_rules, true); } /* Setup the Host and Line PRBS generator */ hsc_prbs_t hsc_prbs; /* Apply the Host TX generator rule configuration */ if (intf & HSC_INTF_HTX) { for (chn_idx = 0; chn_idx < num_host_chns_0 ; chn_idx++) { /* Construct PRBS */ hsc_dev_prbs(dev, host_chns_0[chn_idx], HSC_INTF_HTX, &hsc_prbs); /* Apply the Host TX generator rule configuration to desired prbs*/ status |= hsc_prbs_gen_rules_apply(&hsc_prbs, &host_gen_rules); if (status != HSC_OK) { //HSC_WARN("Can not enable generator at channel %d htx intf\n", host_chns_0[chn_idx]); } } } /* Apply the Line TX generator rule configuration */ if (intf & HSC_INTF_LTX) { for (chn_idx = 0; chn_idx < num_line_chns_0; chn_idx++) { /* Construct PRBS */ hsc_dev_prbs(dev, line_chns_0[chn_idx], HSC_INTF_LTX, &hsc_prbs); /* Apply the Line TX generator rule configuration to desired prbs*/ status |= hsc_prbs_gen_rules_apply(&hsc_prbs, &line_gen_rules); if (status != HSC_OK) { //HSC_WARN("Can not enable generator at channel %d htx intf\n", line_chns_0[chn_idx]); } } } return status; } /** * The following example describes the sequence configuration of PRBS checker * * @param dev [I] - The device being accessed * @param intf [I] - Interface to be configured * * @return HSC_OK on success, HSC_ERROR on failure */ static hsc_status_t prbs_checker_config_0(hsc_bundle_t *bundle, e_hsc_intf intf,e_hsc_operational_mode mode) { hsc_status_t status = HSC_OK; hsc_prbs_chk_status_t prbs_status = {0}; hsc_prbs_chk_rules_t host_chk_rules; hsc_prbs_chk_rules_t line_chk_rules; uint32_t chn_idx; hsc_dev_t *dev = hsc_bundle_dev_get(bundle); if (mode == HSC_OPER_MODE_DUAL_PRBS || mode == HSC_OPER_MODE_HOST_PRBS) { /* Construct Host checker rules */ if (hsc_dev_prbs_chk_rules(dev, &host_chk_rules) == NULL) { //HSC_CRIT("Failed construct the host PRBS checker rule\n"); return HSC_ERROR; } } if (mode == HSC_OPER_MODE_DUAL_PRBS || mode == HSC_OPER_MODE_LINE_PRBS) { /* Construct Line checker rules */ if (hsc_dev_prbs_chk_rules(dev, &line_chk_rules) == NULL) { //HSC_CRIT("Failed construct the line PRBS checker rule\n"); return HSC_ERROR; } } if (mode == HSC_OPER_MODE_DUAL_PRBS || mode == HSC_OPER_MODE_HOST_PRBS) { /* * Below is Host PRBS checker rules configuration */ /* Configure Host PRBS checker rules mode */ hsc_prbs_chk_rules_mode_set(&host_chk_rules, HSC_PRBS_MODE_MSB_LSB); /* Configure Host PRBS checker rules pattern */ hsc_prbs_chk_rules_pattern_set(&host_chk_rules, HSC_PRBS_PAT_PRBS31); /* Configure line PRBS checker rules pattern lsb */ hsc_prbs_chk_rules_pattern_lsb_set(&host_chk_rules, HSC_PRBS_PAT_PRBS31); /* Enable Host PRBS checker */ hsc_prbs_chk_rules_enable(&host_chk_rules, true); } if (mode == HSC_OPER_MODE_DUAL_PRBS || mode == HSC_OPER_MODE_LINE_PRBS) { /* * Below is Line PRBS checker rules configuration */ /* Configure Line PRBS checker rules mode */ hsc_prbs_chk_rules_mode_set(&line_chk_rules, HSC_PRBS_MODE_MSB_LSB); /* Configure Line PRBS checker rules pattern */ hsc_prbs_chk_rules_pattern_set(&line_chk_rules, HSC_PRBS_PAT_PRBS31); /* Configure Line PRBS checker rules pattern lsb */ hsc_prbs_chk_rules_pattern_lsb_set(&line_chk_rules, HSC_PRBS_PAT_PRBS31); /* Enable Line PRBS checker */ hsc_prbs_chk_rules_enable(&line_chk_rules, true); } /* Apply the PRBS checker */ hsc_prbs_t hsc_prbs; if (intf & HSC_INTF_HRX) { for (chn_idx = 0; chn_idx < num_host_chns_0; chn_idx++) { /* Construct PRBS */ hsc_dev_prbs(dev, host_chns_0[chn_idx], HSC_INTF_HRX, &hsc_prbs); /* Apply the Host RX checker rule configuration to desired prbs*/ status |= hsc_prbs_chk_rules_apply(&hsc_prbs, &host_chk_rules); if (status != HSC_OK) { //HSC_WARN("Can not enable checker at channel %d hrx intf\n", host_chns_0[chn_idx]); } /* Clear the initial counters */ hsc_prbs_chk_status_query(&hsc_prbs, &prbs_status); } } if (intf & HSC_INTF_LRX) { for (chn_idx = 0; chn_idx < num_line_chns_0; chn_idx++) { /* Construct PRBS */ hsc_dev_prbs(dev, line_chns_0[chn_idx], HSC_INTF_LRX, &hsc_prbs); /* Apply the Line RX checker rule configuration to desired prbs*/ status |= hsc_prbs_chk_rules_apply(&hsc_prbs, &line_chk_rules); if (status != HSC_OK) { //HSC_WARN("Can not enable checker at channel %d lrx intf\n", line_chns_0[chn_idx]); } /* Clear the initial counters */ hsc_prbs_chk_status_query(&hsc_prbs, &prbs_status); } } return status; } /** * * The following example describes the way to query PRBS status from ASIC then * print detail information * * @param dev [I] - The device being accessed * @param intf [I] - Interface to be configured * * @return HSC_OK on success, HSC_ERROR on failure */ static hsc_status_t prbs_query_status_0(hsc_bundle_t *bundle, e_hsc_intf intf) { uint32_t chn_idx; hsc_status_t status = HSC_OK; hsc_prbs_chk_status_t prbs_status = {0}; hsc_prbs_t hsc_prbs; hsc_dev_t *dev = hsc_bundle_dev_get(bundle); if (intf & HSC_INTF_HRX) { for (chn_idx = 0; chn_idx < num_host_chns_0; chn_idx++) { /* Construct PRBS */ hsc_dev_prbs(dev, host_chns_0[chn_idx], HSC_INTF_HRX, &hsc_prbs); /* Query the Host RX checker rule configuration of desired prbs*/ HSC_NOTE("\nPrbs status for channel %x\n", host_chns_0[chn_idx]); status |= hsc_prbs_chk_status_query(&hsc_prbs, &prbs_status); if (status != HSC_OK) { HSC_WARN("hsc_dev_prbs_chk_status_query fail at channel %d HRX intf \n", host_chns_0[chn_idx]); } HSC_NOTE(" HRX intf\n"); HSC_NOTE(" Defects:\n"); HSC_NOTE(" Locked: %s\n", prbs_status.prbs_lock ? "yes" : "no"); HSC_NOTE(" Counters:\n"); HSC_NOTE(" - rx bits err : %x\n", prbs_status.prbs_error_bit_count); HSC_NOTE(" - rx bits err(LSB): %x\n", prbs_status.prbs_error_bit_count_lsb); } } if (intf & HSC_INTF_LRX) { for (chn_idx = 0; chn_idx < num_line_chns_0; chn_idx++) { /* Construct PRBS */ hsc_dev_prbs(dev, line_chns_0[chn_idx], HSC_INTF_LRX, &hsc_prbs); HSC_NOTE("\nPrbs status for channel %x\n", line_chns_0[chn_idx]); /* Query the Line RX checker rule configuration of desired prbs*/ status |= hsc_prbs_chk_status_query(&hsc_prbs, &prbs_status); if (status != HSC_OK) { HSC_WARN("hsc_dev_prbs_chk_status_query fail at channel %d LRX intf \n", line_chns_0[chn_idx]); } HSC_NOTE(" Prbs LRX intf\n"); HSC_NOTE(" Defects:\n"); HSC_NOTE(" Locked: %s\n", prbs_status.prbs_lock ? "yes" : "no"); HSC_NOTE(" Counters:\n"); HSC_NOTE(" - rx bits err : %x\n", prbs_status.prbs_error_bit_count); HSC_NOTE(" - rx bits err(LSB): %x\n", prbs_status.prbs_error_bit_count_lsb); } } return status; } /** * The following example demonstrates configuring PRBS for bundle 0. * * @param dev [I] - The device being accessed * * @return HSC_OK on success, HSC_ERROR on failure */ hsc_status_t prbs_gen_config_0(hsc_bundle_t *bundle,e_hsc_operational_mode mode) { hsc_status_t status = HSC_OK; /* PRBS generator for Host side */ status |= prbs_generator_config_0(bundle, HSC_INTF_HTX,mode); /* PRBS generator for Line side */ status |= prbs_generator_config_0(bundle, HSC_INTF_LTX,mode); return status; } hsc_status_t prbs_chk_config_and_status_show_0(hsc_bundle_t *bundle,e_hsc_operational_mode mode) { hsc_status_t status = HSC_OK; /* PRBS checker for host side */ status |= prbs_checker_config_0(bundle, HSC_INTF_HRX,mode); /* PRBS checker for line side */ status |= prbs_checker_config_0(bundle, HSC_INTF_LRX,mode); /* PRBS query status for host side */ status |= prbs_query_status_0(bundle, HSC_INTF_HRX); /* PRBS query status for line side */ status |= prbs_query_status_0(bundle, HSC_INTF_LRX); return status; } /** * This is the main wrapper method for the example. * * @param argc [I] - The number of input arguments in argv[] * @param argv [I] - The array of input arguments * * @return The return code to the OS (0 == success, anything else for failure) */ int Datapath_config(e_hsc_operational_mode mode, e_hsc_baud_rate baud_rate, e_hsc_signal_mode signalling) { int rc = EXIT_SUCCESS; hsc_status_t status = HSC_OK; bool flag_wait_link_ready = false; bool flag_show_link_status = false; bool flag_i2c_enable = true; /* Device handle */ static hsc_dev_t device; /* Connect back to the GUI for register access */ //hsc_gui_connect(argc, argv); /* Construct */ if (hsc_dev(&device, 0 /* asic_id */) == NULL) { //hsc_gui_close(); return EXIT_FAILURE; } hsc_dev_i2c_access_enable(&device, flag_i2c_enable); /* Teardown all current active bundles */ bundles_teardown(&device,mode); /* Configure for bundle 0 */ hsc_bundle_t bundle_0; uint32_t bundle_id_0 = 0; hsc_dev_bundle(&device, bundle_id_0, &bundle_0); status |= bundle_config_0(&bundle_0,mode,baud_rate,signalling); if (mode == HSC_OPER_MODE_DUAL_PRBS || mode == HSC_OPER_MODE_HOST_PRBS || mode == HSC_OPER_MODE_LINE_PRBS ) { /* Turn on PRBS generator */ status |= prbs_gen_config_0(&bundle_0,mode); } flag_wait_link_ready = false; if (flag_wait_link_ready) { /* Wait for the bundle to be ready, timeout = 2s */ status |= hsc_bundle_link_ready_wait(&bundle_0, 2000*1000) == true ? HSC_OK : HSC_ERROR; //HSC_NOTE("\nhsc_bundle_link_ready_wait: %s\n", STATUS_2_STR(status)); } if (mode == HSC_OPER_MODE_DUAL_PRBS || mode == HSC_OPER_MODE_HOST_PRBS || mode == HSC_OPER_MODE_LINE_PRBS ) { /* Turn on PRBS checker and show status */ status |= prbs_chk_config_and_status_show_0(&bundle_0,mode); } flag_show_link_status = false; if (flag_show_link_status) { hsc_bundle_status_show(&bundle_0); } if(status != HSC_OK) { //HSC_NOTE("Example failed\n"); rc = EXIT_FAILURE; } //hsc_gui_close(); return rc; }
In the above Script I need to call Datapath_config function in the main in order to configure Datapath.
The modes ,Baudrates and signaling is declared has on Enums so I have declared enum variables respectively.
typedef enum { /** PAM signalling mode */ HSC_SIGNAL_MODE_PAM = 0, /** NRZ signalling mode */ HSC_SIGNAL_MODE_NRZ = 1, /** Invalid signalling mode */ HSC_SIGNAL_MODE_UNKNOWN = 2 } e_hsc_signal_mode; so on /* enum variables */ e_hsc_operational_mode dsp_op_mode ; e_hsc_signal_mode dsp_signal_type ; e_hsc_baud_rate dsp_data_rate ;
Here is my observation while debugging the code,
Case 1:
When we run the single C Script with entire I2C_IRQ_handler function it will configure datapath and other functions also works.
Case 2:
When we run the Combined Script without I2C_IRQ_handler function it will configure datapath and some I2C functionality will work in polling mode but not efficient.
Case 3:
When we run the Combined Script with I2C_IRQ_handler function it crashes and will get above hardfault error.