|The Pico In C: A 1-Wire PIO Program|
|Written by Harry Fairhead|
|Wednesday, 28 April 2021|
Page 1 of 3
The 1-Wire bus is not an easy protocol to implement in PIO assembler for the Pico - but it can be done. This is an extract from my latest book all about the Pico in C.
Programming the Raspberry Pi Pico In C
By Harry Fairhead
Buy from Amazon.
The 1‑Wire bus is a proprietary bus that is very easy to use and has a lot of useful devices you can connect to it, including the iButton security devices, memory, data loggers, fuel gauges and more. However, probably the most popular of all 1‑Wire devices is the DS18B20 temperature sensor - it is small, very cheap and very easy to use. This chapter show you how to work with it, but first let's deal with the general techniques needed to work with the 1‑Wire bus.
Programming in C on the Pico gives you more than enough speed to implement a bit-banging driver, which for many purposes is sufficient. However, the 1-Wire protocol is easy enough to implement using the PIO. In this chapter we look at the basic ideas of the 1-Wire bus, implement a bit banging program for its most popular device and extend this to a PIO program.
In Chapter but not in this extract.
A PIO DS18B20 Program
Implementing the 1-Wire protocol using a PIO is one of the most difficult tasks we tackle. It needs to both send and receive data and the master has to provide the start pulse for the slave to send data. The specification also makes it seem that we have to use a conditional to vary the timing of the data part of the pulse depending on sending a one or a zero. This is a lot of logic to fit into 32 instructions. In addition a 1-Wire device can send far more data than the FIFO can hold. At first appraisal the idea of implementing the 1-Wire protocol in a PIO program seems hopeless, but with a shift in emphasis it can be made easier.
The main operations that you need to work with a 1-Wire device is to send a set of bytes and receive a set of bytes. In general, the timing requirements of the 1-Wire bus are at the bit level. That is, when you read data the device will generally store the data until you are ready for it. This means that if you can implement a byte read/write in the PIO then the main program can get on with something else while the 1-Wire device processes data. If the main program is interrupted then no harm is done as it can expect the PIO to continue to process the next byte ready for when it returns.
What all of this implies is that all we really have to do is implement a bit send and a bit receive facility. Using the way that 1-Wire protocol is usually described, this would be very difficult. In other words, trying to implement the simple-minded bit-banging protocol as a PIO program isn’t going to work. A slightly different interpretation of the protocol, however, makes it very possible. If you think of each bit frame as starting with a short low pulse which signals the start of the frame, then a zero sends a low after the initial pulse and a one sends a high. In other words, we can implement the write protocol as:
The read protocol is much the same:
In this form the protocol doesn’t need conditionals as the sending of a zero or a one and the receiving of a zero or a one follows the same steps.
Using this version you could simplify the logic of the bit-banging example given earlier, but there is no real need to as there is plenty of space and computational power – using a PIO is a very different matter and regularity in the implementation of a protocol is important.
There is also the problem of how to implement the PIO program so that the C program can make use of it. One possibility is to use one state machine for send and other to receive, but it is possible to create a single program to to do both jobs.
|Last Updated ( Wednesday, 02 November 2022 )|