Bitbanging SPI/UART/etc.. for learning purposes

Go To Last Post
9 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

So i've been learning on AVR for a bit, and i've read about *How* UART/SPI work under the hood. However, I feel like I need to implement a simple software version of them to fully understand how they work and what's going on. 

 

I don't know which one would be better/easier to start with. UART "seems" easier, but I seem to see more Soft-SPI Libraries. From my understanding looking at the USART block diagram were taking a clock and doing some clock generation/division to produce a specific baud rate which takes data from a buffer and feeds it into a shift register where it's fed out (Pretending were talking about TX here) MSB first correct? (Leaving out parity/stop bit). Reading the block diagram im a bit confused what UCSRnA,B,C exactly do (Since they just seem to be sitting on the data bus), I mean I know they are various status/control registers but I guess the diagram doesn't go into detail how they interact of course...nevertheless.

 

Anyways, is this a do-able newbie task? I've read a bit about making sure to sample in the middle of the "bit length". I think probably where I have the most confusion is on timing/latching. IE: Reading/Writing/etc... on clock-edges. For example: If I want to sample at the middle of a clock, or what if I wanted to latch data in on the falling edge im not sure how to do that in software. I understand "what it means" on the hardware side but there is obviously a ton of gaps in my knowledge.

 

So far i've been able to read datasheets and for the most part understand interacting with them on a basic to semi-intermediate level with the Atmega328p, but I want to understand what's going on underneath as well. I think this is where the gaps in my knowledge are pretty heavy (Im used to Web-Dev land, so I feel like I need to refresh in Computer Architecture a bit tbh). 

 

Anyways, sorry for the ramblings. What's a good start with this for someone like me? IMO it'd be really awesome to build a "Physical" breadboard sort of layout with an actual shift register and buffers and status LEDS for example (Maybe SUPER slowed down) to show the same thing.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Mercfh wrote:

So i've been learning on AVR for a bit, and i've read about *How* UART/SPI work under the hood. However, I feel like I need to implement a simple software version of them to fully understand how they work and what's going on. 

 

I really wouldn't bother going that route. I'd be more inclined to buy (if you don't already own) a basic logic analyser and start outputting data and then varying the various configuration bits in the registers to see what effect they have on the output. You'll get a much better feel for what's going on like that.

 

Suppose you do write a software version. How do you know it's accurate?

 

Or download the evaluation version of Proteus and use the built in instruments.

#1 This forum helps those that help themselves

#2 All grounds are not created equal

#3 How have you proved that your chip is running at xxMHz?

#4 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand." - Heater's ex-boss

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Brian Fairchild wrote:
I really wouldn't bother going that route.
-1

 

For once I am going to disagree with Brian's usually excellent advice. I think you will learn more about a protocol by actually trying to implement it than any other way. It's certainly the way I originally learned I2C (though the experience of trying to get a bit-bang version to work then put me off for life!!)

 

For my money SPI is way easier than anything else as a first protocol to implement. The fact that it's synchronous means you don't have any kind of temporal worries. You either drive the entire thing in a loop/state machine or you sample in the same being triggered on inbound clock edges. The one "tricky bit" of SPI is the four possible combinations of CPOL/CPHA but, again, I think actually banging it probably gives you an even clearer understanding of what that is all about.

 

I'd probably leave UART to last (well Rx anyway). I guess UART Tx is OK because again - you can control the activity but, because of the temporal nature of the beast, it's going to involve some kind of timing generator (please make that a timer interrupt, not software delay loops!!)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

That's not a bad idea. I mean from reading other implementations on this board of SPI and UART, it's essentially pulling a GPIO high or low with certain delays correct in the end? (I mean obviously USART is not that simple under the hood, but from reading the block diagram if you take out clock generation/parity config/etc... it's just a shift register with a buffer at the "base level" from what I can see with a clock".

 

I do need to get used to using a Logic Analyzer/Oscilloscope. It's sort of my next purchase if I really want to go down the path of becoming an embedded dev one day. I think im just feeling un-confident being in Web-Dev land for so long. Would a Logic Analyzer be a better buy before an Oscilloscope for someone working at a hobbyist level currently?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

For what you are talking about here a logic analyzer is a better first tool than a 'scope. An analyzer will let you monitor 8 or even 16 channels at once whereas even 4 channel scopes are pretty expensive. You can get an analyzer on ebay for about $10 then run it with the "sigrok" open software. Do NOT be tempted to steal Salae's "Logic" software. Rather stupidly (in my opinion) they don't "lock" their software so you can buy a $10 analyzer then use their software with it but when sigrok does almost as good a job and is free why would you commit intellectual theft?

 

EDIT: the kind of electronics I'm talking about:

 

https://www.ebay.co.uk/itm/24MHz...

 

The software to drive it:

 

https://sigrok.org/wiki/Supporte...

https://sigrok.org/wiki/Getting_...

etc.

Last Edited: Mon. Nov 26, 2018 - 04:44 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:

Brian Fairchild wrote:
I really wouldn't bother going that route.
-1

 

For once I am going to disagree with Brian's usually excellent advice. I think you will learn more about a protocol by actually trying to implement it than any other way. It's certainly the way I originally learned I2C (though the experience of trying to get a bit-bang version to work then put me off for life!!)

 

For my money SPI is way easier than anything else as a first protocol to implement. The fact that it's synchronous means you don't have any kind of temporal worries. You either drive the entire thing in a loop/state machine or you sample in the same being triggered on inbound clock edges. The one "tricky bit" of SPI is the four possible combinations of CPOL/CPHA but, again, I think actually banging it probably gives you an even clearer understanding of what that is all about.

 

I'd probably leave UART to last (well Rx anyway). I guess UART Tx is OK because again - you can control the activity but, because of the temporal nature of the beast, it's going to involve some kind of timing generator (please make that a timer interrupt, not software delay loops!!)

 

I guess that was sort of my thinking, and SPI seems to be more common when I look on this board. Leaving out the different combinations (Sticking with default at first) from my understanding (Using Psuedocode and pretending it's CPOL of 0 and CPHA of 0) were going to (Pretending were transmitting from Master to Slave):

 

  1. Put data on GPIO pin "MOSI" (LSB first on Master from my understanding)
  2. Clock High
  3. Some Delay for "Read-in" time
  4. Read in from "MISO" line (Which would be the MSB from slave)
  5. Delay for Slave
  6. Clock goes low
  7. Shift Right once 
  8. repeat till all bits are shifted out.

 

I think the difficulty for me is timing and latching. I mean...I can read a timing diagram, but it's my weakest point for sure. Designing/Coding around latching on leading edges/etc.... It's certainly something I need to read about though. I think I need to find myself a decent Digital Design/Computer Architecture book. This book has super good reviews: https://www.amazon.com/Digital-D...

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I think writing both as bit-banged protocols would be great learning projects.

 

I use an O'scope a lot more than my LA, but I'll concede that I am in the minority on this one.

 

If I were to undertake this project I would set up a Master micro, with an LCD, and some LEDs, etc., and program it using the hardware USART (SPI) and high level language interactions with the modules.

This device can Transmit a given signal when you press a push button switch, and can display what is received on the LCD.

 

I'd then make two of the above.

 

With that set up you can now send data back and forth between two micros and see the incoming data on the LCD ( s ).

 

You now have a great hardware platform to work from for the core project, which is writing your own bit-banged drivers.

 

Now, on one of the two setups, you can work with your own code, and you already have a known - good other setup to use for testing, both to send the bit-banged setup data, and to receive data from it.

 

Yes, you will likely benefit from having either an O'scope or LA to visualize the actual data lines.

 

I'd further suggest a couple of Arduino Nano's on breadboards, but any Arduino (clone) hardware would be a good starting point.

 

BTW, driving the LCD is then either the simple matter of using a library, or is itself another learning project, preceding the project, that precedes the final goal project.

 

Photo shows the concept.  An Arduino Nano clone (<$3 USD Banggood Electronics or others), on a breadboard with a small LCD.

(In this case its a graphics LCD, a character LCD would be easier to start with.)

 

The one small PCB has a few extra LEDs and a piezo beeper, these and a push button switch or two could just be on the breadboard, without their own PCB.

 

The little PCB on the left end is a power supply, not needed for your project as the Nano has its own power supply.

 

The square device in the middle is a GPS module, not needed for your project, obviously.

 

Anyway, the concept is two, identical Arduinos on breadboards, set up with LCD displays, push button switches, and a sprinkling of LEDs, to send data back and forth.

 

Good luck with your investigations!

 

JC

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

For bit-banging I2C routines, see the Peter Fleury library code for I2C.  There is an example of bit-bang and one of using AVR's TWI registers and interrupt.

 

For SPI routines, download the Arduino development system (which also uses a Mega328P) and find the SPI.cpp and SPI.h files.   They are buried about six levels deep in the directory structure under 'hardware'.   But they use the SPI hardware peripheral registers of the 328P.

 

I disagree that anyone is better off studying hardware peripherals like I2C and SPI on a low level to the code level.  It is helpful to know how they work in theory, but the actual code to use them has already been done on a high level for Arduino, and it works well.   Concentrate your studies instead on developing effective and easy-to-understand user interfaces using inexpensive (< $10) touch screens.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Given a choice, I'd suggest that bit-banging things is a last resort. Just last week I cobbled up a soft uart as the part i was using had only one uart and I wanted another. In the early days the micros I was using didn't have uarts in them - they were external chips. I would expect any self respecting embedded guy to know how to do this - it is really interfacing 101. Same with i2c and spi - the early micros didn't have peripheral to do this, so one bit-banged them. Back then there was not the interwebs we have today, so you had to do it yourself.

 

If the question is should you or could you? These are simple interfaces, so with some motivation you should be able to do this. There's plenty of prior art to work from or work direct from the specs. I2C and SPI are not so timing critical, whereas uart is. So the uart is a good lesson in real time programming and if you use a timer, timer hardware and interrupts. Note that the way you do a soft uart is not how it is done in hardware!