Parallel bus - sync CS toggle to PWM clock

MrCanvas

Well-known member
Hi,

I am revisiting an old project where a T4.1 is controlling ancient IC's on an 8-bit parallel bus with 1MHz clock generated by a PWM on pin 33. So far I have toggled the CS asynchronous to the clock. This works, but sometimes waste write cycles. And more importantly, I dont like how the oscilloscope image looks ;-) The hardware is fixed so I cant just wire up the clock to another pin.

So I a trying to get at least some synchronization to the PWM clock signal. Looking at old posts the suggestion was to compare the correct i.Mx PWM counter registers to understand where the PWM is in its cycle. However I have tried a lot of combinations without much luck.

I deduced that pin 33 is FLEXPWM2.0 (possibly wrong?) but not sure if it is PWM A, B or X. Nevertheless I tried all VALx with no effect. It looks like the sequence stays more or less unsynced to the PWM.

Below is the write sequence (a bit messy due to experimentation but I think the concept is simple). Any suggestions?

Code:
void BusManager::_write()
{
  uint8_t CSpin = _nextEvent->CSpin;
  if (_stage == 0)
  {
    uint8_t address = _nextEvent->address;
    uint8_t data = _nextEvent->data;

    if (_oldAddress != address)
    {
      _oldAddress =  address;
      digitalWriteFast(SID_A0, bitRead(address, 0));
      digitalWriteFast(SID_A1, bitRead(address, 1));
      digitalWriteFast(SID_A2, bitRead(address, 2));
      digitalWriteFast(SID_A3, bitRead(address, 3));
      digitalWriteFast(SID_A4, bitRead(address, 4));
    }
 
    if (_oldData != data)
    {
      _oldData = data;
      digitalWriteFast(SID_D0, bitRead(data, 0));
      digitalWriteFast(SID_D1, bitRead(data, 1));
      digitalWriteFast(SID_D2, bitRead(data, 2));
      digitalWriteFast(SID_D3, bitRead(data, 3));
      digitalWriteFast(SID_D4, bitRead(data, 4));
      digitalWriteFast(SID_D5, bitRead(data, 5));
      digitalWriteFast(SID_D6, bitRead(data, 6));
      digitalWriteFast(SID_D7, bitRead(data, 7));
    }
    // check if passed first trigger point
    _triggerTime = FLEXPWM2_SM0VAL4;
    _currentTimer = FLEXPWM2_SM0VAL1;
    while ( _currentTimer < _triggerTime ) delayNanoseconds(10); // wait for suitable first trigger point
    // set CS
    _setCS(CSpin, LOW);
    // should check here for a second trigger point, then delay to ~100ns after clock goes low
    delayNanoseconds(100);
    //delayNanoseconds(990); // note: this works without any timing checks
    _stage = 1;
  }
  if (_stage == 1)
  {
    _setCS(CSpin, HIGH);
    _nrBufferedItems--;
    _movePtr();
    _stage = 0;
  }
}
 
Last edited:
My "cheat sheet" for identifying the FlexPWM signals is FreqMeasureMultiIMXRT.cpp. Pin 33 is FlexPWM 2.0.B

I can't tell from your code what you want the relationship of CS to be to the PWM edges, but I think you should be able to do what you're trying to do.
 
Thanks, appreciated! So I should be on the right track, but probably screwed up something. Will try again.

As for timing I am aiming to have everything set on the bus about 50ns before clock goes low and then stay about 100ns after that.
 
Well, below is the spec. However I find some 6581 IC's sometimes do funny things when the bus updates near the low-high clock. So I prefer to do everything within the clock high phase if possible. These glitches may be an effect of something else like my pcb design or using 3.3V io.

I am also a bit confused by the iMX manual, are the PWM's "edge aligned" or something else per default if I use analogWriteFrequency/analogWrite?

1718637304757.png
 
Back
Top