This is a question but also maybe a discussion point. For my swift-stm32c011-examples project, I noticed that although I was able to bring in register definitions with SVD2Swift, they weren't too useful without creating helpers, like for example for configuring and using GPIOs:
extension GPIO {
public enum Mode: UInt32 {
case input = 0x0
case output = 0x1
case alternateFunction = 0x2
case analog = 0x3
}
public enum OutputType: UInt32 {
case pushPull = 0x0
case openDrain = 0x1
}
public enum OutputSpeed: UInt32 {
case low = 0x0
case medium = 0x1
case high = 0x2
case max = 0x3
}
public enum Pull: UInt32 {
case `none` = 0x0
case up = 0x1
case down = 0x2
}
public struct Configuration {
public var mode: Mode
public var outputType: OutputType
public var outputSpeed: OutputSpeed
public var pull: Pull
public var alternateFunction: UInt32
public init(
mode: Mode,
outputType: OutputType,
outputSpeed: OutputSpeed,
pull: Pull,
alternateFunction: UInt32 = 0
) {
self.mode = mode
self.outputType = outputType
self.outputSpeed = outputSpeed
self.pull = pull
self.alternateFunction = alternateFunction
}
}
public func get(pin: Int) -> UInt32 {
return self.idr.read().raw.storage.get(
mask: 0b1,
offset: UInt8(pin)
)
}
public func set(pin: Int, value: UInt32) {
self.odr.modify { rw in
rw.raw.storage.set(
value: value,
mask: 0b1,
offset: pin
)
}
}
public func configure(pin: Int, as configuration: Configuration) {
self.moder.modify { rw in
rw.raw.storage.set(
value: configuration.mode.rawValue,
mask: 0b11,
offset: pin * 2
)
}
// Comprised of 16 x 1 bit fields.
self.otyper.modify { rw in
rw.raw.storage.set(
value: configuration.outputType.rawValue,
mask: 0b1,
offset: pin
)
}
// Comprised of 16 x 2 bit fields.
self.ospeedr.modify { rw in
rw.raw.storage.set(
value: configuration.outputSpeed.rawValue,
mask: 0b11,
offset: pin * 2
)
}
// Comprised of 16 x 2 bit fields.
self.pupdr.modify { rw in
rw.raw.storage.set(
value: configuration.pull.rawValue,
mask: 0b11,
offset: pin * 2
)
}
// Comprised of 16 x 4 bit fields, split across 2 registers.
if pin < 8 {
self.afrl.modify { rw in
rw.raw.storage.set(
value: configuration.alternateFunction,
mask: 0b1111,
offset: pin * 4
)
}
} else {
self.afrh.modify { rw in
rw.raw.storage.set(
value: configuration.alternateFunction,
mask: 0b1111,
offset: (pin - 8) * 4
)
}
}
}
}
So my question is, has there been any thought or discussion towards perhaps standardizing a HAL-library for Swift that can be used for interacting with different things on embedded, that could take different lower-level register definitions and abstract that away for embedded applications?
Kind of like the STM32 CubeC0 HAL...but for Swift?
For now I've been building a small library with a bunch of these helpers for the STM32C011 as I start using the different peripherals, but I was curious if this was a consideration for a future effort.