diff --git a/config.toml b/config.toml
index 90a3f7d..a089b83 100644
--- a/config.toml
+++ b/config.toml
@@ -15,3 +15,6 @@ theme = 'beautifulhugo'
[[module.mounts]]
source = 'static/media'
target = 'assets/media'
+
+[markup.goldmark.renderer]
+ unsafe = true
diff --git a/content/posts/005-stm32begin-004-pwm.md b/content/posts/005-stm32begin-004-pwm.md
new file mode 100644
index 0000000..1e2f6e0
--- /dev/null
+++ b/content/posts/005-stm32begin-004-pwm.md
@@ -0,0 +1,174 @@
+---
+title: "STM32 For Beginners [4]: PWM"
+date: 2024-10-08T00:36:00+03:00
+draft: false
+summary: "..."
+author: "Rusted Skull"
+series: ["STM32 For Beginners"]
+tags: ["Embedded", "STM32"]
+---
+
+Digital outputs are all fun and good, but very few things in actual reality are digital (just "on" or "off") in nature.
+MCUs have a few ways to emulate a truly analog output, with Digital to Analog Converters (DACs) being the most useful one.
+However, in most cases, we can make due with a digital signal driven in a specific manner. This is where PWM comes in.
+
+# Generating a PWM, For a LED
+
+PWM stands for "Pulse Width Modulation". We will be generating a series of pulses, and modulating, changing, the width
+of those pulses over time. This allows us to do all kinds of fun things in the real world, for example, drive DC motors
+or dim LEDs.
+
+The waveform of a typical PWM signal would look something like this:
+
+{{< figure src="/media/stm32begin-004-001.png" >}}
+
+The waveform has some key properties:
+* Tperiod is the time of a full ON-OFF cycle, this is usually static per application,
+* TON is the time during which the output pin outputs a HIGH signal (in the STM32 case, a 3.3 V signal).
+
+Not pictured is the frequency (FPWM) of the PWM signal. This can be derived from the Tperiod: FPWM = 1 s / Tperiod.
+For, example, if our Tperiod = 25 us, then the frequency FPWM = 1 s / 25 us = 40 kHz.
+
+The other property that's not pictured is the duty cycle (D) of the pulse. The duty cycle represents the ratio
+between the ON and OFF time in a single period: D = TON / Tperiod. In the figure above,
+if we continue with the assumption that Tperiod = 25 us, then we can say that TON = 8.3 us,
+and thus D = 8.3 / 25 = 0.33 = 33%. The duty cycle is the metric that we will be driving by modifying the TON
+of the signal.
+
+An important property of the PWM signal is that, once the frequency of the signal is high enough, in most physical
+systems, the ON-OFF switching will be evened out by the properties of the connected circuitry. This means that the
+observed output voltage UOUT can be expressed as the function: UOUT = UVCC × D.
+Note that UVCC is the peak voltage of the signal, in our case, 3.3 V. So for our drawing, the averaged
+output voltage of the PWM signal is: UOUT = 3.3 × 0.33 ~= 1.1 V.
+
+# Timers
+
+Generating a PWM signal on the STM32 series is done via the timer peripheral. In other cases, these may be called
+counters, or timer/counters. But in principle, across microcontroller series and manufacturers, timers work the same:
+they count the number of pulses, and thus, allow you to keep track of time.
+
+A timer is effectively configured to run at a given frequency, and it will count. It will either count to its maximum
+limit (unsigned 32-bit integer's maximum value for STM32s), or until it reaches a configured Nperiod value.
+Once that value is reached, usually, the timer is reset and it will either stop or restart, depending on the configuration.
+The functionality of a generic timer is illustrated in the figure below.
+
+{{< figure src="/media/stm32begin-004-002.png" >}}
+
+As can be seen, by modifying the Nperiod value, we can modify the real world Tperiod in which the timer
+counts to its reset value.
+
+The rate at which the timer counts is determined by Ftick. For STM32s, the timers are powered by APB1 and APB2 clocks.
+These usually have speeds in the megahertz. Which can be way too big. For this purpose, timers on the STM32 include a frequency divisor:
+a prescaler. This prescaler value will let us slow down the counting to a reasonable point for us. As such, we can say that Ftick = Fin / Nprescale.
+
+This also lets us calculate the Fperiod = Ftick / Nperiod = Fin / Nprescale / Nperiod.
+And if we remember that Fperiod = 1 s / Tperiod, we can calculate the period time as well. From the
+above example, we can say that Fperiod = FPWM.
+
+This lets us tie the period of the PWM to the period of the timer. But we also need a midway point for inverting the signal.
+STM32 timers call this value a "compare" value: it's an arbitrary value during which we can do _something_ in. For generating
+a PWM, the STM32 hardware uses the compare value as the point at which the the pulse inverts its value. This means, we can
+combine the two previous figures as follows:
+
+{{< figure src="/media/stm32begin-004-003.png" >}}
+
+## Configuring a Timer
+
+We now know that we need to configure a timer to generate PWM. Great.
+
+From before, we know that we also have to choose two parameters: Nprescale and Nperiod.
+What you choose as Nperiod will dictate the range in which you can adjust the PWM "value" in code.
+For example, setting a period of 100 will let you input the PWM "power" as a number between 0 and 100.
+Setting it to some other, more random value, will make the logic harder. So, pick a sane period. In our case,
+100 will do.
+
+We thus know that Nperiod = 100 and we also know that Fin = 8 MHz and we wish our output
+frequency to be FPWM = 40 kHz. This lets us calculate Nprescale as the last unknown in our
+configuration.
+
+If FPWM = Fin / Nprescale / Nperiod
+
+then Nprescale = Fin / FPWM / Nperiod
+
+thus Nprescale = 8e6 / 40e3 / 1e2 = 2.
+
+**Note**: due to the digital nature of our work, and with the number 0 counting as a "1" for mathematical purposes,
+both Nperiod and Nprescale will need to be input as the calculate value - 1. So we're finally
+left with:
+
+Nperiod = 99, and Nprescaler = 1.
+
+Now we go over into CubeMX. For illustration purposes, we'll be applying the PWM to the LED that's on the dev board.
+This will have the effect of letting us dim the LED's brightness. Fortunately, the STM32F303k8 dev board has a PWM
+channel attached to the LED pin PB3. We can check this by clicking the pin and seeing if there's any TIMx_CHy functions
+attached to it. In the case of PB3, we can see that there's TIM2_CH2, which means it's connected to Timer 2's channel 2.
+
+{{< video src="/media/stm32begin-004-004.mp4" type="video/mp4" preload="auto" >}}
+
+Our next step is to enable TIM2 by setting its "Clock Source" to "Internal Clock", and setting "Channel2" to "PWM Generation
+CH2".
+
+{{< video src="/media/stm32begin-004-005.mp4" type="video/mp4" preload="auto" >}}
+
+With that done, we now have to set the counter values. We have to set:
+* **Prescaler (PSC - 16 bits value)** to our calculated Nprescale (1),
+* **Counter Period (AutoReload Register - 32 bits value)** to Nperiod (99),
+* set **auto-reload preload** to "Enabled".
+
+{{< video src="/media/stm32begin-004-006.mp4" type="video/mp4" preload="auto" >}}
+
+With this done, generate the code as you would normally.
+
+## Controlling the PWM
+
+We've configured the timer, the PWM output, now to start it and play with its duty cycle.
+
+After code generation, we go to main. The first thing we have to do is actually start the timer
+and start the PWM generation. This is done as such:
+
+```cpp
+ /* USER CODE BEGIN 2 */
+ HAL_TIM_Base_Start(&htim2);
+ HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_2);
+ /* USER CODE END 2 */
+```
+
+The code should be placed in user code section 2, before the while loop but after the MX_x_Init functions.
+
+* `HAL_TIM_Base_Start(&htimx)` will start the actual timer itself, and
+* `HAL_TIM_PWM_Start(&htimx, TIM_CHANNEL_y)` will start the PWM for that timer on the specified channel.
+
+If you're using multiple PWM channels from the same timer, you will have to call `HAL_TIM_PWM_Start` for each
+channel that you're using.
+
+To set the PWM to a given duty cycle value, we would use the macro function `__HAL_TIM_SET_COMPARE(&htimx, TIM_CHANNEL_y, n)`.
+Where the `n` is a value between 0 and Nperiod. This effectively sets us our duty cycle as well.
+
+To dim the LED from off to full brightness in sequence, we could do something like this, for example:
+
+```cpp
+ /* Infinite loop */
+ /* USER CODE BEGIN WHILE */
+ while (1)
+ {
+ __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_2, 0);
+ HAL_Delay(400);
+ __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_2, 20);
+ HAL_Delay(400);
+ __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_2, 40);
+ HAL_Delay(400);
+ __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_2, 60);
+ HAL_Delay(400);
+ __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_2, 80);
+ HAL_Delay(400);
+ __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_2, 99); // because our period was 99 and not 100.
+ HAL_Delay(400);
+ /* USER CODE END WHILE */
+
+ /* USER CODE BEGIN 3 */
+ }
+ /* USER CODE END 3 */
+```
+
+Bootload the code, and off we go. We now have a functional PWM useful for dimming a LED... Or driving motors. Which we'll
+cover next.
diff --git a/content/posts/006-stm32begin-005-motors.md b/content/posts/006-stm32begin-005-motors.md
new file mode 100644
index 0000000..8300cf0
--- /dev/null
+++ b/content/posts/006-stm32begin-005-motors.md
@@ -0,0 +1,32 @@
+---
+title: "STM32 For Beginners [5]: Motors"
+date: 2024-10-10T00:36:00+03:00
+draft: true
+summary: "..."
+author: "Rusted Skull"
+series: ["STM32 For Beginners"]
+tags: ["Embedded", "STM32"]
+---
+
+Thus far we've learned very basic ways of making our microcontroller interact with the world: GPIO mostly.
+But to build a folkrace robot we need a little bit more. Motors, specifically motors with variable speed would help.
+The most simple motor to use in this scenario is a DC motor, like the [Pololu micro metal gearmotors](https://www.pololu.com/category/60/micro-metal-gearmotors).
+
+# Driving DC Motors, Theory
+
+To drive a DC motor, we typically use a H-bridge based motor driver. In the case of the Robotics Club course,
+we are given a [Pololu DRV8835 carrier board](https://www.pololu.com/product/2135) which contains the Texas Instruments DRV8835 dual H-bridge
+chip. "Dual" in this case means that one board can drive two motors, perfect for a simple differential-drive
+folkrace robot.
+
+{{< figure src="https://a.pololu-files.com/picture/0J4056.1200.jpg" caption="Source: https://wwww.pololu.com" >}}
+
+If we look at the "Using the motor driver" section in the "Description" of the carrier board's page,
+we notice the following diagram:
+
+{{< figure src="https://a.pololu-files.com/picture/0J4058.600.png" caption="Source: https://www.pololu.com" >}}
+
+The right side is dedicated to the motors, and the left side specifies the input signals expected from the microcontroller.
+We immediately notice that for this control scheme, the "phase-enabled mode", we need to generate two PWM
+signals, alongside a few GPIO output signals. Let's look a little closer as PWM now, since that's the missing
+piece for us.
diff --git a/content/posts/006-stm32begin-005-tofs.md b/content/posts/007-stm32begin-006-tofs.md
similarity index 90%
rename from content/posts/006-stm32begin-005-tofs.md
rename to content/posts/007-stm32begin-006-tofs.md
index 64cc4f2..2c8f416 100644
--- a/content/posts/006-stm32begin-005-tofs.md
+++ b/content/posts/007-stm32begin-006-tofs.md
@@ -1,6 +1,6 @@
---
-title: "STM32 For Beginners [5]: Time of Flight Sensors"
-date: 2024-10-09T00:36:00+03:00
+title: "STM32 For Beginners [6]: Time of Flight Sensors"
+date: 2024-10-11T00:36:00+03:00
draft: false
summary: "..."
author: "Rusted Skull"
diff --git a/static/media/stm32begin-004-001.png b/static/media/stm32begin-004-001.png
new file mode 100644
index 0000000..7553f99
--- /dev/null
+++ b/static/media/stm32begin-004-001.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:5a4f6d5ea9d8ea36da838592cae7c3686283476f66a0a5dfaf6a99be428f03c3
+size 28605
diff --git a/static/media/stm32begin-004-002.png b/static/media/stm32begin-004-002.png
new file mode 100644
index 0000000..197b033
--- /dev/null
+++ b/static/media/stm32begin-004-002.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:11f01ace894dd6c5532a048fd1edbe64ce37ac60fbc881149c3584027f0aa5ec
+size 52342
diff --git a/static/media/stm32begin-004-003.png b/static/media/stm32begin-004-003.png
new file mode 100644
index 0000000..803a273
--- /dev/null
+++ b/static/media/stm32begin-004-003.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:4bfa68daecc33147a26e45d85a29167d481b17e7e982f24ef5bc2f1ef62a3821
+size 72164
diff --git a/static/media/stm32begin-004-004.mp4 b/static/media/stm32begin-004-004.mp4
new file mode 100644
index 0000000..183c3ce
--- /dev/null
+++ b/static/media/stm32begin-004-004.mp4
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:64e5e215e93ab917bf03aff27a8107196309ed870fdf1d42fea9d0d787551bf1
+size 147509
diff --git a/static/media/stm32begin-004-005.mp4 b/static/media/stm32begin-004-005.mp4
new file mode 100644
index 0000000..436adad
--- /dev/null
+++ b/static/media/stm32begin-004-005.mp4
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:473a9cf242dc35ca8093701c361a74f2468200dcdb327650309960ca98d63510
+size 210692
diff --git a/static/media/stm32begin-004-006.mp4 b/static/media/stm32begin-004-006.mp4
new file mode 100644
index 0000000..c7f2861
--- /dev/null
+++ b/static/media/stm32begin-004-006.mp4
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:82854fed1d163c2b779db71810985e27c7f047bc107a0256d8962cef46806d8c
+size 99858
diff --git a/static/stm32begin-004.drawio b/static/stm32begin-004.drawio
new file mode 100644
index 0000000..871a909
--- /dev/null
+++ b/static/stm32begin-004.drawio
@@ -0,0 +1,1238 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+