What is Bit Banging and how to bit bang a SPI bus.
Also how to use an Excel spreadsheet to do logic simulation.
Forum: https://www.eevblog.com/forum/blog/eevacademy-3-bit-banging-spi-tutorial/
EEVblog Main Web Site: http://www.eevblog.com
The 2nd EEVblog Channel: http://www.youtube.com/EEVblog2
Support the EEVblog through Patreon!
http://www.patreon.com/eevblog
EEVblog Amazon Store (Dave gets a cut):
http://astore.amazon.com/eevblogstore-20
T-Shirts: http://teespring.com/stores/eevblog
💗 Likecoin – Coins for Likes: https://likecoin.pro/ @eevblog/dil9/hcq3

Ok, today we're going to talk about deep banging Bit bangs. the process of using software to control hardware instead of using already existing hardware to output some kind of serial protocol. Tipping is usually done in assembly or C or C++ and it's kind of a toss of the hair. It's really quite a slow process and it's not usually all that advisable.

You often hear a lot of gray beards. you know you haven't programmed embedded systems tell you. Bit bang, Whatever. Tipping is actually really simple.

All you need to know about bit banging is basically all you're doing is setting and clearing pin. So in this little waveform up here, this this waveform up here all we're going to be doing is you know we're going to set that point to one. Set that point to zero, Set that point to one, Set that point to zero. Set that to, you know, 1.

Then we'll do it again to 1 and then we're going to set to 0 and then to 1. This is all bit thing is, you're setting the the pins and because this is the earliest time because you're actually plotting this way and you would have set it in this order this way. So to do this, you know the lines of code would be really simple. All we would have done is we would have said let's call the value up here V And let's just say the lines of code are V equals zero because it transitions down the equals one because it transitions up, V equals one because it stays up, V equals zero because it transitions down, and then V equals one.

So the transition up and then again V equals zero because it transitions down, v equals one because it transitions up and then V equals one because it stays up here. So usually it's more advisable to use the hardware in a microcontroller or some embedded system than to be paying. Hardware handles all of the protocol semantics and you don't really have to worry too much about it being overhead on your processor because it all happens in the background. Bit banging is for this reason inadvisable in many applications, but sometimes you just don't have enough serial ports or you don't have the type of serial port you want.

So it is some things about saying that you need to know before we really go into how you do it on a microcontroller. Each pin has the ability to drive the output high, low or be high impedance. Usually when the pin is an imported Italian pins and this is a trait that you exploit in bit banging. This is a Microchips Pic16f877a idea and the output pin just here.

So what they're doing is they have a push-pull driver that sets the value of the output pin. So if you say you know b1 this push-pull the driver just sets the output to one, It just sets it to one and that's what we're going to do into thing. If you set it to zero it of course you know sets it to zero, but if you, for example, wanted to make it high impedance, you wanted to disconnect this output. This is a bit weird, isn't it? So what microchips doing is they're using an XOR gate and a NAND gate to exploit a trait of these push-pull drivers.
that is their opposite values. If they're not, you know, if they're not connected like this, then the outputs will be one of two things. They will be shorted. you know, power to ground, or both of them will be open circuit.

Which is exactly what we want to happen. Because if this wire here is effectively connected to, well, nothing. If this isn't connected and this isn't connected, then we basically have it as high impedance. So what they're doing here is using an XOR gate to XOR with the triste register.

When the Trish register on a pic is set to one they want depend to be an input and when it's set to zero, they want it to be an output. So they're using this XOR gate to make sure that when this is one, this value here is the opposite to this. and that means that these pins end up being open like we wanted. It makes the tri-state here and that way we get that trait.

So they're doing some missing us here to make sure that the two power supply pians aren't shorted. They using the an gate in the XOR gate to make sure that you never have the condition where both the P FET and the M set are on. So why would you want to make the pin high impedance? One of the reasons is the I2c interface requires that the pins be open drained. Each of the pins is pulled up with a resistor to the power supply and if we were just driving the pins, we wouldn't be meeting the protocols spec.

The only way we can do that is by having a open circuit here and allowing that resistor to pull the pin up for the powerplay. So bit banging in general is usually like a tight loop. The loop is usually a series of bits set and bit clears where between each bit you have some kind of clock. So a clock line usually is very periodic something like this.

and between each byte you set, you also have a clock signal so that the other device can clock in the data without the clock signal. The slave device that is the device that's not controlling the bus will not receive any commands at all. So most serial protocols have a master slave relationship with a master controls Whether the slave is listening or responding or and it sends all the commands the slave usually won't engage in conversation, it will only respond because they're very big differences in the way master and slave devices handle their protocol. It is really important to have separate implementations for their bit banging and usually you wouldn't be paying a slave.

The reason is because if a slave device is bit banging, then it must always be polling the bus. otherwise it might miss communication and if it's always pulling the bus, the program can't do anything else. There's no other task that the program can do while it is polling the bus. So when be paying a slave device they need to do a thing called polling.

Polling is basically the process of checking the value of a pin over and over and over and over and over. And when it changes respond when your bit being a slave. This can take a lot of crime and it usually takes too much CPU time to make it viable. So why would you use bit banging? Why would you ever bit bang? It sounds like it's slow and just worse than using the existing hardware.
Well sometimes you simply can't use the existing hardware. Sometimes you just don't have enough serial ports. Sometimes you've got a few I2c devices which is a serial protocol which have the same address and you need to communicate with them. You you need to connect multiple multiple different ITC lines to separate them.

It's either that or a multiplexing solution and sometimes you just want to pay for the extra chip. All right, it's time to learn about the serial peripheral interface. Or Spy Spy is basically a four wire interface occasionally three that has a clock line, a chip select, and two data lines. The data lines are basically data in and data out.

Spy has a master/slave relationship. that means that all the communications are coordinated by the single device. The Master the Slave doesn't ever initiate communication. The only thing the slave can do is respond synchronously with the clock through the My So line.

the master input slave output. The master sends data to the slave via the master output slave input. Occasionally these are names differently, but I believe this. Way's the best.

The Directx way of labeling is confusing and causes pretty big problems with the US and other serial protocol. So as I said before, there's four different wires and bios. Four different wires are as follows here, and these wires only go in the single direction. The chip select clock and mosy only driven by the master.

The only line that the slave does Drive is the My So So. A typical spy frame has a signal that looks like this: You have a clock line that goes up and down like this and then you have a select line which is active low and you have these data lines. The data lines are synchronized with the clock and they could be synchronized rising edge or a falling edge. So Spy isn't as basic as the previous picture made.

It seemed it actually has a thing called polarity which complicates this interface, which basically indicates the idle state. That's this line here that the clock line returns to. That is the the logic level that the clock line is on when it's not communicating with any devices. So in this case, polarity is 0 and it is logic low before and after 5 frames.

In the case where it's Polarity 1, the idle state is high. As you can see on this line, they are basically just upside-down You can think of the polarity being one being the clock line inversion. So the first edge of polarity 0 is actually a rising edge and the first edge of polarity 1 is a falling edge. This means that when you implement a protocol for this in bit banging, or maybe you just want to look at your oscilloscope and try reverse engineer what you're receiving, you need to know.
You know, am I reading on a rising or a falling edge? In this case, we have the middle of the byte. That's kind of when you want to read or clock in data is right in the middle. So we're reading on that rising and that falling edge. Strictly speaking, that isn't the end of the complexity of Spie.

So as well as the polarity, the upside down this of the clock line, you also have the phase and that basically is when are we clocking in and clocking out data. So a phase of 1 is basically shifting the data by half the period of the clock. See the distance between these red lines is the period of the clock and notice when phase is 1, we've shifted the data across by. Ah, In this case, the data is clocked out on this first red line and then it is red on this blue line.

Here, That is when phases One: When phases 0, it's initially the data and then it reads on this first line. Here, clock down. the blue line reads on the red line and you get the opposite for phase one. This can be a bit confusing in code because it does make your code look a little higgledy-piggledy The phase is much more complicated to implement than the polarity usually in bit banging libraries.

You have a very simple implementation. You don't need to usually implement all the different variations in polarity and phase. That is because you usually have a very specific application in mind and it's unlikely. and I've never seen it before that a chip implement simultaneously.

For example, Polarity 0 & 1. Chips do often have support for two different spy modes though, but it's not 0 1. It's often pairs 2 after each other. So for example, they have support for everything with clarity 0 or with clarity 1.

This is why in data sheets like this one, you often see this type of list. You see a polarity is 0 and 0 or polarity is 1 and 1. A common way you see the spy bus connected is as this diagram shows here you have all the different devices connected to the same bus and selected with separate chip select line. When the device isn't selected, these pins here go high impedance and it is as if the master is communicating directly to the slave it chooses to.

Okay, so to demonstrate this painting, I've got a small library in C++ that basically emulates a bit bang spy port and we're going to use this library to test whether we've implemented the be span correctly. So we're just going to run it now and it spit out some data. We're transmitting the number 12 on the four different spy nodes, so let's just copy all of that and put it into a spreadsheet. So we're pasted the data into a spreadsheet and this can be useful if you're you've only got an oscilloscope, not a logic analyzer.

You can compare what the wave looks like on the oscilloscope to what we have in a plot like this. So in this case we do in fact have 12. So as you can see on this, this edge Here, the rising edge. We have one and on this edge here we have another one followed by two zeros.
and that is how the number 12 looks in binary. So this is what we expect and as you can see, the polarity is different like we expect where the default value of the idle value is high when player Is 1 and it is low when polarity is low. The phase is doing the same thing where the the waveform appears to be shifted by half the period. So what does a right routine look for a bit Bank spy port.

So we've got to be talking with all the four pins to implement this and we have to transmit and receive eight bits. So that means we need to have a loop that goes around eight times. but before and after that loop, we need to select and deselect the line. so that means to put it to logic low and then after the frame, bring it back to logic high.

These two lines here and here handle all the chip select nonsense and in the middle, we can focus on the bits. So the first thing we do is set the data pin. Uomo sees value. If the most significant bit of the input is 1, then we want to set the pin to be 1.

Following that, we do the first rising clock edge and then we input some data from the buffer. This is a standard order to do this and then we want to lower the clock edge again. ready for the next loop around. Before we go around again, though, we need to make sure that our next bits that we send isn't the same bit.

We need to move the second most significant bit to the position of the most significant bit. we do this with this shift operation. so after then we go round to the top again and then we're sending the second most significant bit and then it'll go round and round and round until we're at the the 8 bit in the byte and then it will follow through here. Return it to the idle state and deselect the line.

Ok, so here we are loading up co-composer and we're just going to show I'm just going to show that the code is exactly the same between platforms. This is why the Visual Studio Excel testing thing is kind of ok. So I'm just going to copy my gift for the Visual Studio code literally just cop in it. There we go.

and now we're going to go to the ICC seeing in this library here. I'm just going to paste over the top. There we go. So now it's identical and we're going to just run it straight away.

No changes and yes, it builds and it's loading onto the platform now. And before I start simulations is our setup. This is the Teva see setup. It's a TM for micro controller like from 2014 Texas Instruments device and we go to Staley Logic Analyzer bringing feedback into the computer so we can read back the spy frame in Staley logic on the PC so we can confirm that our protocol is correct.
Okay, we're just going to run it now and the application is configured to only transmit when I press on the button. So I'm just gonna open up Steely logic. Okay, so we serve the logic analyzer now is going to start simulation. Okay, we're clearly collected too much data, but here we have the spy frames.

There's got a few things, some transmitting at once here, so let's see if we can figure out what's happening. So what we have here is the spy frame, a single five frame with a clock line here, and the chips lucky, and the data here. So what are we transmitting? What number? So in this case we're writing a counter. so the port 0 is sending the even numbers and port 1 will be sending odd numbers.

So here we have the port 0 up the top sending 42 and then we have port one sending 43 45 47, all the odd numbers and each of them going up by 2 and the port 0 is doing the same boy 2 44 46 48 so we can confirm that it is receiving the frames correctly and sailing logic. The sailing logic analyzer is correctly interpreting our frames. so I hope you found that useful and I hope that you learnt a little bit more about the spy protocol bit banging and how you can use you know simulations on the PC to help out in your debugging bye you.

Avatar photo

By YTB

22 thoughts on “Eevacademy #3 – bit banging spi tutorial”
  1. Avataaar/Circle Created with python_avatars IngenieroCristian says:

    Awesome! Could you please tell me which books deal with this topic? I happen to need to do a development with ESP8266 and I2C acting as multi-master

  2. Avataaar/Circle Created with python_avatars Khairul Akmal says:

    What is the brand and model of your logic analyzer..

  3. Avataaar/Circle Created with python_avatars tohtorizorro says:

    Watching this video either leaves you where you were or more confused.

  4. Avataaar/Circle Created with python_avatars snnwstt says:

    That has nothing to do with bit banding. Bt banding is about accessing one bit. When you write a value in an octet, you write the whole 8 bits. You cannot WRITE just one bit. So unless you have some special C extension, you have to relay on trick like reading the octet, or-ing it with the proper mask, write base the result of the or-operation. Well, that works to write a one. To write a 0, you have to and, not to or, the negation of the mask. That makes 3 instructions, which CAN BE INTERRUPTED, and using an operator which differs if you wish to assing a 1 than to assign a 0. It is even slower if you use a function call (with the added push/pull). With the help of bit banding, you can direaclty write the value 1b, or a 0b, in an appropriate memory address and, through hardware wiring, that would write the 1, or the 0, in one single step, so, not interruptible. So, to the contrary of your claim, bit banding is FASTER than any other code, since it is as fast as the memory write can be, that is, ONE clock cycle. You seem to be confused with mimicking SPI protocol by software instead of using specialize hardware peripheral of the MCU, which has, once again, NOTHING TO DO with bit banding.

  5. Avataaar/Circle Created with python_avatars jnk mal says:

    Dave, what happened to your voice?

  6. Avataaar/Circle Created with python_avatars Sreejith S says:

    Without flow control, how a master will assure a successful communication ?
    (If it is I2C, there is ACK response, right ? But it is not there in SPI. Then how ?)

  7. Avataaar/Circle Created with python_avatars jonka1 says:

    Sorry but this simply does not work. I'm trying to learn here. This all went far too fast. Not everyone has an IQ of 200 and this ended up as an example of too much knowledge in too little time. Dave please come back and present your wonderful way of explaining things.

  8. Avataaar/Circle Created with python_avatars Yasir Noori says:

    A big thumbs up to the multimeter and Aneng for its price.

  9. Avataaar/Circle Created with python_avatars Quentyn Zbikowski says:

    This tutorial is completely useless for anyone that doesn't already have a pretty comprehensive understanding of bit banging.

    Taught from the perspective of someone that has been embedded in the environment so long that he doesn't know what is or isn't common knowledge.

  10. Avataaar/Circle Created with python_avatars Bill Allen says:

    Yawn – Falling asleep within 10 mins

  11. Avataaar/Circle Created with python_avatars Radek Rak says:

    Co-hosting EEVBlog like that is the best idea since the channel started 🙂

  12. Avataaar/Circle Created with python_avatars SkyCharger001 says:

    I was just wondering: is it possible to make the chip-select bidirectional so that it could work as an IRQ?

  13. Avataaar/Circle Created with python_avatars SkyCharger001 says:

    another reason for bit-banging: if (the initial run of) the serial-communication-chip does not meet its design-criteria. (This is why the C64 uses bit-banging instead of dedicated serial by default.)

  14. Avataaar/Circle Created with python_avatars Esven says:

    Couldn't you use an interrupt on the slave device?

  15. Avataaar/Circle Created with python_avatars Menis Ponster says:

    Who are you and where is kermit?

  16. Avataaar/Circle Created with python_avatars Guy Tech says:

    Bit banging is necessary simply because some SPI devices don't have common word sizes, or do something funky like outputting date while you sending the next instruction/command. It would be nice if SPI device manufactures didn't do funky stuff so we could just us hardware implemented SPI I/O!

  17. Avataaar/Circle Created with python_avatars AvE says:

    Get well soon Dave!

  18. Avataaar/Circle Created with python_avatars Lukas Dzunko says:

    Why are you drawing plot in opposite direction ? We normally draw earlier time on left and later on right. E.g. time "flow" from left to right. I am missing something ?

  19. Avataaar/Circle Created with python_avatars STRONG TONY says:

    If you say so pal…

  20. Avataaar/Circle Created with python_avatars fatima I.M says:

    thumbs down are from people who prefer i2c over spi

  21. Avataaar/Circle Created with python_avatars Glayson Nobre says:

    Ola DAve favor faça um video sobre o beeprog2 se possível descubra como o gravador identifica os adaptadores pois os mesmos são de uso exclusivo.

    Hi DAve please make a video about beeprog2 if possible find out how the recorder identifies the adapters because they are for exclusive use. Send hi to Brazil

  22. Avataaar/Circle Created with python_avatars gonX says:

    Just some criticism on the audio, it sounds really muffled and digitally compressed at a low bitrate. The bitrate is a recurring issue with most of the EEVblog videos, but this one takes the cake for shoddy audio quality. Otherwise the content is top notch, keep it up Dave^2!

Leave a Reply

Your email address will not be published. Required fields are marked *