So we talked a lot about ICs and breakout boards, had a solve these little technical challenges that come up. What if you want to build something more flexible than that? Is a question you can ask. Because in IoT, we see all sorts of crazy stuff. We see these cameras that can recognize faces and things that can pick up objects and move them around in different ways, displays that can display temperature and all sorts of stuff. You might be thinking, how can I design circuits for all these things? The answer is, you really can. Circuits are good for very specific things, driving a motor or increase in voltage. But if you want to do more advanced stuff, like fly drones around or build a car that recognizes shapes or something like that, that's a lot harder you have to deal with many contingencies. It's hard to design a single circuit to do that. So this leads to an interesting idea. What if we could build ICs that were themselves programmable? What if we had something where you can have a little IC with some input pins and some output pins, and then maybe even some control pins where you can tell it what to do. Then if we had something like this we can say, "Hey, IC. Please become a circuit that adds things together." Then tell it to become a circuit that adds pins one through four and five through eight for example. Then we can do that by lighting up certain control pins and then the IC would magically become that circuit and then we send in data. It would get added up and then send out the output pins and so that would be great. Then maybe later on we want the circuit to do something else. You've got your IoT device and encounter some other exception or challenge and so no problem. We'll just tell this programmable IC to become a different circuit. We'll tell it to become a circuit that maybe we need to solve some oscillation challenge. So we're going to encode that as lighting up pin C1. If we send that control information in, it's going to raise and lower pin 5, 20 times a second. Then maybe we have some other challenge. We want it to become a circuit that amplifies the signal on pin 7 and sends it to pin 4. So we wanted to act like an op-amp. So that's fine. Light up a different set of control pins and then it will become that circuit. So would it be great if we had IC that could be programmable and it turns out we do. You've probably heard of them, they're called CPU. So a CPU is a special kind of circuit that's been designed to be extremely flexible and be programmable. What we could do with CPU is we can take them and write programs and put them on them and then have them drive electronics. So here's a simple diagram of how you would use a CPU and a simple device. You have a CPU and you want it to control an LED, a seven-segment display. So what you do is you take your seven-segment display, hook it up to some voltage, and then write a program on your CPU and then your CPU could light up lines which could make certain LEDs turn on in your seven-segment display. So the CPU could light up different patterns, like if we wanted to display an H, then it could light up the sequence of output pins and H would appear. Then we can keep lighting up different sequences. Letter E would be like this. Letter L would be like this and so on. So we can display the word HELLO, for example. So one question is how you do this? Well, CPUs are programmable so you can take a program and write it in code and then put it on the CPU. CPUs are designed to follow a set of instructions. So they have something called a program counter which will point at a certain instruction to start off with. Then there could be an oscillator which tells it to repeatedly move the program counter down, execute the next instruction and then run through the program. So here's a program which makes a CPU write the word HELLO on the seven-segment display. It goes down and executes each instruction in turn. So this is how CPUs work. When you design IoT devices, you need to understand a little bit more than this. You need to understand, because when you design your system, how do you know which CPU to put in your system. So it helps to know a little bit more about CPU. So you can understand the different metrics associated with them. So a typical system is going to have the CPU which has a set of components inside of it. Then a set of supporting components like memory and IO devices and things like that. Typically, your memory is divided up into instruction memory and data memory. So there's this set of instructions which tells the CPU what to do and then a set of data which the CPU can operate over. The CPU communicates with the memory using a set of buses. There's an address bus where the CPU can tell the memory what address is referring to, which location in memory is talking about. There's a data bus where the CPU can send and retrieve data from the memory. Then there's a control bus where the CPU can tell the memory what to do. Inside the CPU, the CPU also has memory. It has a set of registers and counters which can temporarily store values. It also has a state machine where iterates through a set of steps. First, it fetches data and instructions, it decodes the instructions and figure out what to do, then it executes the instruction. It will have an attached oscillator which can drive how fast it runs. So if you overclock your CPU, you're messing with oscillator, you put a faster oscillator in there. Then there's a set of logic inside the CPU. There's something called a decode unit which recognizes a instruction which is encoded as set of bits and then figures out what operations to do based on that set of bits. There's also an Arithmetic Logic Unit which executes the instruction and Control Unit which can be used to control external devices such as memory. So if we were going to execute this program, we've got a program sitting in there in memory and the instruction memory. Here's how the CPU would work. It would turn on and then the first thing it would do is, it would enter the fetch state. So CPU start out by doing fetching. So it's going to be initialized with this program counter to zero. The program counter is going to be put in the memory address register and this is how we do a fetch. It's going to put the address there. Then that address will be sent out over the address bus, and the CPU will tell the memory to do a read. So it's telling that memory to read at the specified address. The memory is going to send back the value at that address over the data bus which will then be put in the memory data register. The CPU will then take the data to register and since it knows this wasn't instruction, it will put that value in the instruction register. This is the current instruction it is dealing with. So it will take the instruction and decode it. So it'll send it to the decode unit. In the decode unit, we'll look it up. It'll look at this instruction and in this particular architecture, we're using the first four bits to encode the operand or the opcode or the type of instruction it is and the last four bits to encode the parameters to that opcode. So here, the opcode is 0101 which we can look in the table. We can see this is a load instruction. So this instruction is going to tell the CPU to load a piece of data. In later instructions, it might tell the CPU to add data or subtract or do various other sorts operations on it. So it's a load instruction and the parameter to this load instruction is 0111. So it's going to load the value located at address 0111. So the CPU then proceeds to put in the address register 0111 because that's the address it's going to operate on and then it moves to execute. So now it's going to execute this load instruction. So it lights up 0111 to the memory and then over the control bus it tells it to do a memory read because that's what a load is, reading the memory. The memory will then retrieve the value located at that address and then send it back which will then be put in the memory data register. Now here things are different. This data is from data memory and the CPU knows this is not an instruction so it's not going to take it and putting it in the instruction register. Instead, it knows it's data and so it's going to put it in the accumulator which is a little piece of memory inside the CPU where you use it to do various arithmetic operations. So perhaps the next instruction is going to add a value and so then we would add that together with the value in the accumulator. So this is a quick tour of how CPUs work. There's a bunch of different components inside, there's opcodes in operands. There's memory and how you communicate over this and this is important to know because when we get into CPUs and in design, we're going to be talking about metrics a lot and different CPUs differ in terms of how many opcodes they have. Some have very rich opcode sets. Some have very small ones. Some of them differ in terms of the size of the address bus and how fast they can communicate and all sort of thing. So it's useful to keep this diagram in your mind as we go through that. Okay, so CPUs are useful. They're used all over the place and they're used in situations where you need customizable logic in your hardware and it really enables this huge explosion and sophistication. We have so many things like operating systems and facial recognition and machine learning and all this stuff it's really enabled because of CPUs. You just could not design circuits that was scale up to these sorts of problems. That said, CPUs have their niche, the place in the market where they occupy. They're focused on digital applications, because of that we have a huge number of components in logic. It's easier to consolidate them into a compact unit, a single device in your system and this makes CPUs great for many applications. Are extremely high-speed, you can do complex things. So CPUs have a lot of benefits. That aside, CPUs have some downsides as well and one of the downside is it's hard to make them cheaply. They're designed to be ultra general. The focus is, maybe I'm using more electricity and more power because they do more complicated things. This leads to a question that comes up a lot in the context of IoT of, what do we do for more cheap applications? If we want to build something that's cheaper. So one idea is, could we take a CPU and scale it down. Make something more special purpose, something targeted to a particular application that only has the capabilities we need. Maybe it's reduced power, reduced clock speed or there are tricks we can do to reduce its costs and the answer is yes. So it turns out there's special purpose CPUs that are designed for specific applications that are lower-cost and these are called micro-controllers. So micro-controller is like a CPU but it's designed to be lower end. So this makes them really useful for environments where you have lower power requirements and things like that. The way we achieve this is we scaled back certain things about the CPU. We reduce it's power usage, we reduce it's clock speed, we reduce it's transmission capabilities. Micro-controllers are often simpler as well. They have more limited instruction sets which makes them more compact physically. Micro-controllers also typically have a consolidated to the design where memory in oscillators and I/O controllers and all this stuff are on the chip itself. So this makes the entire architecture simpler and lower cost. You don't have to design a CPU with a whole bunch of pins and then have a separate memory and a separate I/O bios and all these various things outside the chip. A Micro-controller has all these things on a single chip so you can really focus on making that cheap at low-cost. Micro-controllers often typically have certain on-chip functions like peripherals which are on the chip-set. In addition, micro-controllers are targeted at certain specific applications. Unlike a CPU where you doing really general stuff, micro-controllers are more about certain targeted applications. So in micro-controllers you often find special-purpose functions embedded on the chip itself. So the chip might need to communicate with some analog device. So it wouldn't be surprising to find a micro-controller with ADD converters embedded on the chip or things that can do pulse-width modulation or have little programmable logic blocks on them and so on. So it turns out there's a lot of micro-controllers out there. So when you build something, you need to choose which micro-controller to use and so I'm going to try and get some insights on that next. So how do you choose a micro-controller for your project? Well, there's a few things you might want to keep in mind when you do this. So one thing you might want to keep in mind is the design of the core inside that micro-controller. So say the micro-controller, there's whole bunch of peripherals and stuff like that but at it's core theirs the part of the logic which defines the opcodes and the ALU and things like that and that's typically the most complex part of the micro-controller and that's where you code to. So it's very important and typically micro-controller designs are going to be proprietary to a certain vendor or they might be third-party. There's also micro-controller designs that are shared across multiple vendors. One example of that is ARM. So ARM is a company that produces micro-controller cores and CPU cores and they've been so successful. If you buy a cell phone, there's a very high chance you have an ARM core inside of there and they've been so successful in the CPU market, they're starting to get into micro-controllers too and the 32-bit ARM core is becoming very ubiquitous in the micro-controller market and ARM did something very smart, when they designed their business strategy, they decided, "we're not going to be a hardware vendor, we're going to design the hardware and then we're going to license our design to manufacturers that actually create the hardware" and so the ARM core is something that's been instantiated by large number of vendors. So it's a very popular core. So this is an example of a third-party core. Intel 8051 is another example. That's another core, it wasn't really licensed by Intel but a bunch of vendors copied the Intel design. So these are third-party cores and the advantage of using a third party core is if you go in and implement your design and you need to transition to another vendor, that maybe easier to do if it's a third party core because probably a lot of your programming, your peripherals and all the stuff will be similar across vendors. So that's one issue to keep in mind. Another issue to keep in mind is what do you really need for your system? Do you need something really high-end that has very high performance or something lower-end which uses less battery, less power, is that better? So it's a question of whether you need something high or low-end and there's a good chance you don't really know. When you start fabricating something and you start building something out, there's a chance you guess wrong. You might build something low end and the market can changes you need to deal with higher-end stuff. So vendor's know this. So typically when they sell microcontrollers, they don't sell the microcontroller by itself, they sell them in families, where they'll have a number of models to choose from and they vary in terms of power. So they'll have a microcontroller I mean this will be four kilohertz and they'll have a higher end one that's 20 kilohertz and have different bandwidths and different memory sizes and things like that. Some vendors are really into this, they'll have big families and microcontrollers with hundreds of models to choose from and some have many fewer. The trade-off here is, if you have more models to choose from, you're more flexibility because if you need to switch models, if you have a vendor with a lot of models in the family, then you can switch and it's going to be very easy to migrate your code. You don't have to redo your whole design. Things will just be easier. The downside is vendors who have a lot of different models, lose economy of scale. It costs them more money because they have to fabricate all of these different designs and keep them all out. So typically, vendors with a lot of models in their family have higher prices. So this is kind of a trade-off you have to think about when designing your system. Another thing you could think about is package availability. What do you need? Do you need something really small that can fit in a smartwatch or do you want something bigger? So you can look at what packages are offered by the vendor. You can also think about peripherals. So different microcontrollers have different abilities to communicate off-chip. Some of them have internal clocks, some of them are going to require you to have your own oscillator, which is externally interfaced. Some of them have multiple interrupt channels, so you might have your code running and then something happens. You might want to kind of switch contexts. So different microcontrollers have different kinds of stacks and things like that. Some of them can do Direct Memory Access and there's different ways to control power configuration and things like that. Another thing to think about is the development experience. You're writing code, what tools does the provider offer for debugging? Are their emulators? Do they sell dev boards that make it easy easier to develop? How much do all these things cost? Are they cross-platform? Then in terms of performance, the microcontroller itself will have a bunch of different metrics. How efficient it is in terms of power usage, what it can do per clock cycle, the size of code it needs to store for a given number of operations and so on. In the market, you're going to see that there are certain microcontrollers which are more popular than other ones. Is what I'm going to do next is run through the most popular microcontroller vendor so you know what they are. So this is a list I'm going to go through. One popular vendor is ATMEL. They provide a platform called the AVR Platform. The ATMEL AVR is a design where they really focused on a few number of upcodes. So you might think that would be bad. You might be thinking, "Well, I can't do much with us chip. It doesn't support very many instructions." Well, the benefit of this is they use this reduced instruction set that allowed them to really focus on making the instructions fast, and so, this particular platform supports a large number of single cycle operations. Multiplies take two cycles. As opposed to other platforms where you may need a larger number of cycles per operation for them to execute. Another strength of this platform is, it has many registers and compilers love that. If you're writing code and you're compiling it to a platform, compilers are really good at taking data and sticking in registers, doing a lot optimizations like that. So ATMEL AVR is good for that. A downside of ATMEL AVR is, some other microcontrollers have only one interrupt priority. There could be slow clock speeds compared to the competition. In some example chips are the ATtiny85, which is used in Arduino, ATtiny1616 and so on. Another very popular vendor is Microchip and they produce the PIC Platform. The Microchip PIC is also a RISC design a reduced instruction set design. So again, the focus was kind of doing instructions that you have a small number of instructions but you're focused on making them fast. Strength of this platform is, it supports many peripherals, that's been historically extremely popular. The downside is PIC only has one register, no stack. Lowering chips have no on-chip debugging support. So this platform used to be really popular but has been falling out of favor a little bit for hobbyists. That said, Microchip has also being getting into the game of offering more powerful platforms. For example, they offer the PIC32, which uses a third party core, which offers really good performance and fixes a lot of these downsides. Some example chips are listed here. So I was mentioning ARM. So ARM is this vendor that produces IP core designs and licenses them out, and there's a bunch of different vendors which produce these chips. ARM started out building CPU. So their focus is more and higher end stuff and they've been getting into the microcontroller market with their M zero platform. So because of that, it's not surprising to find out that ARM chips have really beefy characteristics. They have a lot of interrupt vectors. A lot of interrupt priorities, extensive support for runtime exceptions, 13 registers. So they have a lot of functionality on the chip. Some of the criticisms of these chips are, they can have lower code densities. So when you implement something and compile something, your code can take up a lot of space. You might need more storage for that. They have slower interrupt latency. So if you have code that interrupts other code, that can take time to tap as maybe a little bit less, good for real time stuff. Then there's Intel 8051, which was an extremely popular platform. Intel focused on complex instruction set computing with this platform. So the focus was on having a lot of instructions as opposed to making them small and compact. The Intel 8051 had a lot of registers. It could address 64 kilobytes a program in RAM. Very widely cloned architecture. The Platform was famous for having fast interrupt, so it's very good for real-time systems where he needs to react very quickly to events. Some downsides are this platform is only eight bits and that's becoming less desirable when a lot of platforms are moving to 32-bit computing and there's a bunch of different manufacturers that can create clones of this architecture. So that gives us summary of CPUs and microcontrollers and these provide some background on how they work. Next what I'm going to be doing is, I'm going to be talking about other kinds of preamble circuits, like A6 and FPGAs and GPUs, which can give us some insights into other sorts of competing platforms that are used in the context of IoT.