Hello,My ultimate goal is to achieve three QOM channels output the same waveform, but with a fixed time difference.
I use the QOM function of MPC5554 to control the output waveform of QOM by assigning the address of the event array stored in QOM directly. Qom0 and QOM1 channels use reference mode, QOM2 channel uses immediate mode. I assign ref directly to the following address:
ref=(uint32_t *) ((uint32_t) fs_etpu_data_ram (QOM2_CHANNEL) - (uint32_t) & ETPU_DATA_RAM + FS_ETPU_QOM_LAST_MATCH_TIME_OFFSET);
*(pba + ((FS_ETPU_QOM_REF_ADDR_PTR_OFFSET - 1)>> 2)) = (uint24_t) ref;
But when I use the Reference Address mode, QOM0 and QOM1 do not start with the last match of Qom2 and the time difference of QOM0 and QOM1 between QOM2 is random. Is the reference Address pattern used to assign values directly to the ref's address? How to use reference Address schema correctly?
static uint8_t Event_Array_Update(uint8_t channel,uint32_t CTL_Array[],uint8_t CTL_Array_size)
{
uint32_t *pba;
uint32_t *pba_array;
uint8_t i;
if (eTPU->CHAN[channel].CR.B.CPBA != 0)
{
pba = fs_etpu_data_ram (channel);
pba_array = (pba + (FS_ETPU_QOM_NUM_PARMS) / 4);
}
else return 1;
for(i=0;i<CTL_Array_size;i++)
{
if (i%2==0)
{
*(pba_array + i) = (CTL_Array[i] << 1) + 1;
}
else
{
*(pba_array + i) = (CTL_Array[i] << 1) + 0;
}
}
}
static uint8_t fs_etpu_qom_loop_update(uint8_t QOM_channel,uint8_t loop,uint8_t IC_channel,uint32_t * ref)
{
//only used to FS_ETPU_QOM_LOOP mode channel
uint32_t *pba;
uint8_t *pba8;
uint8_t i;
if (eTPU->CHAN[QOM_channel].CR.B.CPBA != 0)
{
pba = fs_etpu_data_ram (QOM_channel);
pba8 = (uint8_t *) pba;
/*only write reference pointer if using that mode. */
*(pba + ((FS_ETPU_QOM_REF_ADDR_PTR_OFFSET - 1) >> 2)) = (uint24_t) ref;
}
else return 1;
if (mapTestMode == 0)
{
*(pba8 + FS_ETPU_QOM_LOOP_COUNT_OFFSET) = loop;
eTPU->CHAN[IC_channel].CR.B.CIE = TRUE;
eTPU->CHAN[QOM_channel].SCR.R = FS_ETPU_QOM_LOOP;
}
else if (mapTestMode == 1)
{
eTPU->CHAN[IC_channel].CR.B.CIE = FALSE;
eTPU->CHAN[QOM_channel].SCR.R = FS_ETPU_QOM_CONTINUOUS;
}
eTPU->CHAN[QOM_channel].HSRR.R = FS_ETPU_QOM_INIT_PIN_LOW;
eTPU->CHAN[QOM_channel].CR.R =
(FS_ETPU_PRIORITY_MIDDLE << 28) + (FS_ETPU_QOM_TABLE_SELECT << 24) +
(FS_ETPU_QOM_FUNCTION_NUMBER << 16) + (((uint32_t)pba -
fs_etpu_data_ram_start) >> 3);
}
void Data_Update_all(void)
{
{
CTL_off_Time_Map=check_bound24(CTL_off_Time_Map,4000000,0);
CTL_1st_oil_Map=check_bound16(CTL_1st_oil_Map,2500,0);
CTL_1to2_oil_off_Time_Map=check_bound24(CTL_1to2_oil_off_Time_Map,4000000,0);
CTL_2nd_oil_Map=check_bound16(CTL_2nd_oil_Map,2500,0);
CTL_2to3_oil_off_Time_Map=check_bound24(CTL_2to3_oil_off_Time_Map,4000000,0);
CTL_3rd_oil_Map=check_bound16(CTL_3rd_oil_Map,2500,0);
INJE1[0]=CTL_off_Time_Map;
INJE1[1]=CTL_1st_oil_Map;
INJE1[2]=CTL_1to2_oil_off_Time_Map;
INJE1[3]=CTL_2nd_oil_Map;
INJE1[4]=CTL_2to3_oil_off_Time_Map;
INJE1[5]=CTL_3rd_oil_Map;
ref1=(uint32_t *) ((uint32_t) fs_etpu_data_ram (QOM2_CHANNEL) - (uint32_t) & ETPU_DATA_RAM + FS_ETPU_QOM_LAST_MATCH_TIME_OFFSET);
//ref1=(uint32_t *) 0x00023420;
Event_Array_Update(QOM0_CHANNEL,INJE1,6);
INJE2[0]=CTL_off_Time_Map;
INJE2[1]=CTL_1st_oil_Map;
INJE2[2]=CTL_1to2_oil_off_Time_Map;
INJE2[3]=CTL_2nd_oil_Map;
INJE2[4]=CTL_2to3_oil_off_Time_Map;
INJE2[5]=CTL_3rd_oil_Map;
ref2=(uint32_t *) ((uint32_t) fs_etpu_data_ram (QOM2_CHANNEL) - (uint32_t) & ETPU_DATA_RAM + FS_ETPU_QOM_LAST_MATCH_TIME_OFFSET);
Event_Array_Update(QOM1_CHANNEL,INJE2,6);
INJE3[0]=CTL_off_Time_Map;
INJE3[1]=CTL_1st_oil_Map;
INJE3[2]=CTL_1to2_oil_off_Time_Map;
INJE3[3]=CTL_2nd_oil_Map;
INJE3[4]=CTL_2to3_oil_off_Time_Map;
INJE3[5]=CTL_3rd_oil_Map;
ref3=0;
Event_Array_Update(QOM2_CHANNEL,INJE3,6);
}
}