Now Reading
One more keyboard put up, or, introducing ErgoNICE

One more keyboard put up, or, introducing ErgoNICE

2023-01-13 07:32:40

I made a customized cut up mechanical keyboard! As a result of it is me, this concerned issues like contributing to a PCB design instrument and discovering a ridiculously optimized technique to learn a keyboard matrix.

An entire decade in the past (wow!) I learn a weblog put up referred to as “A Modern Space Cadet
and… properly, began caring about keyboards.
I’ve adopted fairly a number of of the software program tips proper there after which: shifts-as-parens and
capslock-as-control-and-escape.

The {hardware} half—the entire mechanical keyboard factor—took me a pair years to get to.
I used to be solely utilizing a MacBook Air when the put up got here out, however ultimately as I received a desktop,
I had bought my first mech which was a Leopold with unique Cherry MX Brown switches.
I’ve used it for a number of years, however ultimately I discovered myself wanting extra.
Particularly, clicky switches and the ergonomics of the cut up type issue.
In 2020 I bought this AliExpress split keyboard from a producer
referred to as “Spider Island”. I’ve ported QMK to it, due to course.
It felt like a pleasant improve on the time, although the clone MX Blue switches weren’t the very best high quality (as in, a pair
began having bizarre phantom actuations) and the SATA cable connection between the halves being flaky was annoying.

Across the finish of 2021 I used to be taking a look at larger high quality cut up choices just like the Dygma Raise
and the ZSA Moonlander and… determined that I used to be too bizarre for both of them
and would relatively spend cash on fabrication and elements for one thing totally customized.
I believe this video might need been the ultimate inspiration.

So, I began occupied with what I truly wished and got here up with this record of necessities:

  • column-staggered format just like the well-known ErgoDox
  • good clicky switches (after some YouTube-watching the selection was clear: Kailh Box Jade!)
  • “floating key” enclosure design (why is that the widespread time period anyway? I all the time wished to name it “borderless”! as a result of it doesn’t have a border, come on!)
  • for connections: USB Sort-C to the host, something dependable between the halves

And a listing of additional “desires”:

  • quantity management knob (simple)
  • pins for connecting exterior buttons like an enormous purple panic button or a vim pedal
  • a magnetic connector for add-on modules like trackballs, like on the UHKB?
  • a 3.3V TTL output-only serial port header, for a “teletype mode” i.e. instantly typing into the UART of one thing like an RPi?
  • possibly analog enter on WASD keys for gaming too?

Spoiler alert: I didn’t efficiently implement all of the experimental stuff 🙂
However I’m actually pleased with the consequence!

End result, the keyboard in its full glory

So, right here’s how we received there…

The very first thing it’s essential to make a PCB-based keyboard is, properly, having the ability to design PCBs!
So I watched a KiCad tutorial on YouTube to be taught and…
didn’t begin utilizing KiCad. Since you see, I’ve a terminal case of hipster-ism 🙂
So I began to mess around with the far much less standard Horizon EDA as an alternative and it was an absolute dream.
What an exquisite, coherent, sensible piece of software program.

Earlier than truly going for the total keyboard, I’ve determined to make a proof-of-concept: just a little dev board
mainly containing what could be the mind of the keyboard (I picked the STM32L1 household as a result of it was
much less affected by the chip scarcity and, , power-saving sounds good) and pins.
Tiny boards are quite a bit cheaper to fabricate, so if one thing went mistaken, it wouldn’t be that a lot of a loss.
So I designed it, uploaded it to JLCPCB, paid some cash and… success! It labored completely!

Ferrispark PCB loaded in Horizon EDA
Two Ferrispark boards fully assembled

I referred to as this board Ferrispark as a reference to Ferris the Rust mascot
and Digispark, the board whose type issue (18×29 mm) this one suits in.
With that little thingy in hand, it was attainable to experiment with firmware stuff whereas ready for the keyboard PCB to be manufactured and shipped.
However first…

In contrast to “regular” keyboards that include boring customary ANSI/ISO layouts, fanatic keyboards are very numerous,
and with a completely customized construct prospects are really limitless. One can try to get away with very few keys
or make an unhinged meme board or no matter.
However I used to be after one thing sensible, tailor-made to my habits, primarily based on ergonomic improvements however not too completely different from customary layouts.

So I opened everyone’s favorite non-FOSS (boo) layout editor web app, loaded the Ergodox preset,
eliminated all of the unassigned keys surrounding the core clusters, and began including keys that made sense to me.

The very first thing I added was two columns on the best aspect that kinda simply carry again the punctuation as it’s on ANSI.
This felt actually vital to me as a result of it’s not nearly retaining the habits relating to the {[<:;'">]} stuff.
Some non-Latin scripts equivalent to Cyrillic have a variety of letters, so these two columns have precise letters on them when typing these.
Developing with options (like chords) for that appeared like extra of a nightmare than simply for punctuation.
By the best way, I added these columns with out shifting them down, so that they ended up as a 3-wide ortholinear grid cluster on the best finish of the format —
I rapidly realized that it might be a very good match for a numpad on an alternate layer too!

Then I began including modifiers and different miscellaneous keys. I’ve added shifts the place my fingers count on them to be
(since I take advantage of shifts-as-parentheses, the “only one shift key” thought from minimalist boards is de facto not for me).
For the thumb clusters, I’ve added a very powerful textual content actions—Area, Tab, Backspace, Return—as giant keys.
I’ve added a devoted precise Compose key as a result of I take advantage of one. Then I began noticing that the important thing rely was climbing up.
Dangerously near a humorous quantity, even. So I’ve added 4 additional “macro” keys, some actually additional stuff like “menu”,
and ended up with precisely 69 keys. That immediately solved the exhausting drawback of naming issues: the board was referred to as “ErgoNICE” from that time on! 🙂
Right here’s how the format seems:

ErgoNICE layout illustration

(That is the bodily format, so that you see QWERTY right here. I truly kind on Colemak although!)

Earlier than truly designing the PCB, I began taking a look at present keyboard designs (practically all in KiCad), importing numerous elements
into Horizon, buying additional elements just like the rotary quantity knob and headphone jacks on AliExpress and modeling them in Horizon,
and in any other case doing numerous preparations.

Keyboard PCBs aren’t rocket science. There are mainly two methods to attach the keyswitches to the MCU: in a matrix
and instantly. With a compact cut up keyboard, direct is extra possible than ever, you don’t even want that big of a microcontroller,
so I truly noticed that answer in one of many designs I used to be taking a look at. However my alternative of MCU was considerably restricted by the chip scarcity,
and my board wasn’t that compact, and I wasn’t trying ahead to routing all of the direct connections with simply 2 layers
(which was the restrict for non-green boards on JLCPCB and I simply waaaanted a black one regardless that it received’t be seen),
so the plain choice was to go together with a matrix with diodes on each change.

The opposite choice I made early on was that the left half would comprise the microcontroller and could be assembled by JLCPCB with a ton of SMD elements,
whereas the best one I might fully hand-solder at residence, utilizing elements I already owned when attainable.
And that may be… through-hole diodes and the MCP23017-E/SP
enter/output expander. Yeah, the DIP bundle variant. As a result of that’s what I bought about 10 years in the past (!) from
an Arduino stuff retailer once I was first experimenting with electronics. How handy!

Talking of diodes, one thing I noticed and actually appreciated was this footprint for either a surface-mount or through-hole diode.
Nonetheless you’ll be able to’t simply import that straightforwardly into Horizon. KiCad is ok with a number of pads/holes sharing a reputation, and
will simply collapse them into one pad. Horizon is much more strict: every pad should have its personal distinctive identify, and if you wish to assemble one thing fancy like that,
it’s essential to do it within a padstack. Fortunately, Horizon’s parametric padstack system is extraordinarily succesful. It’s primarily based on just a little
stack-based scripting language for repositioning all the things primarily based on no matter logic you need. Nonetheless it was lacking the flexibility
to reposition holes from the script, so I’ve needed to add it, after which:

TH-and-SMD padstack loaded in Horizon EDA

So. Anyway. Precise keyboard design time. You possibly can view the full schematic as a PDF here.
There’s not that a lot to say: it accommodates the aforementioned matrix (properly, two of them, left and proper), the microcontroller and all the things it requires,
the USB-C connector with correctly separated CC resistors,
TRRS audio connectors, numerous pin connectors (debug header, extras like exterior buttons),
the rotary knob with required circuitry… oh, and a bunch of assorted safety. Regardless that I’ve observed that numerous
DIY keyboard designs don’t appear to do a lot of it, I used to be actually into the concept of additional security, so I put resistors on all of the external-facing pins,
transistors for reverse polarity safety on energy inputs, a USBLC6 IC on the USB strains, and so forth.

ErgoNICE schematic loaded in Horizon EDA

Structure began with feeding the JSON output of the keyboard-layout-editor web site to a different web site, Keyboard CAD Assistant.
It produces DXF information which are supposed for use for slicing a plate on a CNC router, however I truly wanted it for the PCB.
I’ve imported the DXF into Horizon EDA, drew polygons with diagonals over every key sq., and received exact facilities of every key —
precisely what’s essential to place the keyswitches!

Then I drew the outlines of the halves, positioned all the opposite elements, routed the tracks… all the things as anticipated.
Routing could be fairly enjoyable, particularly when the EDA instrument seems this good (that is the “Rust” shade scheme, ha):

ErgoNICE board loaded in Horizon EDA

After getting fairly assured that the board was appropriate (the design guidelines test in Horizon is fairly useful!) I’ve despatched it off to manufacturing.
A pair weeks later, I obtained the thrilling notification from the put up workplace. The long-awaited bundle from China!

ErgoNICE boards close-up
ErgoNICE left side board close-up, microcontroller section

Right here’s a comparability with the 3D preview in Horizon. The actual factor all the time seems superb!

ErgoNICE board 3D preview
ErgoNICE boards, both halves

If you wish to mess around with the PCB design information in Horizon EDA your self, it’s in the pcb-ergonice directory in the repo.
And within the release downloads, there may be an export with Gerber information and BOM/CPL for meeting.
Disclaimer: the revision 1 which is revealed there may be barely completely different from the revision 0 which I bodily have constructed. Hold studying to see the bug that I mounted there!

Analog keys are a reasonably enjoyable factor for gaming, permitting you to move slowly in CS for example.
I stumbled upon these people here that have been making an attempt to commercially promote add-on flex PCBs
for including the aptitude to an in any other case regular keyboard and commenced questioning if it’s attainable to only DIY it.
It appears to be a little bit of a scary matter as a result of they’ve a patent in some jurisdictions, however who would go after a non-commercial private venture?
So, their approach is simply utilizing a Texas Instruments inductance to digital converter with a PCB coil.
Fortunately, these chips have been simply out there on JLCPCB’s meeting service (although not low-cost), so I simply went forward with the experiment.
That’s, I designed just a little “analysis board”, suspiciously formed to suit below the keyboard PCB’s WASD cluster and connect with it utilizing 2.54mm headers 🙂

The fascinating a part of the design course of is after all the PCB coils. TI offers an online tool for producing them.
It helps some export… into a pair industrial EDA instruments. However I discovered a manner get the outcomes into Horizon. Get this:
export as an EAGLE venture, open that in KiCad, export the coil as SVG, clear it up in Inkscape (merge into one SVG path), export as DXF R12,
and eventually import into Horizon with a downscaling issue of 10000 as a result of causes. Oof, it’s there! However we are able to’t join something to it,
as a result of it’s simply strains, not tracks. And someway they’re not even all related.

Naturally, this was a chance to dig into Horizon EDA’s codebase and add some new tools!
This was a really fulfilling expertise, and with some fast suggestions from the creator of Horizon I cut up one of many instruments into two, and right here they’re:
“choose related strains”, “merge duplicate junctions”, and “strains to tracks”. With Horizon changing into this significantly better, the board was simple to make.
That is the way it seemed:

TI LDC test board flat on the desk
TI LDC test board in a testing setup

To attempt it out, I wrote a Rust embedded-hal driver for the LDC1x1x chips and
an embedded-hal implementation for FreeBSD userspace APIs
in order that I may take a look at it instantly on my PC with a CP2112 USB-to-I²C adapter, simply piping the output from a demo program into
ploot.

What I’ve discovered is that whereas the stream of numbers was certainly correlated with how far the important thing was pushed down,
it was not good. Whether or not I used to be catching the motion of the finger or the spring was fairly complicated, particularly
when below the precise keyboard PCB. The truth that the switches of my alternative have a click on bar may’ve been a detrimental influence,
the gap to the change from behind of the PCB was in all probability an issue, and the massive 4-layer coil in all probability wasn’t fairly compensating
for that (or was it truly simply dangerous?).

Both manner, I couldn’t connect it to the keyboard as a result of it seems I’ve made a foolish mistake within the schematic:
I forgot to attach one of many columns to the microcontroller 😀
So I ended up working a bodge wire to one of many holes meant for the LDC board:

ErgoNICE left side PCB with bodge wire

There are a lot of methods to make a keyboard enclosure, however as I used to be into 3D printing, that query was already answered.
How handy {that a} cut up keyboard suits properly into the dimentions of an Ender 3 construct plate!
I’ve been utilizing realthunder’s FreeCAD fork for modeling 3D printed elements,
in order that’s what I used for this one as properly.
After all FreeCAD’s UI is clunky and its core is crashy,
however I’d relatively not contain proprietary software program on this venture.
Having CAD information in an open format is that worthwhile to me.
And earlier than somebody begins preaching code-CAD like cadquery to me:
sorry, I really like sketching with a mouse and hate school-style math an excessive amount of 😀

I began out with exporting a 3D mannequin of the boards and elements on them as a STEP file from Horizon and importing it into FreeCAD.
Within the file, all the things was cleanly separated out, i.e. every element was its personal physique. Nonetheless on account of format limitations
each occasion of the identical half (e.g. each change) is its personal unbiased physique, which takes up a variety of house on disk.
I wrote a Python script in FreeCAD that may take the at present chosen our bodies and substitute all of them besides the primary one
with a hyperlink to the primary one, eradicating the duplication of precise 3D mannequin information. (Sadly I misplaced that script by now, but it surely was tiny.)

With a mannequin of the boards, it wasn’t too exhausting to make an enclosure round them. The enclosure has two principal elements.
The plate is a flat extrusion that will get completely hooked up between high of the PCB and the underside halves of the switches.
The tray is the remainder of the enclosure, hooked up to the plate with screws.
As well as there are tenting wedges that connect to the underside of the tray, and the precise knob that goes on the rotary encoder.
That is the way it all seems in FreeCAD:

ErgoNICE case overall look in FreeCAD
ErgoNICE case cross-section in FreeCAD

Right here’s a glance into the tray from the above. I’ve added these helps beneath every key for additional rigidity.
In any other case it’s… not that outstanding?

ErgoNICE tray in FreeCAD

I printed the elements on a closely modified Ender 3 Professional out of darkish grey sparkly PETG.
It turned out fairly properly! The whole lot match collectively simply, the tolerances for issues just like the house for the important thing switches
have been precisely proper, it seems very respectable for a DIY object.
Once more, that is the way it seems:

End result, the keyboard in its full glory

If you wish to mess around with the supply mannequin, it’s all of that XML in the case directory
saved within the repo, saved utilizing the version-control-friendly “save as listing” performance of realthunder’s FreeCAD.
And within the release downloads, there’s an archive with STL and STEP exports.

Now that all the things is put collectively bodily, we have to put software program on the tiny little laptop that runs the keyboard
(it’s computer systems all the best way down!).

The most typical technique to get some keyboard firmware going is to make use of a well-liked venture like QMK (a traditional
that began on AVR and added Arm later) or ZMK (standard with Bluetooth, primarily based on a complete RTOS referred to as Zephyr and
configured with flattened device trees).
However after all, “widespread manner” means it’s not what I’m going to do.

I like the Rust programming language rather a lot and it’s, like, good for embedded so after all I’m going to make use of it right here.
Naturally, I’m not the one one doing so: I used to be fairly joyful to find that there was already a library referred to as
Keyberon for dealing with all of the uhh… keyboarding.

Now, how does the Rust ecosystem for STM32 appear to be?
In contrast to the C world the place you work together with one monolithic SDK (both the vendor-provided one or libopencm3)
there may be much more code sharing and integration because of the magic of bundle administration.
The “libopencm3” of Rust is unfold over quite a lot of crates: the middle of that obscure “SDK” is
interface crates like embedded-hal and usb-device,
and there are each drivers that use these interfaces and microcontroller assist crates such because the stm32-rs ones that implement them.
There may be nevertheless the “parallel ecosystems” factor too, however not due to distributors: the relatively standalone world right here is
Embassy, an async embedded framework.

And in reality, as a result of stm32-rs’s stm32l1xx-hal shouldn’t be actively maintained, I’ve thought of utilizing Embassy for the venture.
I performed round with it, fixing some STM32L1 initialization code and stuff,
however in the end ended up simply forking stm32l1xx-hal, including USB assist and I²C timeouts and naturally fixing bugs.

See Also

With an affordable HAL crate and Keyberon in hand, it’s fairly simple to place the items collectively.
However I didn’t do something within the simple manner as a result of I can get kinda obsessive about effectivity 🙂

The cool factor to do for effectivity in embedded improvement is to let {hardware} do issues as a lot as attainable as an alternative of software program.

The primary alternative to leverage good STM32 peripherals is after all the amount knob: the {hardware} timers have the
capacity to learn a rotary encoder as an alternative of, properly, counting time.
So long as you join the encoder to a pair of pins that do correspond to a timer, which I did as
I knew this beforehand, on the PCB design stage.
So within the code, grabbing the timer for this objective is so simple as:

let knob_cnt = cx.gadget.TIM2.qei((gpioa.pa0, gpioa.pa1), &mut rcc);

And when polling all of the issues, we merely test if the rely has elevated or decreased because the earlier
time we did that, and by how a lot.
Relying on that, we press-and-release a delegated key place within the format,
the place we place quantity up / quantity down keys on the principle layer and different enjoyable stuff on different layers
(e.g. I made it in order that Fn+knob is scroll up / scroll down, only for enjoyable).

let knob_now = cx.native.knob_cnt.rely() as i16;
let knob_row = if knob_now > *cx.native.knob_last { 1 } else { 0 };
for _ in 0..(knob_now - *cx.native.knob_last).abs() / 2 {
    handle_event::spawn(format::Occasion::Press(knob_row, (LCOLS + RCOLS) as u8)).unwrap();
    handle_event::spawn(format::Occasion::Launch(knob_row, (LCOLS + RCOLS) as u8)).unwrap();
}
*cx.native.knob_last = knob_now;

Now, how about one thing extra superior? However what’s left there to automate?
Properly, after all, the precise studying of the keyboard matrix! It’s a standard factor, there needs to be {hardware} options!
And there are. There are ICs that do keyboard matrix scanning (often I/O expanders with that performance),
the Programmable I/O peripheral of the RP2040 is likely to be promising for this utility,
after all cool issues could be achieved with FPGAs (you may make a microcontroller with your personal key scanner peripheral
like within the icekeeb venture).
But it surely seems our little STM32 already has an ideal instrument for the job!

As a result of… it will probably DMA between reminiscence and banks of GPIO pins, triggered by a timer.
Once I was occupied with the DMA capabilities, I used to be questioning if somebody has already achieved what I wished to do and sure!
This 2016 blog post describes
precisely the right way to do it. (With some bonus big-brain ideas on key debouncing.)
This a part of the put up sounded considerably worrying:

Allocate all row output pins on one GPIO port and all column enter pins on one other GPIO port

as I’ve not achieved that on my PCB. However properly, I rapidly realized that I may lengthen this concept to work
with pins arbitrarily scattered throughout each of the 2 pin banks, simply by utilizing extra timers.
However my job was barely simpler as solely columns (outputs in my design) have been in each banks, A and B,
whereas rows (inputs) solely have been in financial institution B.

Here is how the Rust magic for that appears

To generate the bit patterns, I used a const fn:

const fn gen_gpio<const N: usize>(pins: [i32; N]) -> [u32; N] {
    let mut consequence: [u32; N] = [0; N];
    let mut p = 0;
    whereas p < N {
        if pins[p] >= 0 { consequence[p] = 1 << pins[p]; }
        p += 1;
    }
    consequence
}

static mut IN_GPIOB: [[u32; LCOLS]; 2 * BOUNCES] = [[69; LCOLS]; 2 * BOUNCES];
static OUT_GPIOA: [u32; LCOLS] = gen_gpio([-1, -1, -1, -1, -1,  8, -1]);
static OUT_GPIOB: [u32; LCOLS] = gen_gpio([ 1, 12, 13, 14, 15, -1,  0]);

Okay, not that cool, it’s a relatively verbose technique to keep away from writing 1 << in all places, however I’m an enormous fan of
compile-time operate execution.
However extra to the purpose, the reminiscence format already explains how the DMA setup works.
On each tick, the following output configuration might be chosen throughout each GPIO ports (activating the following column)
and the following readout of the inputs (properly, of all of the inputs on financial institution B) might be put into reminiscence.

For configuring the DMA engines, which don’t have pleasant wrappers within the HAL crate,
I wrote a macro
wrapping the uncooked {hardware} register writes to make it look respectable like so:

dma_chan! { dma1: 
    cndtr1 [LCOLS]     cmar1 [&OUT_GPIOB as *const _]
    cpar1 [gpiob_odr]  ccr1 [mem2per nointr]
};
dma_chan! { dma1: 
    cndtr2 [LCOLS]     cmar2 [&OUT_GPIOA as *const _]
    cpar2 [gpioa_odr]  ccr2 [mem2per nointr]
};
dma_chan! { dma1: 
    cndtr3 [LCOLS * BOUNCES * 2]  cmar3 [&mut IN_GPIOB as *mut _]
    cpar3 [gpiob_idr]             ccr3 [per2mem intr]
};

So, the output channels simply cycle by the very quick 7-element arrays, enabling just one column at a time.
The enter studying channel is the fascinating one.
The * 2 within the array size is expounded to DMA double buffering.
See, the engine can interrupt the CPU each when it goes by your entire array and wraps round,
and proper in the midst of the array. This enables the CPU and the DMA engine to keep away from stepping on one another’s toes:
on the half interrupt we learn the primary half of the reminiscence, and on the total interrupt we learn the second.
And yeah, every half accommodates a number of readouts in a row, to be fed right into a debouncer.
That is the way it’s achieved, changing the uncooked GPIO readout bytes right into a matrix for Keyberon:

static ROW_GPIOS: [u32; ROWS]  = gen_gpio([4, 5, 6, 7, 2]);
let is_half = dma1.isr.learn().htif3().bit();
let scans = unsafe {
    &IN_GPIOB[if is_half {
        0..BOUNCES
    } else {
        BOUNCES..2 * BOUNCES
    }]
};
for scan in scans {
    let mut mat = [[false; LCOLS]; ROWS];
    for (c, colscan) in scan.iter().enumerate() {
        for (r, rowmask) in ROW_GPIOS.iter().enumerate() {
            mat[r][c] = (colscan & rowmask) != 0;
        }
    }
    for ev in cx.native.debouncer_l.occasions(matrix::PressedKeys(mat)) {
        handle_event::spawn(ev.remodel(left2global)).unwrap();
    }
}

And… it really works! Now, after all I haven’t measured any effectivity positive factors versus doing all the things the essential software program manner 😀
However having enjoyable with the implementation was the purpose greater than something.

All the supply of the firmware is in the fw directory in the repo.

After all the tip consequence ended up much less bold than the preliminary venture.
Out of the preliminary record of concepts, the analog enter fell out on the PCB stage, whereas
the additional peripheral (trackball/and so forth.) assist kinda fell out on the case design stage.
The “teletype mode” by way of the output-only serial port header solely fell out right here on the firmware stage although,
with potential to come back again and add it sometime.

Nonetheless there’s one other factor I used to be relatively occupied with however didn’t get to attempt within the firmware, and that’s
USB Selective Suspend
which ought to permit the microcontroller to fall asleep for idle durations.
This isn’t simple to perform, but it surely looks as if resuming the USB connection after sleep on the STM32L1 sequence is likely to be attainable.

Hello, you may bear in mind me as that unrelenting.know-how particular person
who’s achieved issues with FreeBSD, Firefox, and Wayland,
was concerned with the IndieWeb,
has revealed comparatively standard Rust crates like systemstat and a complete bunch of different issues.

This put up may’ve been revealed many months in the past, because the keyboard was accomplished in February 2022.
Nonetheless, only a couple days after I completed the work, the world has… modified round me. For the more severe.
The dictator of my nation has launched a navy invasion right into a neighboring nation. Struggle.
Struggle is horrifying. After all being within the aggressor nation shouldn’t be like having a missile hit your home,
however dwelling below what’s mainly a fascist navy dictatorship isn’t so superb both.
I used to be afraid that I might be pressured to struggle or to work for the warfare effort, that the borders might be closed
and I might be caught in there for an indefinite time period, that the worldwide web might be disconnected
and I wouldn’t be capable of converse with the one individuals I really like.
In the meantime, my gender journey was taking me from “it might be good to alter issues about my physique sometime”
to “oops truly I kinda simply have some dysphoria” and yeah, no higher time and place to take care of that, proper.

Now that I’m out of there, I don’t have an earnings anymore. So, I’ve opened a Patreon page.
I’m not asking for charity on account of my scenario, however relatively for funding for my work on free software program.
For those who appreciated this put up and the way each time I work on a venture like this I find yourself contributing throughout the FOSS ecosystem,
if you wish to see issues like an atomic image-based FreeBSD by-product come to life (a little bit of a spoiler for the following weblog put up?)…
any stage of assist could be appreciated.

Thanks, Val <3



Source Link

What's Your Reaction?
Excited
0
Happy
0
In Love
0
Not Sure
0
Silly
0
View Comments (0)

Leave a Reply

Your email address will not be published.

2022 Blinking Robots.
WordPress by Doejo

Scroll To Top