I found the description you mentioned regarding the CNT register being read-only in non GPIO mode, in MPC5777CRM section 36.5.3 (page1399). However, the same section claims "When entering some operation modes, this register is automatically cleared (refer to the “UC Modes of Operation” section for details)."
However, the only note on this topic in the OPWFMB mode, is what I stated in my original post "...Thus in order to avoid the counter wrap condition make sure its value is within the 0x1 to B1 register value range when the OPWFMB mode is entered."
We use this code in a safety-critical application so it is essential that the eMIOS perform correctly. Would it make sense to update the PWM driver to initialize the CNT register prior to entering the OPWFMB, by calling EMIOS_SetUCRegCNT() as shown below?
static status_t EMIOS_DRV_PWM_InitPeriodDutyCycleMode(uint8_t emiosGroup,
uint8_t channel,
emios_opwfm_param_t *opwfmParam)
{
uint8_t restChannel = 0U;
bool restValidate = EMIOS_ValidateChannel(channel, &restChannel);
DEV_ASSERT(emiosGroup < EMIOS_NUMBER_GROUP_MAX);
DEV_ASSERT(restValidate == true);
DEV_ASSERT(opwfmParam != NULL);
DEV_ASSERT((opwfmParam->mode == EMIOS_MODE_OPWFMB_FLAGX1) || \
(opwfmParam->mode == EMIOS_MODE_OPWFMB_FLAGX2));
/* Validate opwfm parametter */
DEV_ASSERT((opwfmParam->periodCount <= EMIOS_OPWFMB_MAX_CNT_VAL) && \
(opwfmParam->periodCount > EMIOS_OPWFMB_MIN_CNT_VAL));
DEV_ASSERT(opwfmParam->dutyCycleCount <= opwfmParam->periodCount);
/* Valid Opwfmb with channels supported */
if (EMIOS_ValidateMode(emiosGroup, restChannel, (uint8_t)EMIOS_GMODE_OPWFMB) == false)
{
DEV_ASSERT(false);
}
/* Configure registers */
eMIOS[emiosGroup]->UC[restChannel].C = 0UL; /* Disable channel pre-scaler (reset default) */
if ((uint8_t)opwfmParam->outputActiveMode == (uint8_t)EMIOS_NEGATIVE_PULSE)
{
EMIOS_SetUCRegA(emiosGroup, restChannel, opwfmParam->dutyCycleCount);
}
else
{
EMIOS_SetUCRegA(emiosGroup, restChannel, opwfmParam->periodCount - opwfmParam->dutyCycleCount);
}
EMIOS_SetUCRegB(emiosGroup, restChannel, opwfmParam->periodCount);
EMIOS_SetUCRegCEdpol(emiosGroup, restChannel, (uint32_t)opwfmParam->outputActiveMode);
EMIOS_SetUCRegCMode(emiosGroup, restChannel, (uint32_t)opwfmParam->mode);
EMIOS_SetUCRegCUcpren(emiosGroup, restChannel, opwfmParam->internalPrescalerEn ? 1UL: 0UL);
#if defined(FEATURE_EMIOS_PRESCALER_SELECT_BITS)
EMIOS_SetUCRegC2UCEXTPRE(emiosGroup, restChannel, (uint32_t)opwfmParam->internalPrescaler); /* Pre-scale channel clock by internalPrescaler +1 */
EMIOS_SetUCRegC2UCPRECLK(emiosGroup, restChannel, 0UL); /* Prescaler clock selected*/
#else
EMIOS_SetUCRegCUcpre(emiosGroup, restChannel, (uint32_t)opwfmParam->internalPrescaler); /* Pre-scale channel clock by internalPrescaler +1 */
#endif
return STATUS_SUCCESS;
}