motor-control-sdk/source/position_sense/bissc/driver/bissc_drv.c
Dhaval Khandla c5bc321959 am243x: bissc: Refactor the code
- Align to coding guidelines
- Remove am243x-evm examples

Fixes: PINDSW-5479

Signed-off-by: Dhaval Khandla <dhavaljk@ti.com>
2023-12-14 18:06:44 +05:30

564 lines
22 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* Copyright (C) 2023 Texas Instruments Incorporated
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <position_sense/bissc/include/bissc_drv.h>
#include <kernel/dpl/ClockP.h>
#include <drivers/hw_include/tistdtypes.h>
#include <drivers/hw_include/hw_types.h>
static struct bissc_priv bissc_priv;
void bissc_command_send(struct bissc_priv *priv)
{
struct bissc_pruicss_xchg *pruicss_xchg = priv->pruicss_xchg;
if(priv->load_share)
{
pruicss_xchg->cycle_trigger[0] = (pruicss_xchg->channel & 0x1)?0x1:0;
pruicss_xchg->cycle_trigger[1] = (pruicss_xchg->channel & 0x2)?0x1:0;
pruicss_xchg->cycle_trigger[2] = (pruicss_xchg->channel & 0x4)?0x1:0;
}
else
{
pruicss_xchg->cycle_trigger[0] = 0x1;
}
}
int32_t bissc_command_wait(struct bissc_priv *priv)
{
struct bissc_pruicss_xchg *pruicss_xchg = priv->pruicss_xchg;
uint32_t timeout;
/* Minimum and Maximum BiSSC cycle time depends on various params as below:
TCycle_min = TMA (5 + DLEN + CRCLEN) + tLineDelay + tbusy_max + busy_s_max + tTO
Instead wait for max of 5 ms as this can vary for different encoders and for daisy chain
*/
timeout = BISSC_MAX_CYCLE_TIMEOUT;
while(1)
{
if(priv->load_share)
{
if((pruicss_xchg->cycle_trigger[0] == 0 ) && (pruicss_xchg->cycle_trigger[1] == 0) && (pruicss_xchg->cycle_trigger[2] == 0))
{
break;
}
}
else if(pruicss_xchg->cycle_trigger[0] == 0)
{
break;
}
ClockP_usleep(1000);
timeout--;
if(timeout == 0)
{
return SystemP_FAILURE;
}
}
return SystemP_SUCCESS;
}
int32_t bissc_command_process(struct bissc_priv *priv)
{
int32_t ret = SystemP_FAILURE;
bissc_command_send(priv);
ret = bissc_command_wait(priv);
return ret;
}
void bissc_enable_load_share_mode(struct bissc_priv *priv)
{
void *pruss_cfg = priv->pruicss_cfg;
uint32_t rgval;
if(priv->pruicss_slicex)
{
rgval = HW_RD_REG32((uint8_t *)pruss_cfg + CSL_ICSSCFG_EDPRU1TXCFGREGISTER);
rgval |= CSL_ICSSCFG_EDPRU1TXCFGREGISTER_PRU1_ENDAT_SHARE_EN_MASK;
HW_WR_REG32((uint8_t *)pruss_cfg + CSL_ICSSCFG_EDPRU1TXCFGREGISTER, rgval);
}
else
{
rgval = HW_RD_REG32((uint8_t *)pruss_cfg + CSL_ICSSCFG_EDPRU0TXCFGREGISTER);
rgval |= CSL_ICSSCFG_EDPRU0TXCFGREGISTER_PRU0_ENDAT_SHARE_EN_MASK;
HW_WR_REG32((uint8_t *)pruss_cfg + CSL_ICSSCFG_EDPRU0TXCFGREGISTER, rgval);
}
}
void bissc_config_primary_core_mask(struct bissc_priv *priv, uint8_t mask)
{
switch (mask)
{
case 1: /*only channel0 connected*/
priv->pruicss_xchg->primary_core_mask=0x1;
break;
case 2: /*channel1 connected*/
priv->pruicss_xchg->primary_core_mask=0x2;
break;
case 3: /*channel0 and channel1 connected*/
priv->pruicss_xchg->primary_core_mask=0x1;
break;
case 4: /*channel2 connected*/
priv->pruicss_xchg->primary_core_mask=0x4;
break;
case 5: /*channel0 and channel2 connnected*/
priv->pruicss_xchg->primary_core_mask=0x4;
break;
case 6: /*channel1 and channel2 connected*/
priv->pruicss_xchg->primary_core_mask=0X4;
break;
case 7: /*all three channel connected*/
priv->pruicss_xchg->primary_core_mask=0x4;
break;
}
}
int32_t bissc_get_pos(struct bissc_priv *priv)
{
uint32_t raw_data0, raw_data1, shift, sl_num, max, ch_num, numencoders, ls_ch;
int32_t ch = 0;
if(bissc_command_process(priv) < 0)
{
return SystemP_FAILURE;
}
for(ch_num = 0; ch_num < priv->totalchannels; ch_num++)
{
ch = priv->channel[ch_num];
if(priv->load_share)
{
numencoders = priv->num_encoders[ch];
ls_ch = ch;
}
else
{
numencoders = priv->num_encoders[0];
ls_ch = 0;
}
for(sl_num = 0; sl_num < numencoders; sl_num++)
{
raw_data0 = priv->pruicss_xchg->pos_data_res[sl_num].raw_data[ch].pos_data_word0;
raw_data1 = priv->pruicss_xchg->pos_data_res[sl_num].raw_data[ch].pos_data_word1;
max = pow(2, priv->single_turn_len[ls_ch][sl_num]);
if((priv->data_len[ls_ch][sl_num] + BISSC_POS_CRC_LEN + BISSC_EW_LEN) <= 32)
{
priv->raw_data = (uint64_t) raw_data0;
priv->enc_pos_data[ch].position[sl_num] = (uint64_t) (raw_data0 >> (BISSC_POS_CRC_LEN + BISSC_EW_LEN));
priv->enc_pos_data[ch].ew[sl_num] = ((raw_data0 >> (BISSC_POS_CRC_LEN )) & 0x03);
priv->enc_pos_data[ch].num_of_turns[sl_num] = priv->enc_pos_data[ch].position[sl_num] >> priv->single_turn_len[ls_ch][sl_num];
priv->enc_pos_data[ch].angle[sl_num] = (float)(priv->enc_pos_data[ch].position[sl_num] & (max - 1)) / max * (float)360;
priv->enc_pos_data[ch].rcv_crc[sl_num] = raw_data0 & 0x3F;
priv->enc_pos_data[ch].otf_crc[sl_num] = priv->pruicss_xchg->pos_data_res[sl_num].pos_data_otf_crc[ch];
priv->pd_crc_err_cnt[ch][sl_num] = priv->pruicss_xchg->pos_data_res[sl_num].pd_crc_err_cnt[ch];
}
else
{
shift = ((priv->data_len[ls_ch][sl_num] + BISSC_POS_CRC_LEN + BISSC_EW_LEN) - 32);
priv->raw_data = (uint64_t) raw_data0 << shift | raw_data1;
priv->enc_pos_data[ch].position[sl_num] = (uint64_t) (priv->raw_data >> (BISSC_POS_CRC_LEN + BISSC_EW_LEN));
priv->enc_pos_data[ch].ew[sl_num] = ((priv->raw_data >> (BISSC_POS_CRC_LEN )) & 0x03);
priv->enc_pos_data[ch].num_of_turns[sl_num] = priv->enc_pos_data[ch].position[sl_num] >> priv->single_turn_len[ls_ch][sl_num];
priv->enc_pos_data[ch].angle[sl_num] = (float)(priv->enc_pos_data[ch].position[sl_num] & (max - 1)) / max * (float)360;
priv->enc_pos_data[ch].rcv_crc[sl_num] = priv->raw_data & 0x3F;
priv->enc_pos_data[ch].otf_crc[sl_num] = priv->pruicss_xchg->pos_data_res[sl_num].pos_data_otf_crc[ch];
priv->pd_crc_err_cnt[ch][sl_num] = priv->pruicss_xchg->pos_data_res[sl_num].pd_crc_err_cnt[ch];
}
}
}
return SystemP_SUCCESS;
}
void bissc_config_clock(struct bissc_priv *priv,
struct bissc_clk_cfg *clk_cfg)
{
void *pruicss_cfg = priv->pruicss_cfg;
struct bissc_pruicss_xchg *pruicss_xchg = priv->pruicss_xchg;
/* Set PRU1_ED_RX_SB_POL polarity bit to 0 for bissc, required for ICSSG (don't care for ICSSM) */
if(priv->pruicss_slicex)
{
HW_WR_REG32((uint8_t *)pruicss_cfg + CSL_ICSSCFG_EDPRU1RXCFGREGISTER, ((clk_cfg->rx_div << 16) |
(clk_cfg->is_core_clk << 4) | (clk_cfg->rx_div_attr)));
HW_WR_REG32((uint8_t *)pruicss_cfg + CSL_ICSSCFG_EDPRU1TXCFGREGISTER, clk_cfg->tx_div << 16 |
(clk_cfg->is_core_clk << 4));
}
else
{
HW_WR_REG32((uint8_t *)pruicss_cfg + CSL_ICSSCFG_EDPRU0RXCFGREGISTER, ((clk_cfg->rx_div << 16) |
(clk_cfg->is_core_clk << 4) | (clk_cfg->rx_div_attr)));
HW_WR_REG32((uint8_t *)pruicss_cfg + CSL_ICSSCFG_EDPRU0TXCFGREGISTER, clk_cfg->tx_div << 16 |
(clk_cfg->is_core_clk << 4));
}
if(priv->load_share)
bissc_enable_load_share_mode(priv);
/* Clock configuration has changed - Indicate fw to measure the delay again */
pruicss_xchg->measure_proc_delay = 1;
}
void bissc_config_channel(struct bissc_priv *priv, int32_t mask, int32_t totalch)
{
struct bissc_pruicss_xchg *pruicss_xchg = priv->pruicss_xchg;
int32_t ch_num;
pruicss_xchg->channel = mask;
priv->totalchannels = totalch;
/* Below for loop iterates for enabled channel number of times.
Updates channel in this manner:
if ch0 only selected --> priv->channel[0] = 0;
if ch1 only selected --> priv->channel[0] = 1;
if ch2 only selected --> priv->channel[0] = 2;
if ch0 & ch1 are selected --> priv->channel[0] = 0, priv->channel[1] = 1;
if ch0 & ch2 are selected --> priv->channel[0] = 0, priv->channel[1] = 2;
if ch1 & ch2 are selected --> priv->channel[0] = 1, priv->channel[1] = 2;
if ch0, ch1 & ch2 are selected --> priv->channel[0] = 0, priv->channel[1] = 1, priv->channel[1] = 2;
*/
for(ch_num = 0; ch_num < totalch; ch_num++)
{
if((mask & 1) && ch_num == 0)
priv->channel[ch_num] = 0;
else if((mask & 2) && (ch_num == 0 || ch_num == 1))
priv->channel[ch_num] = 1;
else if((mask & 4))
priv->channel[ch_num] = 2;
}
}
void bissc_config_load_share(struct bissc_priv *priv, int32_t mask)
{
priv->load_share = 1; /*Enable load-share*/
bissc_config_primary_core_mask(priv, mask);
bissc_enable_load_share_mode(priv);
}
int32_t bissc_wait_for_fw_initialization(struct bissc_priv *priv, uint32_t timeout, uint8_t mask)
{
int32_t i;
struct bissc_pruicss_xchg *pruicss_xchg = priv->pruicss_xchg;
for(i = 0; i < timeout; i++)
{
if(priv->load_share) /* for loadshare mode*/
{
switch (mask) {
case 1: /*channel 0 connected*/
if((pruicss_xchg->status[0] & 1))
return SystemP_SUCCESS;
break;
case 2: /*channel 1 connected*/
if((pruicss_xchg->status[1] & 1))
return SystemP_SUCCESS;
break;
case 3: /*channel 0 and 1 connected*/
if((pruicss_xchg->status[0] & 1) && (pruicss_xchg->status[1] & 1))
return SystemP_SUCCESS;
break;
case 4: /*channel 2 connected*/
if((pruicss_xchg->status[2] & 1))
return SystemP_SUCCESS;
break;
case 5: /*channel 0 and 2 connnected*/
if((pruicss_xchg->status[0] & 1) && (pruicss_xchg->status[2] & 1))
return SystemP_SUCCESS;
break;
case 6: /*channel 1 and 2 connected*/
if((pruicss_xchg->status[1] & 1) && (pruicss_xchg->status[2] & 1))
return SystemP_SUCCESS;
break;
case 7: /*all three channel connected*/
if((pruicss_xchg->status[0] & 1) && (pruicss_xchg->status[1] & 1) && ( pruicss_xchg->status[2] & 1))
return SystemP_SUCCESS;
break;
}
ClockP_usleep(1000 * 1);
}
else if(pruicss_xchg->status[0] & 1)
{
break;
}
else
{
ClockP_usleep(1000 * 1);
}
}
if(i == timeout)
{
return SystemP_FAILURE;
}
return SystemP_SUCCESS;
}
void bissc_get_enc_proc_delay(struct bissc_priv *priv)
{
int32_t i;
struct bissc_pruicss_xchg *pruicss_xchg = priv->pruicss_xchg;
for(i = 0; i < NUM_ED_CH_MAX; i++)
{
priv->proc_delay[i] = pruicss_xchg->proc_delay[i];
}
}
void bissc_config_clr_cfg0(struct bissc_priv *priv)
{
void *pruicss_cfg = priv->pruicss_cfg;
if(priv->pruicss_slicex)
{
HW_WR_REG32((uint8_t *)pruicss_cfg + CSL_ICSSCFG_EDPRU1CH0CFG0REGISTER, 0);
HW_WR_REG32((uint8_t *)pruicss_cfg + CSL_ICSSCFG_EDPRU1CH1CFG0REGISTER, 0);
HW_WR_REG32((uint8_t *)pruicss_cfg + CSL_ICSSCFG_EDPRU1CH2CFG0REGISTER, 0);
}
else
{
HW_WR_REG32((uint8_t *)pruicss_cfg + CSL_ICSSCFG_EDPRU0CH0CFG0REGISTER, 0);
HW_WR_REG32((uint8_t *)pruicss_cfg + CSL_ICSSCFG_EDPRU0CH1CFG0REGISTER, 0);
HW_WR_REG32((uint8_t *)pruicss_cfg + CSL_ICSSCFG_EDPRU0CH2CFG0REGISTER, 0);
}
}
void bissc_config_endat_mode(struct bissc_priv *priv)
{
void *pruicss_cfg = priv->pruicss_cfg;
if(priv->pruicss_slicex)
{
HW_WR_REG8((uint8_t *)pruicss_cfg + CSL_ICSSCFG_GPCFG1 + 3, 4);
}
else
{
HW_WR_REG8((uint8_t *)pruicss_cfg + CSL_ICSSCFG_GPCFG0 + 3, 4);
}
}
int32_t bissc_calc_clock(struct bissc_priv *priv, struct bissc_clk_cfg *clk_cfg)
{
uint32_t freq = priv->baud_rate;
clk_cfg->rx_div_attr = BISSC_RX_SAMPLE_SIZE;
if((freq == BISSC_FREQ_1MHZ) || (freq == BISSC_FREQ_5MHZ))
{
freq = freq * 1000 * 1000;
clk_cfg->tx_div = (priv->core_clk_freq / freq) - 1;
clk_cfg->rx_div = (priv->core_clk_freq / (freq * 8)) - 1;
clk_cfg->is_core_clk = 1;
}
else if((freq == BISSC_FREQ_2MHZ) || (freq == BISSC_FREQ_8MHZ))
{
freq = freq * 1000 * 1000;
clk_cfg->tx_div = (priv->uart_clk_freq / freq) - 1;
clk_cfg->rx_div = (priv->uart_clk_freq / (freq * 8)) - 1;
clk_cfg->is_core_clk = 0;
}
else if(freq == BISSC_FREQ_10MHZ)
{
freq = freq* 1000 * 1000;
clk_cfg->tx_div = (priv->core_clk_freq / freq) - 1;
clk_cfg->rx_div = (priv->core_clk_freq / (freq * 4)) - 1;
clk_cfg->is_core_clk = 1;
clk_cfg->rx_div_attr = BISSC_RX_SAMPLE_SIZE_10MHZ;
}
else
{
return SystemP_FAILURE;
}
return SystemP_SUCCESS;
}
void bissc_hw_init(struct bissc_priv *priv)
{
struct bissc_clk_cfg clk_cfg;
bissc_calc_clock(priv, &clk_cfg);
bissc_config_endat_mode(priv);
bissc_config_clock(priv, &clk_cfg);
bissc_config_clr_cfg0(priv);
}
struct bissc_priv *bissc_init(PRUICSS_Handle gPruIcssXHandle,
int32_t slice,
uint32_t frequency,
uint32_t core_clk_freq,
uint32_t uart_clk_freq)
{
struct bissc_pruicss_xchg *pruicss_xchg;
void *pruicss_cfg;
pruicss_cfg = (void *)(((PRUICSS_HwAttrs *)(gPruIcssXHandle->hwAttrs))->cfgRegBase);
if(slice)
pruicss_xchg = (struct bissc_pruicss_xchg *)((PRUICSS_HwAttrs *)(gPruIcssXHandle->hwAttrs))->pru1DramBase;
else
pruicss_xchg = (struct bissc_pruicss_xchg *)((PRUICSS_HwAttrs *)(gPruIcssXHandle->hwAttrs))->pru0DramBase;
bissc_priv.pruicss_xchg = pruicss_xchg;
bissc_priv.pruicss_cfg = pruicss_cfg;
bissc_priv.pruicss_slicex = slice;
bissc_priv.baud_rate = frequency;
bissc_priv.core_clk_freq = core_clk_freq;
bissc_priv.uart_clk_freq = uart_clk_freq;
bissc_hw_init(&bissc_priv);
return &bissc_priv;
}
void bissc_update_max_proc_delay(struct bissc_priv *priv)
{
struct bissc_pruicss_xchg *pruicss_xchg = priv->pruicss_xchg;
pruicss_xchg->fifo_bit_idx = 4; /* 8x over clock - middle bit*/
if(priv->baud_rate == BISSC_FREQ_1MHZ)
pruicss_xchg->max_proc_delay = BISSC_MAX_PROC_DELAY_1MHZ;
else if(priv->baud_rate == BISSC_FREQ_2MHZ)
pruicss_xchg->max_proc_delay = BISSC_MAX_PROC_DELAY_2MHZ;
else if(priv->baud_rate == BISSC_FREQ_5MHZ)
pruicss_xchg->max_proc_delay = BISSC_MAX_PROC_DELAY_5MHZ;
else if(priv->baud_rate == BISSC_FREQ_8MHZ)
pruicss_xchg->max_proc_delay = BISSC_MAX_PROC_DELAY_8MHZ;
else if(priv->baud_rate == BISSC_FREQ_10MHZ)
{
pruicss_xchg->max_proc_delay = BISSC_MAX_PROC_DELAY_10MHZ;
pruicss_xchg->fifo_bit_idx = 2; /* 4x over clock - middle bit*/
}
}
int32_t bissc_wait_measure_proc_delay(struct bissc_priv *priv, uint32_t timeout)
{
int32_t i;
struct bissc_pruicss_xchg *pruicss_xchg = priv->pruicss_xchg;
for(i = 0; i < timeout; i++)
{
if(pruicss_xchg->measure_proc_delay & 1)
{
break;
}
else
{
ClockP_usleep(1000);
}
}
if(i == timeout)
{
return SystemP_FAILURE;
}
return SystemP_SUCCESS;
}
void bissc_set_default_initialization(struct bissc_priv *priv, uint64_t icssgclk)
{
int8_t pru_num, totalprus, ls_ch;
struct bissc_pruicss_xchg *pruicss_xchg = priv->pruicss_xchg;
/* Initialize parameters to default values */
if(priv->load_share)
totalprus = priv->totalchannels;
else
totalprus = 1;
for( pru_num = 0; pru_num < totalprus; pru_num++)
{
if(priv->load_share)
ls_ch = priv->channel[pru_num];
else
ls_ch = 0;
pruicss_xchg->enc_len[ls_ch].data_len[0] = BISSC_POS_DATA_LEN_DEFAULT;
priv->data_len[ls_ch][0] = BISSC_POS_DATA_LEN_DEFAULT;
priv->single_turn_len[ls_ch][0] = BISSC_POS_DATA_LEN_DEFAULT;
pruicss_xchg->enc_len[ls_ch].num_encoders = 1;
priv->num_encoders[ls_ch] = 1;
priv->multi_turn_len[ls_ch][0] = 0;
pruicss_xchg->ctrl_cmd[ls_ch] = 0;
}
pruicss_xchg->pos_crc_len = BISSC_POS_CRC_LEN;
pruicss_xchg->ctrl_cmd_crc_len = BISSC_CTRL_CMD_CRC_LEN;
pruicss_xchg->rx_clk_freq = priv->baud_rate;
bissc_update_max_proc_delay(priv);
pruicss_xchg->delay_40us = ((icssgclk*40)/1000000);
pruicss_xchg->delay_100ms = (icssgclk / 10); /*((icssgclk*100000) / 1000000)*/
pruicss_xchg->icssg_clk = icssgclk;
pruicss_xchg->valid_bit_idx = 24;
pruicss_xchg->measure_proc_delay = 1;
pruicss_xchg->execution_state[0] = 0;
pruicss_xchg->execution_state[1] = 0;
pruicss_xchg->execution_state[2] = 0;
}
void bissc_update_data_len(struct bissc_priv *priv, uint32_t single_turn_len[], uint32_t multi_turn_len[], int32_t pru_num)
{
struct bissc_pruicss_xchg *pruicss_xchg = priv->pruicss_xchg;
uint32_t sl_num, ls_ch;
if(priv->load_share)
ls_ch = priv->channel[pru_num];
else
ls_ch = 0;
for( sl_num = 0; sl_num < NUM_ENCODERS_MAX; sl_num++)
{
if(single_turn_len[sl_num])
{
priv->single_turn_len[ls_ch][sl_num] = single_turn_len[sl_num];
priv->multi_turn_len[ls_ch][sl_num] = multi_turn_len[sl_num];
priv->data_len[ls_ch][sl_num] = single_turn_len[sl_num] + multi_turn_len[sl_num];
pruicss_xchg->enc_len[ls_ch].data_len[sl_num] = single_turn_len[sl_num] + multi_turn_len[sl_num];
priv->num_encoders[ls_ch]++;
}
}
pruicss_xchg->enc_len[0].num_encoders = priv->num_encoders[0];
pruicss_xchg->enc_len[1].num_encoders = priv->num_encoders[1];
pruicss_xchg->enc_len[2].num_encoders = priv->num_encoders[2];
}
int32_t bissc_set_ctrl_cmd_and_process(struct bissc_priv *priv, uint32_t ctrl_cmd[])
{
struct bissc_pruicss_xchg *pruicss_xchg = priv->pruicss_xchg;
pruicss_xchg->ctrl_cmd[0] = ctrl_cmd[0];
pruicss_xchg->ctrl_cmd[1] = ctrl_cmd[1];
pruicss_xchg->ctrl_cmd[2] = ctrl_cmd[2];
int32_t ch = 0, ch_num;
if(priv->load_share)
{
pruicss_xchg->ctrl_cmd_status[0] = (pruicss_xchg->channel & 0x1)?1:0;
pruicss_xchg->ctrl_cmd_status[1] = (pruicss_xchg->channel & 0x2)?1:0;
pruicss_xchg->ctrl_cmd_status[2] = (pruicss_xchg->channel & 0x4)?1:0;
while(pruicss_xchg->ctrl_cmd_status[0] + pruicss_xchg->ctrl_cmd_status[1] + pruicss_xchg->ctrl_cmd_status[2])
{
if(bissc_command_process(priv) < 0)
{
return SystemP_FAILURE;
}
ClockP_usleep(1000);
}
}
else
{
pruicss_xchg->ctrl_cmd_status[0] = 1;
while(pruicss_xchg->ctrl_cmd_status[0] & 1)
{
if(bissc_command_process(priv) < 0)
{
return SystemP_FAILURE;
}
ClockP_usleep(1000);
}
}
/*supplying 2 extra cycles for ctrl communication stop bit */
bissc_command_process(priv);
ClockP_usleep(1000);
bissc_command_process(priv);
ClockP_usleep(1000);
for(ch_num = 0; ch_num < priv->totalchannels; ch_num++)
{
ch = priv->channel[ch_num];
priv->enc_ctrl_data[ch].cmd_result = pruicss_xchg->ctrl_res[ch].ctrl_cds_res;
priv->enc_ctrl_data[ch].cmd_rcv_crc = pruicss_xchg->ctrl_res[ch].ctrl_rcvd_crc;
priv->enc_ctrl_data[ch].cmd_otf_crc = pruicss_xchg->ctrl_res[ch].ctrl_otf_crc;
priv->ctrl_crc_err_cnt[ch] = pruicss_xchg->ctrl_res[ch].ctrl_crc_err_cnt;
}
return SystemP_SUCCESS;
}