Schematics, datasheets, and drivers.

Schematics and datasheets

An integral part of software (and of course firmware) development is coming up with requirements, i.e. figuring out what your code needs to do. This is actually a surprisingly non-trivial task. Even if you’re given a detailed design on how to structure your code, the exact actions you’ll need to take might not be specified, i.e. what GPIO pin do you read from, or what registers to read from an ADC. This information is generally found in schematics and datasheets. In this section, we’ll go over how to extract this information in a firmware context.

Schematics

Schematics show the electrical layout of a PCB. For the most part, the hardware team stores them in Altium 365: https://university-of-waterloo-solar-car-team.365.altium.com/designs. Note that to get access to Altium 365, let a firmware lead know that you’d like access and send them your email address.

The schematics can generally be found by simply by double-clicking on the board that we want to see. There may be multiple revisions (versions) of the board, so look for the one with the highest number!

Example: here’s where to find the schematics for the BMS carrier board.

Type in “BMS” in the search bar and click on BMS Carrier Board.

Next, look click the design folder to see all the files in the project.

The schematics will be in the .SchDoc files.

Here’s the first page of the BMS carrier board:

These may be intimidating at first, especially if you haven’t done any in-depth circuits courses. Thankfully, we can normally ignore most of the information and focus on the details that affect how we write our firmware.

Note: the following section is outdated because the hardware team changed the way we talk to fans, but the principles and steps still hold true!

Let’s say you were assigned to write the `fan_control` module for BMS carrier. Some quick background: BMS stands for Battery Management System, and “carrier” is the electrical board that runs the firmware. Batteries can get pretty hot, so we have fans to cool them. However, those fans draw current from the batteries, sapping energy we could use for driving. Thus, we power the fans based on the temperature. For now, you can assume the temperature reading comes from somewhere else.

Some questions you might have if you were assigned this:

  1. How do we turn the fans on and off?

  2. How do we set the power level of the fans?

The first place to go for answers is the schematic. On most projects, the first place to go would be the controller board diagram:

It’s usually labelled, but in general it’ll be a tall skinny rectangle with lots of words and lines coming out of it. Here, let’s look for things related to our task:

It may not be immediately obvious what each of these does, but we’ll figure it out eventually. Next, let’s look through the schematic for where these show up again

The FAN_PWM and FAN_x_SENSE labels show up here:

While the fan enable and FAN_X_SENSE show up here:

We can probably make some educated guesses at this point: There’s only one fan enable and fan pwm pin, so those probably control all the fans at the same time. Also, there’s 4 fan sense pins, so there’s probably only 4 fans.

This gives a vague idea of what’s going on, but to really understand, we’ll have to read the datasheet.

Datasheets

Datasheets are documents written by the manufacturer of a component that describes all the characteristics and operation procedures. Many of these we don’t have to worry about since they have to do with the electrical characteristics. We’re using Noctua computer fans for BMS carrier. Normally you’d have to find the datasheet yourself through google (they’re normally pretty easy to find), but I’ve got it for you here https://noctua.at/pub/media/wysiwyg/Noctua_PWM_specifications_white_paper.pdf.

As a reminder, we’re looking to answer the questions “how do we enable the fans?” and “how do we control fan speed?”. Scrolling through the data sheet, this page looks relevant:

With some quick googling, a tachometer is an RPM gauge, so that’s probably how we read speed. The yellow +5V would then be the “enable”, and the blue PWM signal would be the control signal. More details are provided later in the document, I highly encourage you to take a look!

Drivers

Unfortunately, most of the electrical components we interact with aren’t as simple as fans controlled via a PWM signal. Usually, we talk to various ICs (integrated circuits) to perform extra functionality that our controller board can’t, like take very precise voltage and current readings, or read from 30 different thermistors at once. They’re like specialized versions of the STM, with much less or no compute capabilities but better functionality in one area. We usually talk to these chips using SPI and I2C, a couple common communications protocols we’ll get into next lesson. For now, just understand we can send and receive data from them. Some examples of ICs we use:

  • ADS1259: a 24 bit 14,000 sample-per-second ADC we use to measure current coming in and out of our battery.

  • MCP23008: an 8-bit I/O expander that turns 2 bits of IO into 8

  • ADG731: a 32:1 multiplexer/demultiplexer that you choose one of 32inputs to read from.

All of these solve some limitation of our controller boards: for example, our onboard ADC isn’t very precise or fast, and we have a limited number of GPIO pins. You can google the datasheets for any of these if you’re curious how any of them work.

Since we may reuse the same IC in several boards, we separate out the code to interface with these ICs into their own libraries. These libraries are called “drivers”, since they let the STM “drive” the IC.

The datasheets for these chips are often incredibly long and packed with information, often more than 50 pages! Again, a lot of this is electrical characteristics we don’t have to worry about, but there’s still a lot to read. Writing drivers is hard, so be nice to anyone working on them.

In general, the goal of a driver is to make it easy to use the IC, boiling down the nitty gritty register reads and bitwise operations into clean functions like “read_voltage”. For reference, the driver for the MCP2515, a SPI to CAN converter, has ~400 lines of code, while it only exposes three functions.