summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/random/2024-04-05.md3
-rw-r--r--docs/umich/img/w24_wrapup/311_bad_apple.jpgbin0 -> 172031 bytes
-rw-r--r--docs/umich/img/w24_wrapup/311_hp_4155b.jpgbin0 -> 248257 bytes
-rw-r--r--docs/umich/img/w24_wrapup/311_latex.pngbin0 -> 448670 bytes
-rw-r--r--docs/umich/img/w24_wrapup/373_bike.jpgbin0 -> 352164 bytes
-rw-r--r--docs/umich/img/w24_wrapup/373_dhl.pngbin0 -> 184253 bytes
-rw-r--r--docs/umich/img/w24_wrapup/373_fuck_you_st.pngbin0 -> 123750 bytes
-rw-r--r--docs/umich/img/w24_wrapup/373_log_cover.pngbin0 -> 41935 bytes
-rw-r--r--docs/umich/img/w24_wrapup/373_pcb.pngbin0 -> 240176 bytes
-rw-r--r--docs/umich/img/w24_wrapup/373_pcb_back.jpgbin0 -> 544376 bytes
-rw-r--r--docs/umich/img/w24_wrapup/373_pcb_front.jpgbin0 -> 258584 bytes
-rw-r--r--docs/umich/img/w24_wrapup/373_pcbway_meme.pngbin0 -> 219100 bytes
-rw-r--r--docs/umich/img/w24_wrapup/373_protoboard_parts.jpgbin0 -> 321150 bytes
-rw-r--r--docs/umich/img/w24_wrapup/373_protoboard_wires.jpgbin0 -> 358098 bytes
-rw-r--r--docs/umich/img/w24_wrapup/373_this_side_toward_enemy.jpgbin0 -> 30449 bytes
-rw-r--r--docs/umich/img/w24_wrapup/482_submission.pngbin0 -> 96194 bytes
-rw-r--r--docs/umich/img/w24_wrapup/482_website.pngbin0 -> 118775 bytes
-rw-r--r--docs/umich/img/w24_wrapup/banana.jpgbin0 -> 95607 bytes
-rw-r--r--docs/umich/img/w24_wrapup/blueberry_pizza.jpgbin0 -> 202851 bytes
-rw-r--r--docs/umich/img/w24_wrapup/boston_art.jpgbin0 -> 301661 bytes
-rw-r--r--docs/umich/img/w24_wrapup/dallon.jpgbin0 -> 152500 bytes
-rw-r--r--docs/umich/img/w24_wrapup/eclipse.jpgbin0 -> 21653 bytes
-rw-r--r--docs/umich/img/w24_wrapup/fluke_77.jpgbin0 -> 144864 bytes
-rw-r--r--docs/umich/img/w24_wrapup/gummy_worm_cake.jpgbin0 -> 115991 bytes
-rw-r--r--docs/umich/index.md4
-rw-r--r--docs/umich/w24_311.md238
-rw-r--r--docs/umich/w24_373.md1081
-rw-r--r--docs/umich/w24_482.md356
-rw-r--r--docs/umich/w24_wrapup.md194
29 files changed, 1876 insertions, 0 deletions
diff --git a/docs/random/2024-04-05.md b/docs/random/2024-04-05.md
index be1919f..fe62e55 100644
--- a/docs/random/2024-04-05.md
+++ b/docs/random/2024-04-05.md
@@ -239,6 +239,9 @@ of that.
Dallon casually admitted to sampling a car horn in the ending track,
"iDIOTS OF Oz". We have achieved peak [xkcd #780](https://xkcd.com/780/).
+Over the duration of the show, Dallon threw two picks, but neither was in
+my range.
+
### The cringeworthy story of my PCBs
Warning: this story is cringe. If we ever meet in person, even if we're
diff --git a/docs/umich/img/w24_wrapup/311_bad_apple.jpg b/docs/umich/img/w24_wrapup/311_bad_apple.jpg
new file mode 100644
index 0000000..8de5d1e
--- /dev/null
+++ b/docs/umich/img/w24_wrapup/311_bad_apple.jpg
Binary files differ
diff --git a/docs/umich/img/w24_wrapup/311_hp_4155b.jpg b/docs/umich/img/w24_wrapup/311_hp_4155b.jpg
new file mode 100644
index 0000000..f26c6b2
--- /dev/null
+++ b/docs/umich/img/w24_wrapup/311_hp_4155b.jpg
Binary files differ
diff --git a/docs/umich/img/w24_wrapup/311_latex.png b/docs/umich/img/w24_wrapup/311_latex.png
new file mode 100644
index 0000000..d5d4561
--- /dev/null
+++ b/docs/umich/img/w24_wrapup/311_latex.png
Binary files differ
diff --git a/docs/umich/img/w24_wrapup/373_bike.jpg b/docs/umich/img/w24_wrapup/373_bike.jpg
new file mode 100644
index 0000000..3b81690
--- /dev/null
+++ b/docs/umich/img/w24_wrapup/373_bike.jpg
Binary files differ
diff --git a/docs/umich/img/w24_wrapup/373_dhl.png b/docs/umich/img/w24_wrapup/373_dhl.png
new file mode 100644
index 0000000..b9d818b
--- /dev/null
+++ b/docs/umich/img/w24_wrapup/373_dhl.png
Binary files differ
diff --git a/docs/umich/img/w24_wrapup/373_fuck_you_st.png b/docs/umich/img/w24_wrapup/373_fuck_you_st.png
new file mode 100644
index 0000000..831776a
--- /dev/null
+++ b/docs/umich/img/w24_wrapup/373_fuck_you_st.png
Binary files differ
diff --git a/docs/umich/img/w24_wrapup/373_log_cover.png b/docs/umich/img/w24_wrapup/373_log_cover.png
new file mode 100644
index 0000000..01278af
--- /dev/null
+++ b/docs/umich/img/w24_wrapup/373_log_cover.png
Binary files differ
diff --git a/docs/umich/img/w24_wrapup/373_pcb.png b/docs/umich/img/w24_wrapup/373_pcb.png
new file mode 100644
index 0000000..bd1da09
--- /dev/null
+++ b/docs/umich/img/w24_wrapup/373_pcb.png
Binary files differ
diff --git a/docs/umich/img/w24_wrapup/373_pcb_back.jpg b/docs/umich/img/w24_wrapup/373_pcb_back.jpg
new file mode 100644
index 0000000..23d80bf
--- /dev/null
+++ b/docs/umich/img/w24_wrapup/373_pcb_back.jpg
Binary files differ
diff --git a/docs/umich/img/w24_wrapup/373_pcb_front.jpg b/docs/umich/img/w24_wrapup/373_pcb_front.jpg
new file mode 100644
index 0000000..1f5ee4d
--- /dev/null
+++ b/docs/umich/img/w24_wrapup/373_pcb_front.jpg
Binary files differ
diff --git a/docs/umich/img/w24_wrapup/373_pcbway_meme.png b/docs/umich/img/w24_wrapup/373_pcbway_meme.png
new file mode 100644
index 0000000..07811a1
--- /dev/null
+++ b/docs/umich/img/w24_wrapup/373_pcbway_meme.png
Binary files differ
diff --git a/docs/umich/img/w24_wrapup/373_protoboard_parts.jpg b/docs/umich/img/w24_wrapup/373_protoboard_parts.jpg
new file mode 100644
index 0000000..9503393
--- /dev/null
+++ b/docs/umich/img/w24_wrapup/373_protoboard_parts.jpg
Binary files differ
diff --git a/docs/umich/img/w24_wrapup/373_protoboard_wires.jpg b/docs/umich/img/w24_wrapup/373_protoboard_wires.jpg
new file mode 100644
index 0000000..1216cd0
--- /dev/null
+++ b/docs/umich/img/w24_wrapup/373_protoboard_wires.jpg
Binary files differ
diff --git a/docs/umich/img/w24_wrapup/373_this_side_toward_enemy.jpg b/docs/umich/img/w24_wrapup/373_this_side_toward_enemy.jpg
new file mode 100644
index 0000000..ca95d03
--- /dev/null
+++ b/docs/umich/img/w24_wrapup/373_this_side_toward_enemy.jpg
Binary files differ
diff --git a/docs/umich/img/w24_wrapup/482_submission.png b/docs/umich/img/w24_wrapup/482_submission.png
new file mode 100644
index 0000000..969a11a
--- /dev/null
+++ b/docs/umich/img/w24_wrapup/482_submission.png
Binary files differ
diff --git a/docs/umich/img/w24_wrapup/482_website.png b/docs/umich/img/w24_wrapup/482_website.png
new file mode 100644
index 0000000..dc80170
--- /dev/null
+++ b/docs/umich/img/w24_wrapup/482_website.png
Binary files differ
diff --git a/docs/umich/img/w24_wrapup/banana.jpg b/docs/umich/img/w24_wrapup/banana.jpg
new file mode 100644
index 0000000..beec971
--- /dev/null
+++ b/docs/umich/img/w24_wrapup/banana.jpg
Binary files differ
diff --git a/docs/umich/img/w24_wrapup/blueberry_pizza.jpg b/docs/umich/img/w24_wrapup/blueberry_pizza.jpg
new file mode 100644
index 0000000..51b9956
--- /dev/null
+++ b/docs/umich/img/w24_wrapup/blueberry_pizza.jpg
Binary files differ
diff --git a/docs/umich/img/w24_wrapup/boston_art.jpg b/docs/umich/img/w24_wrapup/boston_art.jpg
new file mode 100644
index 0000000..760e774
--- /dev/null
+++ b/docs/umich/img/w24_wrapup/boston_art.jpg
Binary files differ
diff --git a/docs/umich/img/w24_wrapup/dallon.jpg b/docs/umich/img/w24_wrapup/dallon.jpg
new file mode 100644
index 0000000..92218dc
--- /dev/null
+++ b/docs/umich/img/w24_wrapup/dallon.jpg
Binary files differ
diff --git a/docs/umich/img/w24_wrapup/eclipse.jpg b/docs/umich/img/w24_wrapup/eclipse.jpg
new file mode 100644
index 0000000..506c903
--- /dev/null
+++ b/docs/umich/img/w24_wrapup/eclipse.jpg
Binary files differ
diff --git a/docs/umich/img/w24_wrapup/fluke_77.jpg b/docs/umich/img/w24_wrapup/fluke_77.jpg
new file mode 100644
index 0000000..092a5a4
--- /dev/null
+++ b/docs/umich/img/w24_wrapup/fluke_77.jpg
Binary files differ
diff --git a/docs/umich/img/w24_wrapup/gummy_worm_cake.jpg b/docs/umich/img/w24_wrapup/gummy_worm_cake.jpg
new file mode 100644
index 0000000..4c5fa49
--- /dev/null
+++ b/docs/umich/img/w24_wrapup/gummy_worm_cake.jpg
Binary files differ
diff --git a/docs/umich/index.md b/docs/umich/index.md
index ecb443b..ee428cb 100644
--- a/docs/umich/index.md
+++ b/docs/umich/index.md
@@ -5,3 +5,7 @@ so basically i live in ann arbor now
- [Lessons in the US of A](us_lessons.md)
- [Fall 2023 Wrapup](f23_wrapup.md)
- [Fall 2023 winter break wrapup](f23_winter_break.md)
+- [Winter 2024 Wrapup](w24_wrapup.md)
+ - [EECS 482, Intro to OS](w24_482.md)
+ - [EECS 373, Intro to Embedded System Design](w24_373.md)
+ - [EECS 311, Analog Circuits](w24_311.md)
diff --git a/docs/umich/w24_311.md b/docs/umich/w24_311.md
new file mode 100644
index 0000000..7080ee4
--- /dev/null
+++ b/docs/umich/w24_311.md
@@ -0,0 +1,238 @@
+# Winter 2024 Course Review: EECS 311
+
+2024-05-03
+
+Course Title: Analog Circuits
+
+Rating: 3/5
+
+## Instructor (David Garmire)
+
+On the first lecture I had a feeling I've seen him before. I checked the
+"courses offered" spreadsheet at SJTU last semester, and he taught 281.
+
+He's all nice and stuff, and he never judges you. But the vibes are not
+the best I could imagine. He's pretty reserved, and often seems in doubt
+of himself, as if he's teaching it for the first time. Contrary to two
+other EECS professors I had this semester, he had the least "authority
+figure" vibes. (Robert Dick sometimes has too much; Brian Noble has it
+just right.) Sometimes we can't tell if we're wrong or he's wrong. If we
+point out he _might_ be wrong, he stops right away, which is good, but his
+first assumption is always he _is_ wrong, which hurts credibility if he's
+not.
+
+One thing I like about David Garmire is his analogies. The best one is how
+the NPN BJT is like a leaky tub of water.
+
+## Course topics
+
+- Introduction & review (e.g. Laplace transform, Bode plots)
+- Opamps
+ - Inverting & non-inverting amplifiers
+ - Nonidealities
+- Sallen & Key filters
+- Diodes
+- BJTs
+ - CE, CC and CB configurations
+ - High frequency
+ - Degeneration
+- MOSFETs
+ - CS, CG and CD configurations
+ - High frequency
+ - Degeneration
+
+### Personal reflections
+
+Compared to EE majors in the room, I was all chill about this course.
+I enrolled because I was interested, not because I was required to. It's
+not like my degree or life depended on it. But my life does depend on
+music, and it's part analog circuitry.
+
+Personally, I think Sallen & Key (S&K) just came out of nowhere. There was
+no motivation. It's just a table of equations that we use to solve for
+like six unknowns. It's not fun.
+
+BJTs are the most complex topic. You've got three currents coming in or
+out of the BJT, one of which can _sometimes_ be ignored. You have three
+modes: cutoff, active and saturation. To make a useful amplifier, you have
+to juggle the voltage correctly to bias it in the right range; then you
+get a transconductance, then you convert it to a linear circuit with
+a dependent current source, then you either do a bunch of nodal analysis
+or just apply formulas. In most cases formulas Just Work™.
+
+I remember taking 215 (the OG circuits course) and scoffing at the notion
+of a "voltage-dependent current source". Like who would use that in real
+life? I bet you ten bucks you can't even build one. However, it turns out
+if you apply superposition principle to a non-linear circuit, and
+constrain your input to a narrow range to pretend it was linear, an
+"X-dependent Y source" appears, and it helps you apply linear formulas to
+an otherwise unholy "e to the power of v over something" pasta.
+
+MOSFETs are just BJTs but with different names for everything (the "active
+region" of the BJT is analogous to "saturation mode" of MOSFETs). Also one
+of the three currents is gone (except in high frequency) and you juggle
+the voltages in a different way.
+
+Overall, this course was more inspiring and extensive than I thought.
+However, it was also pretty elementary. I enrolled because two of my
+hobbies (ham radio and music) are closely relevant to analog circuits, and
+I had hoped to build an amp after this course. Although half of the course
+_is_ building amps, it's pretty theoretical.
+
+### Building amps
+
+The majority of our discussion toward the second half of the course was
+transistor-based amplifiers. Interest was mostly on NPN common-emitter or
+NFET common-source, but there are other configurations to fit niches. We
+had these parameters to optimize for:
+
+- Gain (open-circuit, loaded, or overall)
+- Output voltage swing (how many Vpp can you output before clipping)
+- Bandwidth (low & high 3dB cutoff)
+- Output impedance (affects loaded gain)
+- Input impedance (affects overall gain)
+- Power dissipation (how much DC power does it draw)
+
+Desiging amps, especially multi-stage ones such as what I did in lab 5, is
+an ardous chain of trial and error. My observations are
+
+- Build first stage with around 10x the signal impedance
+- Think about gain first
+- 1 mA is usually a good DC current to start with
+- If it doesn't work, try 1.5 or 2
+- DC current determines gain, output impedance, and power
+- Too little and too much current both lead to bad overall gain
+- Decouple all stages by chucking in a 1 µF to 47 µF cap
+- If load impedance is small, add a buffer at the last stage
+- Bandwidth is the last thing to worry about
+- If you need to squash highs, add a cap from a signal to ground
+- If you need more lows to pass, use larger decoupling caps
+
+Those tradeoffs are an inevitable part of an electronic engineer's life.
+Besides, some transistor parameters (such as beta) depend on temperature
+and fab variations, so we had to add feedback to make our circuit less
+susceptable. I now appreciate the amount of work that analog engineers go
+through just to create a usable amp.
+
+### Sine wave breakdown & shoutout to Samuel
+
+Another way to look at amp-building in the scope of 311 is to break down
+a sine wave:
+
+x(t) = A * sin(ωt + ɸ) + b
+
+- A: amplitude, or in our case, gain. We talk _a lot_ about gain. Arguably
+ the _point_ of amps is gain.
+- ω: frequency. We spent two lectures on high frequency response, one for
+ BJTs and one for MOSFETs, which discuss internal capacitances within the
+ transistors. The effect of external capacitors is discussed in the first
+ half of the course, in analog filters.
+- ɸ: phase. We hardly ever talked about phase, and phase Bode plots were
+ not required. However we were required to tell apart inverting and
+ non-inverting amps.
+- b: DC offset. In general not a thing to worry too much about. If you
+ need to get rid of it, just add a cap. If you need it back, bias your
+ base/gate/whatever. It's just a stepping stone for the AC signal.
+
+The frequency discussion is very interesting. We used a duo of methods
+called OCTC and SCTC (open/short circuit time constant) to estimate the
+lower and upper 3dB cutoff frequencies. They work like magic. Two separate
+occasions, the estimate I got with them is within 1% of SPICE simulations.
+Huge kudos to Samuel Nolan, our IA, for explaining the methods in the lab.
+He is the GOAT IA this semester.
+
+### Analog vs. digital
+
+On the first 311 lecture, David Garmire talked about the quote unquote
+"superiority" of analog circuits over digital ones, such as energy
+efficiency. Somewhat ironically, exams two and three had one design
+problem on each, and the premises are both to design an amplifier for an
+ADC, presumably into a chain of DSP algorithms.
+
+Many systems now use DSP, which often is cheaper and/or more noise-proof,
+so unless you're an retro-audiophile or still live in the 1900's, very few
+things actually have analog circuitry from top to bottom. They usually
+have at least one piece of integrated circuit somewhere. But even if it is
+the case — he argues — analog circuits are essential.
+
+There was a 373 lecture dedicated to ADC/DAC, and later there were a few
+slides that discuss analog filters. It was one of the few occasions this
+semester that 311 was useful for another course. I am more than sure it'll
+be useful for 473 next semester as well.
+
+Robert Dick acknowledges that sometimes there are problems 1's and 0's
+cannot solve. One such example is high frequency noises in the ADC input,
+which cause aliasing, and are a pain to distinguish from actual signal in
+software. So the solution is to add a lowpass filter to the input.
+
+I am unsure whether my preference is analog or digital. On one hand,
+analog is cool because my bass is an analog system. But the DAW is digital
+(it literally stands for digital audio workstation). Let's leave it this
+way.
+
+## Labs
+
+Labs are the heaviest workload of 311. There are five labs in total, each
+spanning over two or three weeks.
+
+- Lab 1A/B: opamps
+- Lab 2A/B: S&K filters with opamps
+- Lab 3A/B: voltage boosting & power harvesting with diodes
+- Lab 4A/B: single-stage BJT amp, measuring beta and capacitances of BJT
+- Lab 5: designing a 3-stage amp
+
+The typical roadmap of a lab:
+
+- Prelab: Do calculations, simulate in SPICE
+- In-lab: Build circuit, measure with ADALM and Scopy
+
+Note:
+
+- The ADALM is a virtual lab kit USB device by Analog Devices
+- Scopy is the software to interface with the ADALM. It's got an
+ oscilloscope, a voltage supply, a multimeter, and a network analyzer
+ (which you use to get Bode plots). Thankfully it is open source and runs
+ on Linux (was a pain to install though because it's not in any pacman
+ repo or AUR. Had to manually build it because I didn't want flatpak.
+ Somehow it wanted a patched version of Qt and many other deps so I had
+ to build like six libraries and manually change CMakeLists so one of
+ them compiles)
+- SPICE is a circuit simulator. The lab docs mention LTSpice, which does
+ not run on Linux, so I used ngspice integrated in KiCad. Halfway through
+ the semester, KiCad upgraded to 8.0 which includes a major overhaul of
+ the ngspice frontend — huge improvement.
+
+In lab 3B, I built a circuit that harvests power from a 3.5mm jack to
+light up an LED. Naturally, I made it play Bad Apple:
+
+![Bad Apple playing next to an oscilloscope waveform. An LED lights up on
+a breadboard circuit](img/w24_wrapup/311_bad_apple.jpg)
+
+In lab 4B, I hooked an NPN BJT to a giant beast of a machine, the HP 4155B
+semiconductor parameter analyzer that thought it was 1997.
+
+![An HP 4155B semiconductor parameters analyzer displaying a graph. The
+date is "97AUG07 11:46PM"](img/w24_wrapup/311_hp_4155b.jpg)
+
+Despite not having an A/B, lab 5 took three weeks. After designing and
+simulating (but not building) a circuit, I needed to write a report for
+the design of my three-stage amp. It "must be written with a word
+processor", but did not mention which one.
+
+![Three pages of my report written with LaTeX, featuring a circuit
+schematic, a bode plot, a transient plot, and
+a table](img/w24_wrapup/311_latex.png)
+
+I used up like 10 pages of scratch paper (single sided) just for the
+calculations. Glad I did meet the specs.
+
+## Verdict
+
+It's just a gateway drug to EE. Don't expect too much — you won't be an
+expert when you walk out, but do expect mind-bending moments, like how
+I discovered that I've been misunderstanding BJTs for like five years.
+
+If your job involves interfacing with "weird" analog signals, like signal
+impedances in the megaohms, then this course is essential.
+
+Would be better if the lab was larger though. It's like a can of sardines.
diff --git a/docs/umich/w24_373.md b/docs/umich/w24_373.md
new file mode 100644
index 0000000..95001ce
--- /dev/null
+++ b/docs/umich/w24_373.md
@@ -0,0 +1,1081 @@
+# Winter 2024 Course Review: EECS 373
+
+2024-05-02
+
+Course Title: Introduction to Embedded System Design
+
+Rating: 3.5/5
+
+## Instructors (Robert Dick & Matthew Smith)
+
+Robert Dick is ridiculously tall and uses a [Panasonic
+Toughbook](https://en.wikipedia.org/wiki/Toughbook) running openSUSE. He's
+the lecturer of this course.
+
+Pros:
+
+- FOSS advocate
+- Is happy to discuss "what if" scenarios
+- Shares stories of real startups (including his own)
+
+Cons:
+
+- Too much of "here's the thing, learn it" versus "so here's how they came
+ up with the thing"
+- Sometimes too eager to share the insides of a thing (it's useful though)
+
+Matthew Smith is our lab instructor who oversees all lab equipment and
+material purchases. He's a really nice guy, but I sometimes worry about
+his health.
+
+Pros:
+
+- Is willing to talk about any idea
+- Knows everything in the lab
+
+Cons:
+
+- He'll talk with a student for a long time, which may be good or bad
+ depending on you happen to be that student or waiting behind them
+
+## Course topics
+
+The course covered a pool of loosely-related topics, all relevant to
+embedded systems but divergent. I categorized them:
+
+- Microcontroller low-level
+ - ARMv7-M Thumb ISA
+ - ABI (registers, stacks and stuff)
+ - Interrupts (with preemption)
+ - Timers (hardware and virtual)
+ - PWM with timers
+ - MMIO (including GPIO)
+- Buses
+ - APB (advanced peripheral bus, an ARM feature)
+ - UART
+ - I²C
+ - SPI
+- Analog
+ - ADC
+ - DAC
+ - RC filters
+ - Op-amps
+- Things you can put a circuit on and how to put a circuit on them
+ - Breadboard
+ - Protoboard
+ - PCB (intro)
+ - Soldering and desoldering
+- Other peripherals
+ - Memory (EEPROM, flash etc)
+ - Motors and other things that move
+ - Shaft encoders
+ - Antennas (and wireless communication)
+- Power
+ - Integrity
+ - Battery life estimate
+ - Just Add Another Capacitor™
+ - AC-AC transformers
+ - AC-DC rectifiers
+ - DC-DC converters
+- Meta
+ - How to pick a project to e.g. start a company for
+ - How to debug a complex system (spoiler: you take it apart)
+
+Of these, the topic I learned the most from is interrupts. I had used
+interrupts in my previous [Byseekel](../projects/byseekel.md) project, to
+wake up the AVR MCU from sleep mode. But now I know what actually happens
+is the MCU switches to interrupt mode and switches back to normal mode
+once the interrupt handler is done running.
+
+The most boring topic, on the other hand, is APB. It just floated into the
+slides for no reason. I've never heard of it, and it doesn't seem all that
+essential other than to illustrate a point that you can interface with an
+FPGA or something that speaks the same protocol if you want.
+
+The reason why the range of topics is so wide is because we had wildly
+different projects. But first let's talk about labs.
+
+## Labs
+
+We have seven labs, covering different topics. All of them were done on
+a Nucleo board, and some of them required a Tang Nano, which is a cute
+Arduino Nano-esque FPGA.
+
+The worst part about labs is how long the documents were. The longest one
+was 41 pages. It's full of images, yes, but it's hard not to be
+intimidated. In hindsight, though, it wasn't the worst lab imaginable, so
+I must have overthought.
+
+Labs were done in groups of two. I often came to the lab (which is open
+24/7) before our session to work ahead, so we don't run out of time. Once
+I discovered that I accidentally did most of the lab all on my own. So for
+the sake of fairness, but in a questionable and kinda condescending
+manner, I told my lab partner on the lab that I did most of the work but
+I'm gonna let him do it again anyway. So I let him take the keyboard and
+watched him do the lab, providing help every other minute. I still have no
+idea if I did the right thing.
+
+## Project
+
+In the final month of the semester, lectures and labs were over, and the
+focus shifted to the project. We didn't even have a final exam, only two
+midterms.
+
+At the beginning I was looking forward to the project — it was the first
+time I had the chance to make something tangible at UMich. And at the end,
+though everyone suffered, many teams made something that's at least fun.
+Not us. Not us in the least bit.
+
+__If you are reading this article for academic guidance, please keep in
+mind that this is personal opinion and personal experience. It is 100%
+honest but does NOT represent the project outcome. My experience is more
+than one sigma lower than average. If you weren't an egoistic idiot like
+me, you'll do better.__
+
+Or just skip to [Verdict](#verdict).
+
+I hate this project so much. If you are my teammate and you're reading
+this, please don't take this personally. I redacted your names (and mine
+as well). It's about this course and this course only.
+
+This part has no constructive purpose. It's a long story and it's painful
+even to write about it, but I'm glad it's over. Let me start from the
+beginning.
+
+I made the right decision to keep a project log. It grew to be 15 pages
+long. It's extremely helpful when I'm trying to get my shit together in
+this blogpost.
+
+### Brainstorming
+
+Last semester, three friends of mine were thinking about enrolling in 373
+and asked if I wanted to be their teammate. I said sure. Later, two of
+them dropped, so the one left asked me if we should find our own teams, or
+invite two more. I chose the latter. It cannot be said whether the
+alternative would have been the better choice, but it might.
+
+So one day after lecture, we sat down at a table in Pierpont to discuss
+our team project idea. Everyone brought along three proposals, as required
+by Robert. This brings a total of 12 proposals. Mine were:
+
+- "Blinkensleeves": MkIII of the bicycle blinker project, but instead of
+ having a switch, the cyclist can blink the LEDs simply by lifting their
+ arm. The LEDs are worn on, you guessed it, their sleeves.
+- "Optophone": An optical turntable where you encode MIDI in a circular
+ barcode-ish pattern, print on paper, and spin under a light sensor to
+ play it back
+- "Bookmargotchi": A bookmark with a Tamagotchi-like character that you
+ must feed every day by reading the book for an amount of time
+
+(Short note: before I discussed them with my team I talked with Matt Smith
+about my ideas. He was oh so patient.)
+
+Other proposals included
+
+- Kibble dispenser for stray cats (we have no stray cats here)
+- Automatic garbage can (that ties up a full bag and open a new one.
+ I need it)
+- Thing that warns you when a pot is boiling to the brim (helpful but we
+ can't actually boil things in the lab)
+- Shoe dryer (extremely useful in snowy Michigan weather but seems
+ infeasible)
+
+I felt "smart" and suggested that we settle this with a vote, where
+everyone gives each proposal a rating from 1 to 5, indicating how much
+they _want_ to do it, not how feasible it seems. Then we sum up the
+ratings for every project.
+
+And my bicycle blinker project won. Later I recounted the votes with
+a quota on how many total votes everyone has, but my project was still in
+the lead. And I could see that my teammates trusted me, because I showed
+them my previous iteration. We thought it was a safe bet.
+
+### Brief tangent: other people's ideas & fedi interview
+
+Because everyone dropped their files to a single google drive folder,
+everyone can see everyone's ideas. When I read some of them I thought,
+huh, it's already invented, why you gonna reinvent it?
+
+Things someone wanted to reinvent:
+
+- Panic button
+- Tuner
+- Automatic door
+- Guitar pedal
+
+Some proposed projects just because they could. They did admit the market
+for the product is next to none. My turntable proposal is one of them.
+
+Robert Dick made a great deal out of market research and how to run
+a successful startup. He said it was helpful to interview strangers, so
+I did on fedi, targeting specifically the cyclists (fedi is never short of
+cyclists). I asked:
+
+> cyclists of the fediverse: is there any kind of device that does not yet
+> exist, but you wish existed, that would improve your cycling
+> experience/safety?
+
+> would be cool if a team of undergrads could make it in two months for an
+> embedded system course (we're brainstorming)
+
+> boosts welcome
+
+> \#cycling #embedded #electronics
+
+Part of the fedi crowd brought up a variant of the blinker idea without me
+even mentioning, so it's definitely one of the more common things
+a cyclist could ask for. Others proposed:
+
+- Car-detecting radar
+- Accelerometer-based brake light
+
+So I thought it would be a good idea to combine these three ideas and not
+add more to avoid making a overcomplex device nobody asked for that might
+not even work.
+
+It turns out Robert's advice was for people who actually wanted to make
+money, not those who are just doing a course project. The market research
+is actually of no importance in the grading.
+
+There's also project proposals that address real unsolved problems, but
+there's a reason they were unsolved.
+
+Some projects are both novel and useful, but they don't have to be
+embedded. It could run as a regular computer application.
+
+Now that the course's ended, I found that it's ok to reinvent something
+for a course project. There is a very narrow window of ideas that are both
+novel and useful. So it's ok to be only one of them.
+
+My failure begins here.
+
+Stupid thing #1: unrealistic idealism and wanting my project to be both
+novel and useful
+
+### So what were we actually gonna build?
+
+In our project proposal, we wrote (excerpt):
+
+> Customer: Cyclists who wish to improve safety with little extra effort.
+>
+> Value: Cycling is a significant source of accidents in the US [1]. Our
+> product increases visibility of the cyclist with LEDs, detects passing
+> vehicles from behind, and alerts both the cyclist and driver.
+
+> The cyclist can control the LEDs either by raising their arm or by
+> activating a switch near the handlebars. The LEDs can be mounted under
+> the bicycle saddle, on the front tube, or fastened to cycling apparel.
+> They can light up in different patterns (e.g. blink left, blink right,
+> brake, flash, etc) to alert vehicles […]
+
+> Our product can also detect vehicles approaching the cyclist from
+> behind. When the cyclist is at risk, it flashes LEDs as a warning to the
+> vehicle and activates the buzzer to alert the cyclist.
+
+> Similar products exist on the market [2]. Ours is more modular. For
+> example, the cyclist may choose to remove the arm position sensors,
+> relying on switch control entirely.
+
+> Approach: Our product is modular. The user can hot-plug different
+> modules to a hub. There are two hubs in a typical installation: front
+> and back. The front hub is to be installed on the handlebar, and the
+> back hub may be mounted on the bicycle facing backward, or clipped to
+> the cyclist’s back. Each hub has a Bluetooth Low Energy-capable MCU,
+> likely an ESP32. The hubs communicate with each other to ensure
+> consistent output.
+
+> Each module below can be hot-plugged to the front hub, back hub, or
+> both:
+
+> - Switch module: front.
+> - Accelerometer module: back. Is a pair of accelerometers physically
+> attached to cyclist’s sleeves.
+> - Radar module: back. Consists of doppler radar sensor and buzzer.
+> - LED module: both. Consists of a light sensor and LEDs. Form factors of
+> LEDs may vary but pinouts are compatible.
+>
+> [1] https://www.cdc.gov/transportationsafety/bicycle/index.html
+> [2] https://www.amazon.com/dp/B0C27FGHMW
+
+Do you see the problem? I was way too idealistic. I falsely assumed I had
+the ability to build something out of a startup. Not with $200 budget. Not
+with two more EECS courses I was taking this semester. I went too far into
+thinking about so-called "user experience" up front, without the
+fundamental safety check that the basic functionalities work. I was so
+keen on the idea of building something that's not like other groups:
+robots, screens, cliché smart-X, just smack a couple Adafruit breakouts
+together on a breadboard like a high school STEM 101. I wanted to make
+something that, at the demo day, stood out among the others for its
+incredible simplicity, beauty and reliability. I wanted to make something
+that doesn't look like a 373 project. Something that I would use. That
+people would use. Of course that didn't happen.
+
+The primary mistake of our team is that we did not form a feedback loop.
+Throughout the project, it seemed like I was the one dumping all the ideas
+into a pool, and failed to ask for enough input to mold them into
+unambiguous targets we could set milestones for. It's like saying "hey
+let's cook something" but not specifying what we even want to eat. So we
+had different ideas of what the project is about.
+
+I named my proposal "Blinkensleeves" because I had envisioned LED strips
+taped to jacket sleeves; it did not happen. Instead we just slapped them
+on a boring box. I forgot when we abandoned the sleeve idea, but it was
+not my decision, but my compromise. (Our project would have sucked anyway.
+Also, we named our project "BicycLED" instead)
+
+I did ask for their opinions; but since it was the early stage of the
+course, we could not tell what is good enough for the course. Picture
+this: You tell your teammates you once built X, and you are gonna build
+X II. You have an idea that you're 50% sure will work. You ask your
+teammates for ideas or alternative. The room falls silent. What happened?
+Is it:
+
+- They agree with you?
+- They can't come up with anything else?
+- They don't understand what you said?
+- They are insecure and internally rejected their potentially better
+ ideas?
+- They think you're a fucking idiot and are just being polite?
+
+I was too good at persuading people that my ideas work. Of course,
+I presented them because I thought they do work. Somehow I have deterred
+the rest of my team from contributing.
+
+Stupid thing #2: Not being specific enough about project goals.
+
+The root cause is that the project was too personal. Having had the idea
+since 2021, I couldn't tolerate a product that deviates from my idealistic
+model. This more or less alienated my teammates, and pressured us all in
+the end.
+
+Despite a "complexity point" requirement in the rubric, I refused to add
+unnecessary features such as a screen. My argumet was that screens on
+a "safety" device is counter-effective. Sure, that may be the case, but
+you're designing a _course project_. Not a fucking body cares, idiot! Just
+add a 1604 LCD and you could stop worrying about those stupid points in
+the final weeks!
+
+Stupid thing #3: Rejecting a screen.
+
+### We did not use ESP32s
+
+You may have noticed that we mentioned ESP32s in our initial proposal, but
+we did not end up using any. Initially I considered the ESP32 because it
+had integrated Bluetooth Low Energy (BLE). But two reasons stopped me:
+
+- The BLE protocol is horribly complex and I didn't understand any of the
+ boilerplate code
+- It seemed we had to use the Nucleo board because that's what the course
+ was about
+
+So I admitted my first defeat and went for the Nucleo. Wireless was done
+over the XBee module, which is a breakout board you talk to via UART and
+it would transmit/receive your payload over 802.15.4. It's just like
+connecting the two MCUs with UART wires. I love it. And it turned out to
+be the part that I worried about the least in the later part.
+
+However I had a brainfart when I first configured them. I had to use
+a program that the XBee company made to flash the firmware, and I needed
+to give each XBee the serial number (like a MAC address but not quite) of
+its peer, but the program only allowed me to touch one XBee at a time. So
+I just typed the serial numbers in a text file. But I made a typo, and
+confused `0xc4db` with `0xc4bd`. This led to probably an hour of wasted
+time (which will turn out to be not the worst).
+
+Using a Nucleo is the best decision. I have no idea what demon would
+unfold if I insisted on the ESP32. I could possibly be the one doing all
+the work, because to my knowledge, my teammates had no prior experience
+with MCUs, so it'd be unrealistic for them to learn yet another tech stack
+(ESP-IDF). And I've never used it either.
+
+### Buying stuff (and getting stuff from the lab)
+
+Now that I'm about to bring up technical names, it may be helpful to
+present an annotated photo of our final product, just so that you know
+what I'm talking about.
+
+![Assembled PCB with an XBee, Nucleo, radar, LDR, expander, NFETs, and
+sockets](img/w24_wrapup/373_pcb_back.jpg)
+
+▲ Back hub
+
+![Similar PCB with no radar but an extra buzzer screwed on the
+board](img/w24_wrapup/373_pcb_front.jpg)
+
+▲ Front hub
+
+(Oh, the PCB, you ask? I designed it. It's the direct source of agony
+later on.)
+
+We had a budget of $50 per person (or $200 for our team of 4). Earlier
+Matt had suggested buying a Doppler radar to realize the vehicle
+detection, partly because he never used one and wanted to see how it was.
+
+Doppler radars (the red spoon-shaped board) are microwave devices, which
+means two things:
+
+- They are more penetrative than light and propagates through thin
+ non-conductive planes like plastic, which makes it possible to keep it
+ inside the enclosure for better water-proofing
+- They're black magic
+
+We asked Matt to buy one on Mouser for maybe $30 or 40.
+
+We got (I got) these tiny Nucleo devkits (L432KC) from the lab. I asked
+for two but neither of the first batch worked. So I asked for two more.
+Matt just gave me two brand new boards. Thanks Matt!
+
+We got (I got) the XBees from the lab. Instead of 2.54mm pitch headers
+they got 2mm ones (I don't understand why), so we got (I got) two adaptor
+boards so we could tack them in the breadboard.
+
+Later we ordered the buzzer because I was dissatisfied about how quiet
+(and how useless as a horn) the 3V piezo buzzer was. This one? It'll blow
+your ears off!
+
+### Early optimism & state synchronization over XBees
+
+I was like "yea im gonna absolutely nail this shit" and did extensive
+research. The idea was to have two "hubs" with an MCU in each. Then, you
+would wire up your LEDs to them. The two hubs communicate wirelessly.
+
+How the hubs communicate to synchronize their states took a bit of
+thinking. I personally think it's the most demanding part of the project
+software-wise.
+
+The essential idea is that each of the two hubs (or MCUs to be precise)
+maintain two states: its own, and its peer's. An input change (e.g. user
+lifted arm) directly changes its own state, not the output. The output is
+determined by both its own state and the peer state. Synchronization
+happens whenever a hub changes its own state, and involves an exchange of
+state over the air.
+
+Imagine two hubs: A and B. All blinkers are off, until user signals left
+on Hub A. Hub A transmits Message 1: `ack=0, peripheral=blink,
+state=left`. (actually this is encoded in a single byte as a bitfield)
+
+Hub B receives Message 1 and takes note that the left blinker of Hub A is
+on. Then it transmits Message 2: `ack=1, peripheral=blink, state=off`,
+which is Hub B's own state. The `ack` stands for acknowledgement; it means
+no reply is necessary. Before I implemented this, the two hubs would keep
+replying to each other forever.
+
+Hub A receives Message 2 and takes note of Hub B's state. At this point
+the state synchronization is complete, and each hub knows both states.
+(They are stored in global variables; our project is full of them. Without
+mutexes or semaphores. Living dangerously.)
+
+Inside each hub, the output function checks both states, and sees that one
+of them wants to turn on the left blinker; so it turns it on. Effectively,
+we can turn on both left blinkers by controlling one side.
+
+Turning off is the same but with `left` replaced with `off`.
+
+One potential issue is, we can't reasonably decide what to do if the user
+gives conflicting commands, like left on Hub A and right on Hub B. Our
+compromise is to just blink both ways, and hopefully the user will notice.
+
+Another interesting thing is that, hubs receive messages in interrupt
+mode, which means it can carry on doing other stuff while waiting for
+a message in the background. We wrote (I wrote) a callback function that
+runs every time we receive something over the XBee. We have a certain
+amount of polling for the switch and stuff, but it's inside of a timer
+interrupt handler. So it's the first embedded project I ever (co-)wrote
+with an empty loop inside of `main()`.
+
+### Checkpoint 1: March 15
+
+It was great to see your prototype working on a breadboard. We managed to
+control some LEDs with a switch in front of the instructors. They asked us
+what we planned to do with the accelerometers. We said (I said) we would
+detect the angle it is held up to relative to ground to trigger the
+blinkers, and deceleration along the "road" axis to trigger the brake
+light. Robert said we managed to eliminate most of the complexity of using
+an IMU (i.e. accelerometer). I asked if it's a good thing or bad thing; he
+said good.
+
+We expressed (I expressed) concerns about us running out of GPIOs on these
+tiny Nucleo boards. Matt replied that we had so-called GPIO expanders, so
+we got one later. It's a PCF8574, running on I²C, which allow
+multiplexing. We use I²C for the accelerometers anyway, so that means
+8 extra pins for free. I noticed that it's pretty unconventional in that
+there's no input/output mode selection; it's kinda scary actually.
+
+Because the output we need are mostly PWM, which is high-frequency, we
+only read GPIO inputs through the expander. This simplifies our driver
+code a lot. (The expander driver, which is 12 lines of code in the most
+permissive definition of code, is one of the few parts in the project not
+authored by me.)
+
+When we left their office, I felt content with our progress. I said:
+"We're gonna make this so even an idiot can use it." Upon which Robert
+replied, "oh, good, so even I can."
+
+A moderate amount of self-deprecation is a healthy communication trick,
+but my arrogance wasn't, especially when it led to me writing this whole
+fucking self-deprecating blogpost. Because you'll see the idiot, in fact,
+is me myself, and I can barely operate the device.
+
+We ordered some light sensors which arrived that day, but later the bag
+containing them was gone, so we ended up replacing them with LDRs (light
+dependent resistors) that did basically the same thing, and arguably
+better on a PCB.
+
+### Anna the Wasp Savior
+
+On 2024-03-17, a wasp got loose in the 373 lab (which may or may not have
+a causal relationship with the presense of a bunch of boy/girl scouts in
+the EECS atrium). I, like many others, was briefly terrified, but calmed
+down to think about a countermeasure.
+
+Anna Huang, the IA, stepped up in a heroic fashion to capture it. She
+grabbed a plastic cup and trapped it against a big box. I offered my
+clipboard and she managed to confine the wasp between it and the cup. We
+walked down the stairs, where I learned that she wasn't about to kill it,
+but to release it. When I asked her where, she initially considered in the
+atrium toward the scouts, but changed her mind and released it outdoors.
+
+She also asked me to take a photo and share it with her, which I did. In
+my final PCB design, I credited her as "IA & Wasp Savior: Anna Huang".
+
+### First Big Mad moment
+
+On 2024-03-17, I wrote the following on the project log.
+
+> Got stuck for 2 hours because
+>
+> - Amazon says the accelerometer is “LIS3DSH”
+> - The PCB says “LIS3DH”
+> - The chip is marked “DSH”
+> - LIS3DH accepts I2C addresses 0x18 and 0x19
+> - LIS3DSH accepts 0x1d and 0x1e
+> - The chip responds to 0x1d and 0x1e
+> - There is a read-only register on the chip called “WHO_AM_I” that’s
+> supposed to be 0x33 on DH and 0x3f on DSH
+> - I read it
+> - It’s fucking 0x3b
+>
+> 17:52: I GOT IT WORKING ON THE BIG NUCLEO WHAT THE FUCK IS DHAPPEBING
+>
+> 18:05: OK this is fucked up
+>
+> On the datasheet it says you’d append 0 to the I2C address if you’re
+> writing and 1 if reading
+>
+> ITS WRONG
+>
+> I just flipped these and it fuckijng worked
+>
+> [in huge font size] FUCK YOU ST
+
+In case the text above didn't make enough visual impact, here's what it
+looks like:
+
+![A page of text ending with a giant "FUCK YOU
+ST"](img/w24_wrapup/373_fuck_you_st.png)
+
+### Enclosure & connectors
+
+My teammate and I took a moment to discuss how we wanted to assemble our
+product, and especially how it looks from the outside. I proposed that we
+expose two sockets, on the left & right, for the accelerometers. I forgot
+how the rest of the conversation went, but it involved searching the whole
+lab for vernier calipers. There was none. We ended up using
+a one-meter-long blackboard ruler for a fucking 7x10 cm board.
+
+Earlier in our proposal we mentioned a modular design, where everything is
+hot-pluggable. Halfway through the project, this target began to seem
+unattainable, so we had to make some of them, like the radar and buzzer,
+integrated on the circuit board, be it protoboard or PCB.
+
+3D printing was never my forte, so my teammate is resposible for modeling
+and printing. She did an impeccable job. One problem was that the PLA they
+printed our enclosure with was yellow. Our LEDs are also yellow.
+
+She was like "it's ok, we can tape over the front surface" and she was
+right.
+
+She also laser-cut acrylic with screw holes to hold our circuit boards in
+place.
+
+I planned to use dupont sockets for the accelerometers. STUPID FUCKING
+IDEA. Dupong sockets are good for prototyping, and that's it. There's
+a REASON why you don't see them everywhere. There's a REASON we have
+different cables.
+
+Stupid thing #4: Not using a proper connector.
+
+### Buying more stuff & putting them together
+
+We bought some more stuff.
+
+- Reflective jacket w/ two armbands
+- Velcro
+- Superglue (despite lab rules _technically_ banning them due to
+ insufficient ventilation i dunno bro we got solder irons running full
+ blast here i could inhale this all day (I did inhale this all day
+ later))
+
+In a genius supernova, my teammate(s?) discovered the art of velcro on
+everything. We attached (they attached) the accelerometers to the armbands
+with velcro. It worked fine (mostly).
+
+### Fire alarm!!
+
+On 2024-04-03, at precisely 13:11, the alarm went off so I packed and
+left. Went for a much-needed lunch.
+
+Two days later I bought a bicycle, partly because of this project.
+Spoiler: it wasn't that much useful.
+
+We also demo'd checkpoint two to an IA. We were behind schedule but
+I didn't think it was a big deal. It _was_ a big deal.
+
+### LDR, stupid thing #5, and brainfart #2
+
+My teammate worked on the LDR. Its resistance depended on ambient
+brightness and all you need to do to read it is to wire it up in series
+with a fixed resistor and ADC the voltage between them. We had a lab for
+that.
+
+I found a problem with the implementation: it slowed down the blinking
+considerably. It was because the Nucleo would do an ADC every time we
+enter the output function, which runs every millisecond, and each blink is
+400 ms. ADC takes time and they add up. At this point I knew what problem
+we had. I focused on writing code on my own, without explaining to my
+teammates what I intend to design it. Of course, it led to relatively
+clean code, but it was worthless if nobody understood it.
+
+There are two states of team project code that are acceptable to me:
+
+- Tightly coupled monolith, but everyone understands every line
+- Each person is responsible for one part only, but interface is clearly
+ defined
+
+Our project was neither. It was tightly coupled and almost completely
+authored by a single person. In hindsight, this was catastrophic. It meant
+that in the later part of the project, when time is running out, I was the
+only one who could make software fixes. The core reason is the lack of
+regular team meetups. I sometimes see all four or at least three members
+of certain teams in the lab or in the basement of the Duderstadt. Our
+team, on the other hand, has never had a meeting where everyone was
+present except the brainstorm discussion, the presentation, the evening
+before the demo, and the demo.
+
+I should have motivated my teammates to meet up at least once every week.
+I should have had the motivation to motivate my teammates.
+
+Stupid thing #5: Not meeting regularly.
+
+When did this blog become a landmine of stupidity to embarrass my future
+self? Anyway.
+
+I had a brainfart again. The LDR had higher resistance when it's dark, and
+if we tie one end to VCC and the other end through a 2.2k fixed resistor
+to GND, then less light would give us a lower ADC reading, and if so we
+decrease the brightness of LEDs. Problem was, if the LDR disconnects from
+the circuit (which may happen on a bumpy road), the ADC drops close to 0,
+even if it's the middle of the day. My teammate's workaround is to detect
+if the ADC drops below a certain threshold, at which point we assume the
+LDR dropped out, and fallback to maximum brightness.
+
+My smartass was like, why this complicated? Just reverse the LDR and the
+2.2k, problem solved!
+
+She was like, no…? If I reversed them, then the ADC reading would also be
+upside down, because LDR dropped out == infinite resistance, which would
+be naïvely interpreted as no light either way. So I admitted I was wrong.
+
+### Presentation
+
+A minor part of the project is a presentation, comprised of a pitch that's
+no longer than 30 seconds, and two minutes of slides per person. I skipped
+a lecture to meet with my teammates. A lack of tables prompted us to go
+outside near the swings. It seemed impossible to read the pitch in 30
+seconds so I cut some sentences. I was very much not stressed at all.
+
+Robert used a D4 to randomly pick a person to do the pitch, and he rolled
+a 1, which happened to be me, who stood on the left hand side of the
+classroom. I did it in probably 20 seconds. Nice.
+
+The presentation was quite successful; I did at least one joke about how
+breadboards on bikes make your distributed system a very distributed
+system.
+
+### PCB
+
+On 2024-04-07, according to the project log, I would "now begin working on
+a pcb." A week later, on 2024-04-14, the PCB was "taking shape". The next
+day, I finished and ordered it from PCBWay. But it was already too late.
+
+I have no idea why I did not finish the PCB sooner. It's just plain
+stupid. I should never have trusted the "3-4" days shipping. Production
+took probably one day and a half; shipping was another story. I was too
+optimistic about global shipping. I modeled it as a sphere on an ideal,
+frictionless plane. In reality it's stuck in Shenzhen, stuck in
+Cincinnati, stuck in Romulus.
+
+![DHL shipment updates](img/w24_wrapup/373_dhl.png)
+
+I needed it for demo day; I got it the afternoon after demo day.
+
+Stupid thing #6: Not ordering the PCB sooner.
+
+But at least I had fun designing the PCB, so let's talk about it.
+
+![Front and back of PCB, rendered in KiCad](img/w24_wrapup/373_pcb.png)
+
+The board shape features a notch, just because we can. Take that Apple!
+
+The screw holes align with those on the acrylic my teammate laser cut.
+
+To avoid interfering with microwave black magic, I intentionally shoved
+the antenna part of the radar over the board edge.
+
+We added a couple NFETs in the power paths of some components, including
+the expander and the radar, because they have a criminal record of
+freezing for no reason, rescued only with a hard power cycle.
+
+The silkscreen features two memes:
+
+- "This side toward enemy", stolen from meme below
+
+![An AT&T network interface device, scribbled "this side toward enemy" in
+all caps with a chisel-end
+marker](img/w24_wrapup/373_this_side_toward_enemy.jpg)
+
+- PCBWay, adapted from a meme I made long ago (🎜 just like the hearse you
+ died to get in again 🎜)
+
+![Photo of Gerard Way on a PCB silkscreen, with a blurry "PCBWay" logo
+below for full meme effect](img/w24_wrapup/373_pcbway_meme.png)
+
+Additionally it features the name of everyone in our team, our
+instructors, GSI, and IAs. I feel it is necessary to pay credit to
+everyone who helped. Also you paid for silkscreen you gotta use silkscreen
+
+In terms of timing, I fucked up.
+
+In terms of design, I regret nothing.
+
+### Protoboard (NOTE: avoid at all costs!)
+
+I would pick soldering ten PCBs over one single protoboard. It's just PCBs
+with all the pain and none of the benefits.
+
+Parts? Manual. Wires? Manual. I would NOT like to remember it, no thank
+you. The last time I ever touched a protoboard was in 2022, so
+I apparently forgot how painful it was. A PCB was definitely worth it. So
+why did we solder the protoboard anyway? Well, see stupid thing #6. fml
+
+If I had done the PCB sooner, I could have avoided the protoboard. If
+I just committed to the protoboard (bad idea), I could have avoided the
+PCB work (and money; I hope it can be reimbursed). But I missed the
+chance, and now I had to do both.
+
+Incidentally, this coincided with my obsession with _OK Computer_ (1999),
+notably the track "Let Down".
+
+Project log, 2024-04-19 10:52:
+
+> Woke up to DHL’s email that the ETA of the PCB is Tuesday by end of day.
+> ffs really reconsidering the point of living at this point. Day ruined
+>
+> Backup plan: I’m gonna head to the lab these days and solder up the
+> protoboard with pin sockets, so all the expensive shit are removable.
+
+Devastated, I told my teammates what I did. I was the one who fucked up,
+so I had to take full responsibility. I sat in the lab with my Pinecil,
+and soldered up one (1) board.
+
+Project log, 2024-04-19 22:53:
+
+> God is dead and it was I who killed him with my Pinecil® soldering iron
+> running on 65W USB-PD as I soldered BicycLED on the protoboard
+>
+> This is the worst shit imaginable. Imagine being late by exactly one day
+> and having to devote 2x more work and endure 10x more stress than a PCB.
+>
+> I have to take full responsibility of the PCB not arriving on time, and
+> I am paying the toll with probably one year of my life expectancy for
+> the lead and rosin inhaled today. At my funeral, in lieu of flowers,
+> send fume extractors.
+
+My teammate (the one who did the 3D printing) joined me. I can't thank her
+enough. We spent entire evenings in the lab, just working our asses off.
+The worst part is that, our work is of no worth other than to not miss
+demo day.
+
+Those nights I had _really_ bad insomnia. Like three hours of dread and
+horror. Pressure did not kill me, but I wished it had.
+
+This was the result:
+
+![Protoboard with a bunch of parts soldered on
+it](img/w24_wrapup/373_protoboard_parts.jpg)
+
+![The back side. Bunch of wires, real
+abomination](img/w24_wrapup/373_protoboard_wires.jpg)
+
+### Fuck it
+
+How the fuck have I written 6k words already?? This is way too long for
+a blogpost. If you're still reading you should go for a glass of water or
+something.
+
+### FUCK YOU ST / FUCK YOU NXP
+
+On 2024-04-11, we were working on the lab computer and found a bug where
+it doesn't regenrate template code when we modify the configs. This led to
+the second fuck you in our project log.
+
+> [W]e moved the buzzer to TIM16. But the `TIM_HandleTypeDef htim16`
+> wasn’t showing up, and the GPIO macros for BUZZER remained unchanged.
+> I restarted the IDE, but it refuses to update code no matter how many
+> times I hit “generate code”.
+>
+> I zipped the project and imported it into my machine. It worked
+> instantly.
+>
+> [in huge font] FUCK YOU ST
+
+On 2024-04-21, we were honored to present the third fuck you.
+
+> [Redacted] and I went ahead and soldered the second board with
+> insurmountable pain. But the PCF8574P we got last time did not work.
+> When we hooked up a logic analyzer, it never acks.
+>
+> I noticed that the two chips we have are different. The first one that
+> works is TI; the other is NXP. However, their datasheets are practically
+> the same.
+>
+> I wrote a loop to iterate I2C addresses from 0x20 to 0x80. It replied to
+> 0x38. According to the datasheet, this address belongs to PCF8574A, but
+> the chip we have is marked PCF8574P, the DIP-16 package of PCF8574,
+> without the A.
+>
+> [in huge font and bold face] FUCK YOU NXP
+
+oh wow I went full linus mode
+
+### Final evenings
+
+Things that happened the evening two days before demo day:
+
+- All four of us showed up (surprise surprise)
+- We attempted to power the circuit with 12V on VIN
+- Why is it so hot??
+
+Stupid thing #7: Not testing power earlier
+
+- It turns out if you power the Nucleo with 12V (max voltage), the MCU
+ gets really hot which shouldn't happen if you have a good voltage
+ regulator
+- We tried USB VBUS on the 5V pin next to VIN
+- The MCU just straight out doesn't work
+- ????????
+- Quick, get a buck converter
+- It's bulky
+- Teammate: Fuck it, just power it over USB!
+- Me: No… ok fine
+- Uh oh, we have to make a hole in the lid
+
+Things that happened the evening just before demo day:
+
+- Teammate: Hey here's a lid with a hole I just laser cut
+- Oh look a perfect fit
+- WHY IS EVERYTHING FAILING EVERY OTHER SECOND???
+- OH GOD OH FUCK SOLDER UP A RESET BUTTON
+- MORE VELCRO!!!
+- OK we did it!
+- Me: Let's install it on my bike!
+- [I bring my teammates to my bike and attract a raccoon]
+- We install stuff
+- It kinda works but wonky
+- Fuck it let's not
+- Take everything off, decide to present them on a table instead
+- What about the poster?
+- Teammate: Oh yeah the poster. It's at my apartment. There's a blank
+ space called "assembled product" which we can finally patch
+- Me: yeah let's print it
+- [We go to the color printer at the Duderstadt and print the pictures]
+- Me: hey let's print the project log it's got three big fuck yous it's
+ funy
+- [I did not wait for their approval]
+- The cover:
+
+![BicycLED project log. Warning: explicit language. (parental advisory
+explicit content sticker typically seen on
+records)](img/w24_wrapup/373_log_cover.png)
+
+The bicycle:
+
+![Two clunky boxes barely holding on
+a bicycle](img/w24_wrapup/373_bike.jpg)
+
+### Demo day. Fucking finally
+
+We were glad it was over. We're just… so done, literally and
+metaphorically. Not sure about how other teams were doing, but we were
+dying of boredom.
+
+I got there early and tested out the stuff we had. The accelerometers
+were… still wonky. Then a few wires came off after we set up the table.
+Never would have happend if I had used a proper connector that stays in
+place. Glad I took my Pinecil with me. The faithful iron fixed like three
+faulty wirings. Truly the MVP of the day.
+
+I skipped two lectures for the demo. The professor whose lecture I was
+supposed to be at (💀) showed up and was one of the first to check out all
+the exhibits. He's my 311 (analog circuits) professor. "There's BJTs in
+here. You would be proud," I said.
+
+"I'm already proud of you," he replied.
+
+Then it was time to do two things:
+
+- Avoid attracting attention, and in the case we failed, explain to the
+ curious person what our project does (spoiler: not a lot)
+- The graded demo
+
+We missed a chance to do the graded demo once, because I was fixing the
+wires. Once we got the chance to get the GSI back, we demo'd all the shit
+we did. He was like "huh cool" and scribbled some notes on his clipboard.
+
+Later the instructors came and to our horror the accelerometers failed.
+(tbf they intermittently failed regardless of who we're presenting to.)
+I pressed the reset button a few times hoping they didn't notice, and it
+finally worked once (probably a false positive). Then Matt grew interested
+in the Doppler radar. He tried to trigger it by moving his body in the
+vicinity of the radar. We had set the threshold to the highest possible to
+prevent false positives (it was still sensitive af), to the point the
+buzzer only honks if you're moving within a few centimeters away from the
+radar. We figured as long as it's for a demo, it'd be fine. And it was
+fine. It didn't honk all the time. It honked some of the time. And that's
+good enough.
+
+Like, the project was a failure, so what? There's nothing I could do at
+this point. I really hope we didn't disappoint the instructors. Not as
+much as I disappointed myself.
+
+I was so done with everything. I pulled up the 473 (advanced embedded
+systems) slides and read them to pull me out of this torture.
+
+We wrapped up all our stuff at 14:00 at the first convenience so we can
+say goodbye to this crap.
+
+### PCB (the sequel)
+
+The moment I came back home, I saw the PCB lying at my door.
+
+The next day I went to the lab… I soldered it with my teammate… Then a few
+days later I demo'd it to Matt. I made an excuse that the accelerometers
+were fried (they probably were, but I was too lazy to check). He sent
+Robert an email that the PCB in our report is a real thing that exists.
+
+Then we took (I took) the project apart and returned the public assets
+back into their respective bins. You won't believe how many USB cables we
+used for the Nucleos, logic analyzers, XBee configuration dongles, etc.
+
+Then it's just a matter of submitting a bunch of end-of-project stuff like
+our code and my PCB design files. And the report. In the report we're
+asked to estimate our complexity points. The goal is 4 (1 for every
+person). Here's our estimate (based on a reference the instructors gave us
+early on):
+
+> - Accelerometers: 0.67
+> - Light sensor: 0.25
+> - Doppler radar: 0.25
+> - XBee: 0.50
+> - Synchronization protocol: 0.50
+> - PWM + Transistor: 0.25
+> - PCF8574P/AP: 0.50
+> - 3D printing & laser cutting: 0.50
+> - PCB & protoboard: 0.67
+> - Total: 4.09
+
+This was based on my teammate's estimate, and I adjusted it while keeping
+the sum over 4. The Doppler radar doesn't actually deserve that much
+complexity; it's just two GPIOs. Infineon did all the analog magic for us
+(which disappointed Matt, who thought it would at least expose some of the
+non-microwave signals for us to do some Fourier with).
+
+The PCFs weren't this complex either. Probably 0.33 at best.
+
+Oh, yeah, and my insomnia is healed.
+
+### Mistakes (again)
+
+I finally dumped everything I want to say about this cursed project of
+ours. Now, let us recap my mistakes.
+
+- I am a poor collaborator
+- Taking too many time-consuming courses
+- I did not ask my team to reach a consensus before beginning work
+- An incorrect, idealistic idea about course projects
+- Not using a proper connector
+- Not synchronizing progress with teammates often
+- Not testing power and heat dissipation early on
+- Designed and ordered PCBs too late
+
+So, to address the problems, all I need to do is:
+
+- __Design everything early__
+- Don't take more than 2 EECS courses per semester
+- Meet with majority of team once per week
+- Discuss project goals
+- Clarify every detail about project goal; when in doubt, leave a note or
+ mark as TODO
+- Use a proper connector for everything
+- Test in real environments as soon as possible
+
+### Final word on project
+
+I take the L.
+
+That said, I still sulk over this course. I feel that I did not release my
+full potential. Indeed, it is hard to compete with other teams of four in
+a team of an effective size of 2.5. But only losers blame teammates.
+Victors blame themselves, fengshui, and the phase of moon. I believe the
+solar eclipse may be part of the conspiracy.
+
+## Verdict
+
+Good course, but don't take it with 482. Useful if you want an extensive
+set of knowledge, so that when you need to make some hardware you know
+where to start. The course is not enough to make anything that would
+instantly sell though. That would require expert knowledge in industrial
+operation, market touching, and probably a lot of money.
+
+I re-emphasize that my experience with the project is not representative
+of the typical 373 experience.
+
+## Future?
+
+Halfway through writing this blogpost, I tooted
+
+> tfw you fucked up a project so bad you're writing a blogpost about the
+> mistakes you made and you're at the 6,458 words mark
+>
+> the #1 advice to not fuck up projects is to not do projects. thanks for
+> coming to my ted talk
+>
+> that said i voluntarily signed up for a project very similar in
+> logistics next semester because i have a habit ofovercompensating [sic]
+
+Yes, I enrolled in 473. I only plan to take a maximum of 15 credits next
+semester, and will drop 3 if my IA application is accepted. This should
+make workload reasonable.
+
+Mark Brehob will be teaching 473, with Matt Smith still being lab
+instructor, which is great news because they're both great and I know
+both of them. But probably everyone does.
+
+And now that I have a bicycle, I can ride to north campus whenever I want.
+
+I already have like two ideas brewing in my head. I will look for
+teammates myself based on project interest this time. I really hope it
+doesn't bust again.
+
+Damn it, "Let Down" just came on again. Better wrap this up before the sad
+part.
diff --git a/docs/umich/w24_482.md b/docs/umich/w24_482.md
new file mode 100644
index 0000000..5fb6d2b
--- /dev/null
+++ b/docs/umich/w24_482.md
@@ -0,0 +1,356 @@
+# Winter 2024 Course Review: EECS 482 (4 credit)
+
+2024-04-30
+
+Course Title: Introduction to Operating Systems
+
+Rating: 4/5
+
+## Instructor (Brian Noble)
+
+Pros:
+
+- Talks clearly
+- Has a schedule
+- Lots of interesting stories so you learn something even if you fail 482
+ (see [Trivia](#trivia)
+
+Cons:
+
+- Practically none?
+
+## What did I learn?
+
+Course topics:
+
+- Threads and concurrency
+ - Mutexes & condition variables
+ - Semaphores
+ - CPU scheduling
+- Virtual memory
+ - Address spaces
+ - Page tables
+ - Page replacement (swapping)
+- Filesystems
+ - inodes
+ - Consistency after crashing
+- Network
+ - Sockets
+ - Client-server model
+ - Distributed systems
+- Miscellaneous
+ - RAID
+ - LFS (log-structured filesystem)
+
+Brian constantly brought up the five tools of computer science:
+
+1. Caching
+2. Hashing
+3. Indirection
+4. Replication
+5. Encryption
+
+482 discusses 1 and 3 in great detail, 2 and 4 occasionally. The
+philosophical takeaway is:
+
+- Whenever you have something to protect, add a layer of indirection (e.g.
+ using virtual addresses for user programs)
+- If there's too much data to copy, also use indirection
+- It can't be indirection all the way down; there must be something fixed
+ by convention (e.g. the first sector being the bootloader)
+- If indirection gets slow, add caching
+- If you want consistency, use replication (e.g. RAID with redundancy)
+
+The course is all about abstraction:
+
+- Threads are abstractions for CPUs
+- Virtual memory is an abstraction for physical memory
+- Filesystems are abstractions for disks
+- Sockets are abstractions for network interfaces
+
+Part of abstraction design is to provide user programs with the illusion
+that resource is infinite. A process can spawn thousands of threads on an
+8-core machine, and they take turns to execute, thanks to the OS
+scheduler. Of course, at some point the context switching overhead
+overshadows the benefits of parallelism, but you _could_.
+
+Another job of the OS is to protect a program from other programs. You
+can't trust user programs. Therefore you must build a layer of abstraction
+so that the user program can never "control" the machine. The three things
+a user program is allowed to do:
+
+- Touch its own property, e.g. address space, open files
+- Touch property that another process explicitly shared with it
+- Transfer control back to the OS with a syscall
+
+The point is that the OS is an absolute tyrant. A user program can never
+run for as long as it likes, nor can it touch anything other than what
+it's explicitly allowed to. To achieve this, the OS conspires with the
+hardware so that it can intervene when certain things happen:
+
+- Every few milliseconds, the timer interrupt fires, transferring control
+ over the CPU to the OS
+- The program issues a load/store marked unreadable/unwritable, and the
+ MMU triggers a page fault, also handled by the OS
+
+Although the timer and the MMU are technically part of hardware, they
+always hand over control to the OS. They're part of the abstraction.
+Without the timer, it would be up to a user program to give up the CPU,
+which makes it really easy to freeze a machine. Without the MMU, user
+programs would use direct addressing, enabling anyone to tamper with
+anyone's memory.
+
+However, the OS can bypass either restriction, and it is the only one
+allowed to do so. When a timer interrupt fires and hands control over to
+the OS, the first thing the OS does is to disable the interrupt, so the OS
+itself gets to run for as long as it likes. Once its job is done, it
+re-enables the interrupt, and hands control back to a user program (may
+not be the same one). We don't give user programs the ability to control
+interrupts; not MMU either.
+
+We just discussed the first half of the course. The second half was less
+mind-bending and more optimization trickery with "make the common case
+fast" heuristics. However we did make a big deal about consistency.
+
+The disk only guarantees block writes are atomic. Therefore, if you need
+to write two blocks to disk and you lose power halfway, you could have
+written zero, one, or two blocks. That basically means you just lost two
+blocks of data, because you're unsure either block is the right version.
+Worst case is you end up breaking essential metadata, which corrupts the
+entire filesystem.
+
+We can play clever tricks like careful ordering of block writes so the
+last block we write "commits" the changes. But when this is not possible,
+due to cyclical dependencies, we came up with the notion of journaling,
+which doubles the cost of writes because we always keep a copy of the data
+we're writing in the journal until we're sure these data made it where
+they belong. Where is the journal? On disk. At this point I was convinced
+that disks just suck. We're paying 100% overhead just to handle the 0.001%
+chance that the machine crashes. But to deliver the "persistent storage"
+promise, we have to pay that cost.
+
+The disk is just a big pool of zeroes and ones — and as such there is no
+way to distinguish a block of metadata and a block of data. You have to
+allocate a static location as the "boss of metadata"; for example, writing
+the root inode to block 0, from which we can discover every descendent, as
+we did in project 4.
+
+### Personal reflections
+
+The reason why I enrolled in the course is all my friends did it. It was
+taught by Manuel, one of the "signature" professors we had at JI,
+Shanghai. It's one of the most challenging courses there ever was, so
+being the arrogant boy, I took it. Peer pressure except it was me who
+pressured myself into taking it.
+
+The most mind-blowing chapter, also the one I once had the most incorrect
+understanding about, is virtual memory.
+
+Rewind to 2021, when I was taking VG151, intro to CS. I had no idea what
+virtual memory was, and was amazed that `malloc` always handed me roughly
+the same address every time, beginning with `0x7fff` or something, as if
+that part of the RAM was always free. I had mistakenly thought that all
+processes share one big heap on the physical memory, and `malloc` had
+a global table of free chunks. It does not. Each process has its own
+address space, and the user program does not know, nor does it care, where
+it lives on physical memory.
+
+The MMU also explains a gap in my brain. Prior to this course, I thought
+the OS would translate memory addresses of a program before it ran (which
+is not possible because you can dynamically allocate memory). Now it
+became clear that there is a dedicated piece of hardware that does the
+translation.
+
+## Projects
+
+Project 1 is solo, 2-4 are done in a group of two or three; mine was
+three. We were enrolled in the 4-credit version of 482, which means we're
+only required to do the core version, which is supposedly less work.
+
+We met Mondays and/or Wednesday mornings at 10 AM at the Duderstadt. It
+was a great excuse to spend money on muffins and coffee at the cafe.
+Nearly every time we sat at the same table with a giant screen. There was
+an HDMI cable but it doesn't work. I ended up opening a Zoom meeting.
+
+Of the three autograders I've used at UMich, this is the least visually
+interesting one, besides only allowing one submit per day with feedback,
+plus three bonus submissions for each project.
+
+![Plain HTML website titled "Project
+4 submission"](img/w24_wrapup/482_submission.png)
+
+It does fit in the brutalist aesthetic of the website.
+
+![Plain HTML website with very little CSS and an embedded google
+calendar](img/w24_wrapup/482_website.png)
+
+### Project 1: Multithreaded disk scheduler
+
+Given mutexes and condition variables, build a disk scheduler.
+
+Not that hard, took me a few tries to get used to the paradigm of
+signaling _after_ work is done.
+
+### Project 2: Thread library
+
+We built our own threads, mutexes, and condition variables. We also get to
+decide what happens in a timer interrupt.
+
+The hardest part was taking care of all the `ucontext_t` objects, which
+can't be moved because they contain pointers to themselves. We had trouble
+keeping track of which stacks and which `ucontext_t`s we could delete,
+because the lifetime of the `thread` object is unrelated to that of the
+thread's execution flow. We ended up playing pointer tricks, which is
+basically shared pointers with extra steps.
+
+Here is a snippet of code I wrote at 2024-02-20 00:30:
+
+```
+void thread::delete_context(ucontext_t *context) {
+ auto it = cpu::self()->stacks.find(context);
+ assert(it != cpu::self()->stacks.end());
+ // delete stack of thread that previously died
+ // like burying your sibling's bones
+ // pour one out for the binary spirits
+ // freed from deallocated homes
+ delete[] cpu::self()->stack_to_delete;
+ // we cannot simply delete the stack
+ // of the thread that is running
+ // for a ghastly segfault taketh us aback
+ // with a coredump equally alarming
+ cpu::self()->stack_to_delete = it->second;
+ cpu::self()->stacks.erase(it);
+ delete context;
+}
+```
+
+Another design mistake is how we used the `ucontext_t` pointer in the
+mutex as a unique identifier for threads. It turns out the instructors
+were so cunning that they managed to make our library allocate
+a `ucontext_t` exactly where one was just deleted, tricking our library
+into thinking the new thread owned the mutex. I still have a hard time
+believing it was possible. They probably overloaded `operator new` on
+a modded version of `ucontext_t`.
+
+I was very involved in project 2; I wrote more than half of the code, and
+thus knew it like the back of my hand.
+
+### Project 3
+
+Virtual memory pager. Manages memory address translation, paging, and
+swapping. Lots of data structures needed, even a state diagram.
+
+I grossly underestimated the complexity. The first time I read the specs,
+I was like, "pfft! single level page tables?" But it was the hardest
+project for me.
+
+Unlike project 2, project 3 had much less effort from me. All I did was
+draw the state diagram and propose the data structures and their names.
+Then I got consumed by 373 and the workload shifted to Samuel who
+basically did it all on his own. Therefore I don't understand it as
+thoroughly as project 2. By the end of project 3 I was completely lost.
+
+The data structures were a complete mess. Here is a list of structs we
+defined:
+
+- `shadow_table_entry_t`
+- `filename_block_t`
+- `page_occupant_t`
+- `file_occupant_t`
+- `swap_occupant_t`
+- `page_status_t`
+
+which are distinct and redundant in a chaotic way. It's a miracle we
+passed all the test cases.
+
+The lack of involvement resulted in a relatively poor understanding of the
+pager, so I devoted more energy to project 4.
+
+### Project 4
+
+Network filesystem. Listens on a TCP port and handles concurrent
+read/write/create/delete requests from clients.
+
+I think I did a pretty good job at factoring out just the redundant code
+while handling special cases in respective functions. Fortunately we just
+have four request types (endpoints) to handle, so a little redundancy is
+ok.
+
+My least favorite part of this project is how strictly we had to enforce
+the one request string format. The request string is delimited with _one
+space_. No leading or trailing whitespace. All this while claiming that
+parsing is "is amenable for processing by `istringstream` (e.g.,
+`operator>>`)". My sibling in heaven, `istringstream` is not the one you
+want if whitespace is significant. I ended up using regexes, because it's
+preferable to having to read one character at a time while constantly
+checking whether you've exhausted the string stream. I regret nothing.
+
+Project 4 was the first time I actually used RAII in a productive way.
+Because every filesystem access is a traversal down a tree, and we want to
+prevent race conditions, every descent requires that we grab a lock and
+release a lock. Some are reader locks and some are writer locks. This is
+cumbersome to manage manually, so I wrote an RAII wrapper that keeps track
+of what locks we are currently holding and what type of locks they are. At
+the end of the object lifetime, the destructor simply goes over the list
+and unlocks them one by one. If we call a function that needs to
+lock/unlock, we simply pass the wrapper by reference. Easy!
+
+I'm not sure if this is healthy, but I cringe whenever someone optimizes
+code to "fit the scenario at hand". In the early stage of the project,
+I wrote a function called `alloc_block()`, which takes void and returns
+the block number just taken out of a pool. Later we realized that if an
+operation needs two allocs, but failed in between, then the first one
+would never be freed. We thought it would be better if we could atomically
+alloc two blocks, so I suggested my teammate to generalize the function to
+take one optional parameter and return potentially more than one block.
+
+When the function was reimplemented, I found that it was not quite what
+I meant. I was thinking something along the lines of
+
+```
+std::vector<uint32_t> alloc_block(uint32_t count = 1);
+```
+
+What it ended up being was
+
+```
+std::pair<uint32_t, uint32_t> alloc_block(uint32_t count = 1);
+```
+
+which returns the allocated block # in the _second_ element of the pair if
+`count == 1` (because it kinda fits our semantics better), and returns two
+valid block #s if `count != 1`.
+
+I feel uncomfortable that `count` did not function as advertised; it
+behaved more like a bool. But since we're using our late days (it's the
+first time I ever used a late day) and we're tired, I let it slide.
+
+## Verdict
+
+Now that I've taken the course, done the projects and sit through the
+exams, I do not regret taking this course. I do, however, regret taking it
+with two more workload EECS courses, one of which (373) is also
+heavy-workload.
+
+I would recommend Brian Noble to anyone, no questions asked. He is my GOAT
+professor of the semester. The slides follow the
+motivation-solution-problem-remedy train, which tightly model the actual
+evolution of real systems in the e.g. 1980s. It's interesting to know what
+came before modern systems and what Linus Torvalds et al. needed to take
+care of when they crafted the revolutionary kernel.
+
+## Trivia
+
+Brian always has stories to tell. My favorite story is how when he was
+young, his advisor talked to him about his unnecessarily complex wording
+in his paper. I personally do believe the doctrine, "why many word when
+few word do trick".
+
+Later on a lecture on log-based filesystems, he had a callback to the
+story. He goes (paraphrased):
+
+> What I lament about project 2 is, the right way to identify who owns the
+> mutex is to add something to your data structure. But you never do that.
+> What you do is you add another map. So what you end up with a lot of
+> suprooflo- su- sur- (waves hand) I can't say it. Uhh… extra. My advisor
+> would be happy about that. Extra maps.
diff --git a/docs/umich/w24_wrapup.md b/docs/umich/w24_wrapup.md
new file mode 100644
index 0000000..386f374
--- /dev/null
+++ b/docs/umich/w24_wrapup.md
@@ -0,0 +1,194 @@
+# Winter 2024 wrapup
+
+2024-05-05
+
+My second semester at UMich is just over, and I will recount major things
+that happened. I will continuously update this blogpost.
+
+## Course reviews
+
+The biggest mistake that I made is that I elected three EECS courses, two
+of which are extra heavy in workload. The rest are not trivial either. It
+is impossible to cover all of them in one single blogpost, so I will split
+them up into individual articles, listed below.
+
+- [EECS 482, Intro to OS](w24_482.md)
+- [EECS 373, Intro to Embedded System Design](w24_373.md)
+- [EECS 311, Analog Circuits](w24_311.md)
+- Other courses WIP
+
+## Notable material gains
+
+- A 20 oz thermo flask, as a gift from the School of Information for
+ participating in the 10-week accessibility challenge last semester
+- A bicycle, as described in [2024-04-05](../random/2024-04-05.md). Easily
+ the best investment this semester.
+- A MIDI keyboard (AKAI MPK mini play) with which I made a few loops
+- A MCR-themed zine I took at the Duderstadt gallery (it said "take one")
+- Two CDs: Blurryface (2015) and Scaled And Icy (2021).
+
+More on the CDs: Blurryface is for myself, SAI is for a friend. I rode
+downtown to four record stores in one day and bought them in the third and
+fourth, respectively. The first store had SAI listed online, but they sold
+out recently. The second store sold mostly vinyls. In both the third and
+fourth, I took the last tøp CD in stock, so I can't really blame the
+person who did it in the first store.
+
+The four stores are
+
+- Your Media Exchange, 319 S Main St
+- Underground Sounds, 120 E Washington St
+- Encore Records, 208 N 4th Ave
+- Wazoo Records, 336 S State St
+
+All in downtown Ann Arbor. I've been to YMX last year, and I found some
+rare items in the tøp vinyl section like the Location Sessions for record
+day. I don't have a turntable, so I left them for people who do. This time
+it's gone, along with many more. Whoever bought them has great taste.
+
+## Notable losses
+
+- My sanity over the 373 project
+
+## Notable expenditures
+
+- $39 for the MIDI keyboard (I outbid a swarm of ebay bots by one second)
+- $512 for the Boston trip
+- $90 for the bicycle
+- $187 for a ticket to tøp's Clancy Tour (ffs fbr)
+
+## Notable experiences
+
+- I visited my friend in Boston over spring break.
+ - I saw The Museum of Fine Arts
+ - I saw The Museum of Bad Art
+ - By law of the excluded middle, I saw all art in existence
+ - I took a lecture on Chinese policy at Harvard
+ - I took a lecture on computer systems in the auditorium by the
+ so-called Banana Lounge at MIT
+ - I took the MBTA subway
+ - I saw a weird MIT exhibit with a bunch of glass, lamps, and wood
+ rescued from a bathhouse on fire
+ - I went to the MIT museum
+ - I talked with W1ATO over the W1XM repeater
+ - I went to the Harvard art museums is basically a tub for rich people
+ to dump their art in and as an excuse to exhibit stolen shit
+
+Quiz time!
+
+Which two of these paintings are from the Museum of Bad Art, and which two
+are from the Harvard art museums?
+
+![Four paintings. 1: a tabby cat resting paws on a basket of fruit. 2:
+a frowning lady drawn with crude lines. 3: a bald child with blurry facial
+features. 4: a frowning lady with a rodent-like thing on her
+head.](img/w24_wrapup/boston_art.jpg)
+
+<details markdown="1">
+<summary>Click to show the answer!</summary>
+1, 4: Museum of Bad Art
+
+2, 3: Harvard art museums
+</details>
+
+- I went to an iDKHOW show in Detroit, as described in
+ [2024-04-05](../random/2024-04-05.md).
+
+![Dallon Weekes singing and playing a red bass](img/w24_wrapup/dallon.jpg)
+
+- I watched the eclipse (98% partial in Ann Arbor)
+
+![Solar eclipse through eclipse lens; a crescent
+glow](img/w24_wrapup/eclipse.jpg)
+
+For the folks without eclipse lenses, here's a reenactment:
+
+![Me holding a banana in the way of the sun](img/w24_wrapup/banana.jpg)
+
+- Except for two occasions, I participated in the W8UM/R Sunday net every
+ week, getting to know AC8TO, KE8BZJ, W8EMV, and KB6NU. Also I love our
+ net control WD4DSR.
+- Attended a W8UM monthly meeting (though one hour late and didn't get any
+ pizza) and met AC8TO in person
+- Saw a crime drama play called Trojan Horse. My friend played a role who
+ died for the most of the play
+- Applied for IA of 370 and 373 next semester
+- Cracked open a beer, which I just finished as I write this. The cashier
+ typed a "1" into the YYYY field on the auto checkout before realizing
+ (1) I was born 2003 and (2) aging is inevitable
+
+## Things unrelated to coursework that made my day worse
+
+I received the prize money for last semester's GERMAN 103 roleplay.
+Instead of $200 per group, it was $200 per person. But it went straight to
+my direct deposit and was split to two parts:
+
+- $172 to repay my "financial aid"
+- $28 in federal tax
+
+It pisses me off that I worked so hard on a roleplay just for the prize
+money to fund genocide.
+
+## Things unrelated to coursework that made my day better
+
+Last year I signed up for [Kristin Henry's Stickers and Stamps
+project](https://kristinhenry.medium.com/stickers-and-stamps-a-bright-spot-in-2020-d3011afefa09).
+It took months, but I finally received their letter in the mail. Enclosed
+is a sticker, a handwritten postcard, and a stamped envelope for me to
+return something in. So I handwrote a brief letter a few days later and
+sent it to Kristin.
+
+It was the second time I physically put something in a US mailbox. The
+first time was when I had to send form 8843 to the IRS to prove that I had
+zero income last year.
+
+Cool find at the 373 lab: a vintage Fluke 77 multimeter.
+
+![Grey multimeter with automatic range
+selection](img/w24_wrapup/fluke_77.jpg)
+
+## Albums discovered
+
+I spent the entire semester listening to Radiohead, all thanks to [a meme
+video](https://www.youtube.com/watch?v=2KGRvIFrF3c).
+
+- _The Bends_ (1994)
+ - Favorite tracks:
+ - Fake Plastic Trees
+ - Street Spirit
+- _OK Computer_ (1997)
+ - Paranoid Android
+ - Let Down
+- _Kid A_ (2000)
+ - Everything In Its Right Place
+ - The National Anthem
+ - Idioteque
+- _Amnesiac_ (2001)
+ - Pyramid Song
+ - Life In a Glasshouse
+- _In Rainbows_ (2007)
+ - Weird Fishes
+ - Videotape
+
+And if you stretch the definition of "discover", I discovered _Clancy_
+(2024).
+
+## Interesting food in the dining hall
+
+Both of these were found in Bursley:
+
+- Blueberry pizza (pretty good actually)
+
+![Blueberry pizza](img/w24_wrapup/blueberry_pizza.jpg)
+
+- Gummyworm cake (it tastes exactly what it looks like)
+
+![A single gummy worm on top of oreo powder and
+cream](img/w24_wrapup/gummy_worm_cake.jpg)
+
+## Funny car plates
+
+- NYANKO
+- UWU 55
+- B1GENUF (on a mini)
+- QING1SE (清一色)