Week 6 - Embedded Programming

Group Assignment

Group Page

Solo Assignment

The solo assignment for this week was to first programmer a board to interact with both inputs and outputs. Then, to have it communicate between a remote device(wired or wireless).

Input and Outputs using a Micro-Controller

For programming input and outputs onto a board, I used what I programmed in week 4 to show understanding.

Communication Between the Micro controller and my computer

For the communication between my computer and the board, I used the Serial monitor as my example. When the button on the board is pressed, the serial monitor on my computer displays "Button pressed."

Programming the ATtiny412

Programming the ATtiny412 using an Arduino

To test the ATtiny412 board, we hooked it up to an Arduino using port 6 as the programming port. We then uploaded JTag onto the Arduino to which allows the Arduino to act like a programmer.

Using Jtag

Jtag is super simple to use. First, wire to port 6 the programming port(usually port 6)

Then, go to examples, go down to jtag, and select it

Finally, open a new sketch and write the code as if there is no programmer between.

However, when I sent the code to the ATtiny, we ran into our first problem.

issue 1

The first problem that we encountered was that the light wouldn’t blink. To solve the problem, I first started by checking if the chip was getting power with a multimeter and it was successfully getting 5 volts. Next, I tested some other parts such as the schematics and pin names on the chip. Finally, I learned two things after I found the correct pinout for the ATtiny. The first thing that was wrong was that the pin connected to the LED was pin 0 and not pin 2. The second problem was that what I presumed to be ground was actually 5v power so the LED needed to be flipped around and the code had to be reversed. What I mean by this is rather than how a LED usually gets its power from a port and then sends it to a common ground, my LED gets power from the 5v pin and uses the port as a ground. In coding aspects, this means that when I set the power of the port to LOW, the led gains a ground it needs to complete the circuit and the LED turns on.

Working ATtiny board programmed by arduino!

Programming an ATtiny412 using the Quentorres

To learn how to program the board by Quentorres, I followed Quentorres's documentation.

First I had to add the board packages to arduino. To do so, I first went to preferences, then add ", " after existing packages and paste the package below :

            http://drazzy.com/package_drazzy.com_index.json

This adds the ATtiny412 as a board that I can select. Props to SpenceKonde for this method

Then, I added the uf2 software onto the seeed itself by holding B and clicking R. This brought up the file of the Seeed which I proceeded to overwrite with the given uf2 file.

I continued to follow the steps on the tutorial until I ran into a problem.

Problems of pure pain and suffering

Problem 1

The first problem I encountered with the programming was an error that said "A programmer is required to upload". I then ensured all my wires were connected correctly and tried again. The same error came up again and this time, I looked through the internet forums and found someone who had the same problem as me. sohail-inamdar, the account that had this problem was responded to by per1234. The solution proposed was to go to "sketch" and then "upload using programmer". He said that this problem sometimes occurs when using older versions but it fixed the problem so I was content with the fix

Problem 2

After fixing problem 1, I was then met with a new error. Error code 1, this error typically happens when you unplug the chord mid upload. Due to my understanding of this, I presumed that the error was in the connection between the Quentorres board and the ATtiny412 board. At this time, I was using a breadboard with resistors to connect the two boards together with a 4.7k ohm resistor. Many hours of pain and anguish followed my trouble shooting process. After a few days, I learned that one of my friends had taken the image of the adapter board used in the tutorial and turned it into a milling board that they then milled and soldered. When I saw this board, I new it could fix my problem. AND IT DID!!!!!!! Hurray, the times of pain and struggling are over!

More errors that went away after rebooting or double checking things

Working ATtiny board programmed by the Quentorres Board

Programming a SamD11C board using a RP2040 Quentorres

Props to Quentorres for the instructions

Props to Richard Shan for the help with the SamD board

The first step to programming the SamD11C Board as seen below is to download the board library for the board.

Then, I started the scavenger hunt for edbg files and libraries which I highly recommend going to richard's site for.

Baremetal Programming Try 1

To learn baremetal programming, I watched Low level learning's video and richard shan's documentation. Due to me not being a great or aspiring coder, I focused not on creating the code as I got most of it from these 2 people, but to understand how and why it works. I will share my learnings and explanation with you below.

Before we delve into how it works, I advise you first take a brief look at richard shan's code that I will be deciphering.

// Define the base memory address
#define PORT_BASE 0x41004400

// Define access to the Data Direction Set Register (DIRSET)
#define PORT_DIRSET (*((volatile unsigned long *)(PORT_BASE + 0x08)))

// Define access to the Output Toggle Register (OUTTGL)
#define PORT_OUTTGL (*((volatile unsigned long *)(PORT_BASE + 0x1C)))

// Define the base memory address for the System Control (SYSCTRL) registers
#define SYSCTRL_BASE 0x40000800

// Define access to the Register of the 8MHz internal oscillator (OSC8M)
#define OSC8M (*((volatile unsigned long *)(SYSCTRL_BASE + 0x20)))

void setup() {
  OSC8M |= 0x1;   // Enable the internal 8MHz oscillator by setting the first bit of the OSC8M register.

  PORT_DIRSET = (1 << 5);   // Set the 5th pin as an output 
}

void loop() {
  PORT_OUTTGL = (1 << 5);   // Toggle the state of the 5th pin 
  for (volatile unsigned long i = 0; i < 2000000; i++); // Iterates 2,000,000 times to create a rough delay.
}

int main() {
  setup();
  while (1) {
    loop();
  }
}

How baremetal works

Baremetal programming is the programming behind the arduino IDE that we frequently use. The IDE takes baremetal code, compresses it, makes it easier to read, and lets us input nice simple integers for our values.

Setting up a port

The first step to understanding Baremetal programming is understanding how a port on a chip is called.

A typical chip, lets say an ATtiny 412 for example has ports that can either be inputs or outputs depending on your code. In arduino IDE, we would simply say "pinMode(4, OUTPUT);" and move on with our life. But baremetal is a bit different.

When selecting a pin, we can use

PORT_DIRSET = (x << y)

In this block of code, x can be either 1 or 0. If you set it to 1, the port will be an output. if 0, then an input.

Next, y in this equation is the port pin # of the port you want to use. In the ATtiny, the y for using pin 2 as shown in the pinout below is 6 because the port pin is PA6

By using this code block, you set which port to use and whether that port is an input or output

sending power to a port

After we have defined our port, we can then send power to it. I will only dive into the IDE code of digitalWrite() which sets a output power to 100% or 0%

We can recreate this code using

PORT_OUTTGL = (x << y)

Y in this code still means the port being used. However, X now represents the status of the port. 1 turning the power to the port on, and 0 turning it off.

With this block of code, the led actually gains the power to turn on

Using this knowledge to turn on an LED on the quentorres board.

Results

So........ ya, nothing is working. I don't know if my code is wrong or if baremetal is only from chips and not prebuilt microcontrollers but I will continue to try and explore new possibilities.

Baremetal try 2

Working with my friend Kabir on it

Turns out richards code only works for a samD or a chip. Because of this, I started a diffrent approach in which I used the "see definitions" button on arduino to write and understand baremetal.

The original code that works :

void setup() {
  // put your setup code here, to run once:
  pinMode(7, OUTPUT)
}

void loop() {
  // put your main code here, to run repeatedly:
  digitalWrite(7, HIGH);
  delay(1000);
  digitalWrite(7, LOW);
  delay(1000);
}

The full baremetal code was then created by right clicking on code blocks and clicking "go to definition"

This felt really complicated and I was pretty sure we were not supposed to go this deep, so I headed back and waited for when our teacher would explain how and what we should code on.

Reflection

I learned a ton this week. I learned how to control inputs and outputs, have a board communicate with my computer, and how to use a Quentorres board to program both the ATtiny and the SamD chip. I also learned Baremetal programming which explains the code I use when I write arduino IDE code.