Digital I/O is too fast, but I don't want to wait_us(1)

06 Jul 2010 . Edited: 06 Jul 2010

Hi all,

It's great to see the mbed libraries are improving all of the time and the DigitalIn I/O libraries benefitted from a speed up a little while ago (http://mbed.org/blog/entry/135/). My project is moving on slowly and I have run into a problem because Digital I/O is too fast so I have to add a couple of wait_us(1) lines to slow things down. Here's my code with the extra wait_us(1) lines in bold text:

while (num_bits--) {

// set DSI bit
PIN_BKPT.write(0);
PIN_DSI.write(bdm_response & 0x80000000);
bdm_response <<= 1;
wait_us(1);

// read DSO bit
bdm_response |= PIN_DSO.read();

// rising edge on BKPT/DSCLK
PIN_BKPT.write(1);
wait_us(1);
}

I have my mbed connected to BDM connections in my car's ECU which is 16.78 MHz, the BDM connection can work at up to half that speed so the ideally my loop should repeat at about 8 MHz. Everything works fine with the wait lines though then the speed is just 0.5 MHz (?). If I take the wait_us(1); lines out then it's too fast and doesn't work properly. I'd like to be able to select inbetween speeds if possible. Is there a way of waiting with smaller steps than 1us?

Thanks in advance,

Sophie x

06 Jul 2010

Knowing the clock speed of the mbed uP, you could insert a series of inline NOP's to generate ultra short delays.  Alternately, you could do  a simple "while" loop that decremented a value.  Both approaches require knowledge of the execution time of the assembly code that underlies the C implementation to know what the true delay is.  The NXP documentation for the ARM can provide you with cycle times for each opcode type.  If you had an oscilloscope, you could use an unused output pin to indicate Delay On / Delay Off by setting and clearing the pin immediately before and after the delay. 

Barry 

06 Jul 2010

In case you're wondering, to generate inline NOP's use the following (note double underscore prefix):

   __nop();

Barry