bit banging newbie questions
blindstar
Posts: 12
I have been playing with the GCC Beta, re-implementing some of my stuff in c. I havent found a GCC 1-Wire driver so I thought I might lean something if I tried to write one. What learned is that I really dont understand what is happening to the bus as I mess with the corresponding DIRA pin as opposed driving the bus high or low using OUTA.
I know my hardware works because I have working apps, which use Micah Dowtys SpinOneWire.spin from the object exchange. I am looking at Micahs code and at the DS18B20 datasheet, which says:
INITIALIZATION PROCEDURERESET AND PRESENCE PULSES
All communication with the DS18B20 begins with an initialization sequence that consists of a reset pulse from the master followed by a presence pulse from the DS18B20. This is illustrated in Figure 13. When the DS18B20 sends the presence pulse in response to the reset, it is indicating to the master that it is on the bus and ready to operate.
During the initialization sequence the bus master transmits (TX) the reset pulse by pulling the 1-Wire bus low for a minimum of 480µs. The bus master then releases the bus and goes into receive mode (RX). When the bus is released, the 5kΩ pullup resistor pulls the 1-Wire bus high. When the DS18B20 detects this rising edge, it waits 15µs to 60µs and then transmits a presence pulse by pulling the 1-Wire bus low for 60µs to 240µs.
Reset code from SpinOneWire.spin:
I understand that the bus is floating high. Could someone explain to me how the following code, fromSpinOneWire.spin generates a 480us low pulse then releases the bus? I appears to set the direction register bit on, waits, then switches it off.
Should the following c code accomplish the same result?
Thanks.
I know my hardware works because I have working apps, which use Micah Dowtys SpinOneWire.spin from the object exchange. I am looking at Micahs code and at the DS18B20 datasheet, which says:
INITIALIZATION PROCEDURERESET AND PRESENCE PULSES
All communication with the DS18B20 begins with an initialization sequence that consists of a reset pulse from the master followed by a presence pulse from the DS18B20. This is illustrated in Figure 13. When the DS18B20 sends the presence pulse in response to the reset, it is indicating to the master that it is on the bus and ready to operate.
During the initialization sequence the bus master transmits (TX) the reset pulse by pulling the 1-Wire bus low for a minimum of 480µs. The bus master then releases the bus and goes into receive mode (RX). When the bus is released, the 5kΩ pullup resistor pulls the 1-Wire bus high. When the DS18B20 detects this rising edge, it waits 15µs to 60µs and then transmits a presence pulse by pulling the 1-Wire bus low for 60µs to 240µs.
Reset code from SpinOneWire.spin:
PUB reset : present '' Issue a one-wire reset signal. '' Returns 1 if a device is present, 0 if not. ' Make sure the line isn't shorted if not ina[pin] present~ return ' Pulse low for 480 microseconds or more. dira[pin]~~ waitcnt(constant(USEC_TICKS * 480) + cnt) dira[pin]~ ' The presence pulse will last a minimum of 60us. ' Wait about 30us, then sample. dira[pin]~ dira[pin]~ dira[pin]~ dira[pin]~ present := not ina[pin] ' Wait for the rest of the reset timeslot waitcnt(constant(USEC_TICKS * 480) + cnt)
I understand that the bus is floating high. Could someone explain to me how the following code, fromSpinOneWire.spin generates a 480us low pulse then releases the bus? I appears to set the direction register bit on, waits, then switches it off.
' Pulse low for 480 microseconds or more. dira[pin]~~ waitcnt(constant(USEC_TICKS * 480) + cnt) dira[pin]~
Should the following c code accomplish the same result?
_DIRA |= 1<<ow_buss_pin; usleep(480); _DIRA &= ~(1<<ow_buss_pin);
Thanks.
Comments
So, DIRA[1] pulls the line low, and DIRA[0] lets the line float high.
Thanks,
Changing the DIRA bit from 0 (input) to 1 (output), connects the pin to the output. So before you do this, the actual voltage on the pin (which you can always read from INA, regardless of what DIRA is set to) is determined by external hardware only. If there is a pull-up resistor on the pin (and no pull-down resistor), the pin will be high.
After you connect the output by setting the DIRA bit to 1, the Propeller drives the pin (as well as the pull-up resistor and any other hardware on the pin, but if the hardware is designed correctly, the Propeller should "win" and drive the pin the way you set the OUTA bit). If the OUTA bit is set to 0, the pin will be driven low.
After this, the OUTA register is connected to the pin of course, and you can change OUTA to make the pin go from low to high and back. When you set the DIRA bit back to 0, the output is taken "offline" so only the external hardware (in this case the pull-up resistor) determines the level of the pin.
Hope this helps.
===Jac
Than you very much for the detailed answer. That is exactly what I was looking for.
--marK