rust-embedded/wg

The weekly driver initiative

japaric opened this issue ยท 236 comments

There's now a HAL published on crates.io: embedded-hal (Introduction blog post). ๐ŸŽ‰

To put it to test and to expand the crates.io ecosystem I'm starting the weekly driver initiative.

The goal is to release a new no_std, generic, embedded-hal based driver crate every one or two
weeks. Driver crate here means a library crate that lets you interface an external component like a
digital sensor or a wireless transceiver. A driver release consists of (a) publishing a library
crate on crates.io (*) and (b) presenting your driver to the community via any means: a blog post,
a tweet, a reddit post, a u.r-l.o https://users.rust-lang.org post, etc.

(*) Make sure you tag your crate with the embedded-hal-driver keyword!

If you'd like to participate leave a comment here stating the driver you'll be working on. If you
can post a link to the repo where the (WIP) driver code is or will be, even better! If you don't
have a personal blog to present your driver to the community you can do a guest post on my blog.

For a list of released and WIP drivers check the awesome-embedded-rust list. If you'd like your crate to be added to that list simply send a PR to that repo!

TODO (potentially):

These are components that @japaric has at hand:

  • DHT22 - temperature + humidity sensor (1-wire)
  • ENC28J60 - ethernet controller (SPI)
  • HC-06 - bluetooth (AT)
  • HC-12 - wireless transceiver (AT)
  • HC-SR04 - ultrasonic sensor
  • L298N - Motor driver
  • NEO-6M - GPS (USART)
  • NEO-M8N - GPS (USART)
  • PCA9685 - 16 channel Servo driver (I2C)
  • PCF8574 (+ 16x2 LCD) - 8-bit I/O expander (I2C)
  • PN532 - NFC (SPI)
  • RA-02 - Long-range Radio (SPI)
  • SN65HVD230 - CAN
  • SSD1306 - 128x64 OLED (I2C)
  • Servomotor (?)
  • WS2812B - smart LED
  • nRF24L01 - wireless transceiver (SPI)

I can probably help porting some NRF51/NRF52 drivers from TockOS that I have been involved in. I think the BLE driver could be interesting to have in a separate crate.

Let me know if you think it is a good idea!

dbrgn commented

If I find time I could try to do a DS18B20 (dallas one-wire) temperature sensor driver implementation.

Current stumbling blocks so far (I'm developing on the LPC11UXX):

(In both cases, what @rnestler wrote)

I've tons of devices at hand and I might write drivers for them but first I need to get the device crates and HALs up to snuff.

Apart from the usual Serial/I2C/SPI suspects what I'd like to see is whether the HAL approach is also viable for bit-banged GPIO, potentially even timing critical devices, some of which are also in @japaric's list, like the Neopixels. Something that would be really killer to have is support for multiplexed and charlieplexed LED matrices.

alevy commented

If TockOS starts using this HAL internally then new chip support should be easier to add in the future. I found the LM4F120 port fairly hard going.

I'd personally be highly supportive of that, but would need some convincing that it would fit the capsule architecture (that hasn't seemed to be the case for previous iterations). Perhaps @niklasad1 can report some insights if he ports his BLE stack from Tock.

@japaric Is there going to be a registry for embedded stuff and especially drivers? crates.io is becoming more and more useless to find interesting crates...

The LM4F120 crate now implements embedded_hal::serial::{Read, Write}. It was pretty straightforward.

@niklasad1

Let me know if you think it is a good idea!

More drivers is a good idea, IMO. :-)

porting some NRF51/NRF52 drivers

Just to clarify: Is this driver about interfacing an external pre-flashed nRF5x device, or is it some BleRadio trait on top of which a generic BLE stack con be built? In the later case you implement the BleRadio trait for, say, a nrf51 device crate and you get a BLE stack for free (ideally).

@therealprof

I'd like to see is whether the HAL approach is also viable for bit-banged GPIO

At the very least we'll want to add a digital::OutputPort trait whose API changes the state of a whole port (8 or 16 pins) atomically (single register op). And maybe another trait to change the state of N pins that belong to the same port atomically.

potentially even timing critical devices, ..., like the Neopixels

The words Neopixels and bit banging reminded me of an Arduino library I saw. It implemented the protocol using assembly and was fully blocking (nop delays) to meet the timing constraints. I hope that our neopixels driver provides a DMA based (asynchronous) mode, apart from a bit banged mode.

Is there going to be a registry for embedded stuff and especially drivers?

I meant to include this in the issue description: I'm using the embedded-hal keyword for my driver crates. That makes them easier to find. Perhaps we can just use crates.io and keywords instead of creating another registry / list. We can bikeshed the keywords to use in this thread: perhaps embedded-hal (or embedded-hal-driver) for the driver crates, embedded-hal-impl for the HAL impl crates, like the stm32f30x-hal crate, and svd2rust for the svd2rust generated device crates?

@japaric

Just to clarify: Is this driver about interfacing an external pre-flashed nRF5x device, or is it some BleRadio trait on top of which a generic BLE stack con be built? In the later case you implement the BleRadio trait for, say, a nrf51 device crate and you get a BLE stack for free (ideally).

Coincidentally I'm working on a micro:bit crate (which is based on the NRF51822, as I'm pretty sure you're aware of ๐Ÿ˜‰). I planned on adapting the BLE code from the Zephyr project, since Nordic is quite active there providing a BLE implementation for their devices without the humongous softdevice blob.

It's not quite ready for primetime yet since the documentation is somewhat lacking and reversing Zephyr somewhat time consuming due to the many layers of abstraction and indirection.

But your recent work and post kind of beat me to adapting what I have to the new singleton approach and also use the embedded-hal (which I previously haven't), so I'm trying to put some more time in.

At the very least we'll want to add a digital::OutputPort trait whose API changes the state of a whole port (8 or 16 pins) atomically (single register op). And maybe another trait to change the state of N pins that belong to the same port atomically.

Yeah, that's going to be interesting. But the reason I mentioned this is that there somehow (and I'm not sure what this will might look like just yet) should be a way to facility the required high speed updates.

The words Neopixels and bit banging reminded me of an Arduino library I saw. It implemented the protocol using assembly and was fully blocking (nop delays) to meet the timing constraints. I hope that our neopixels driver provides a DMA based (asynchronous) mode, apart from a bit banged mode.

Some of those WS controllers can be driven by abused SPI peripherals provided by some MCUs but that can't be taken for granted. AFAIR that doesn't work on the RasPi and that one also cannot do the required timing via bitbanging the GPIOs.

I meant to include this in the issue description: I'm using the embedded-hal keyword for my driver crates. That makes them easier to find. Perhaps we can just use crates.io and keywords instead of creating another registry / list. We can bikeshed the keywords to use in this thread: perhaps embedded-hal (or embedded-hal-driver) for the driver crates, embedded-hal-impl for the HAL impl crates, like the stm32f30x-hal crate, and svd2rust for the svd2rust generated device crates?

That might work but has quite a number of disadvantages:

  • It relies on people knowing how to correctly tag the crates and actually do it
  • crates.io doesn't tracking of crates so one doesn't get notified about new crates of interest or updates
  • The quality of the entries varies a lot and investigating potentially relevant crates consumes a lot of time with a strong tendency to becoming even worse
  • The amount of search results is often overwhelming and there's virtually no support narrow down the search. Just for fun I just tried this query and I didn't find the result very encouraging...

crates.io is okay for larger std crates but for the hundreds or even thousands of embedded crates we're going to have, this is going nowhere fast... Originally I was counting on japaric.io or rust-embedded becoming the authoritative source for everything embedded in Rust but somehow this didn't quite happen. ;)

My hopes are still that we can establish a lively community around those topics, with a comprehensive catalog of relevant crates (architectural, register mapping, MCU HAL, peripheral HAL, BSP and specific implementations), articles on the use of any of that and general development topics, guides for embedded Rust development and support (development tools and debugging software/hardware to use) and potentially even general MCU howtos (selecting and connecting peripherals to an MCU, developing your own hardware...)...

@jacobrosenthal

Another open source nrf ble stack to check out is mynewt's nimble, which is
the rtos im currently using in my daily work.
https://github.com/apache/mynewt-core/tree/master/net/nimble

I am aware, I tried everything I could find for that MCU, including (but not limited to) Mynewt, RIOT and Zephyr. Most ecosystems rely on the softdevice while some others provide their own (but often very limited) BLE stack. The Zephyr stack is written by the vendor Nordic themself and has been certified so it is known to be feature complete and (somewhat) correct.

Im hoping to try out rust for the first time, and ble on the microbit would
be a great reason for me to finally dig in as 'full' functionality
(bootloading over ble mainly) on nrf51822 devices is tough to come by with
every other rtos out there due to the low memory. Curious how rust could
stand up.

Rust allows for ridiculously small firmwares on those MCUs (compared to other ecosystems that is) so I'm confident that there won't be any space issues per se. Of course if you add a BLE capable bootloader for DFU that whole situation changes a good deal because that will take a sizeable amount of flash by itself. I wouldn't hold my breath for that to materialize. ;)

https://github.com/runtimeco/mcuboot/

Bootloaders don't have a very high priority for me at the moment but adding support for mcuboot might be straight forward. Question is what the benefits would be, especially on the micro:bit but I'll have a look, thanks.

Rust allows for ridiculously small firmwares on those MCUs (compared to other ecosystems that is) so I'm confident that there won't be any space issues per se.

Is that really true? The generated format! code is very bloated, for example, with its myriad of vtables, tables, floating point...

@whitequark

Is that really true? The generated format! code is very bloated, for example, with its myriad of vtables, tables, floating point...

That's true, format! is relatively expensive due to the incapability to properly see the used types and monomorphize; however (unless there's another bug I'm not aware of, not using format! too much in my code) it should be a one-time overhead which is comparable to printf() formatting in C and no-one forces you to use formatters; outputting strings using write_str() as well as "manually" formatting numbers e.g. using the NumToA crate.

Here I have an example rendering a counter triggered by USART input onto an I2C driven SSD1306 OLED display:

File .text Size Name
0.2% 28.4% 604B USART1
0.2% 26.5% 564B main
0.1% 17.9% 380B [41 Others]
0.1% 11.3% 240B compiler_builtins::int::udiv::__udivsi3
0.0% 5.5% 116B i2c_ssd1306::ssd1306_print_bytes
0.0% 3.9% 84B stm32f042::peripherals::i2c::write_data
0.0% 3.0% 64B cortex_m_rt::reset_handler
0.0% 1.4% 30B __udivmodsi4
0.0% 0.8% 18B __aeabi_memcpy
0.0% 0.8% 18B __aeabi_uidivmod
0.0% 0.5% 10B __aeabi_uidiv
0.7% 100.0% 2.1KiB .text section size, the file size is 310.9KiB

This (a bit older example) includes write_str use and an implementation on the serial port and an somewhat similar implementation for the display rendering...

I have both an HC05 and HC06 pair and a tricolour e-ink display. I should be able to start work on these pretty soon.

I already have (incomplete) PN532 Rust implementation based on i2cdev crate. I'd love to adapt it to HAL, but I don't expect to have time soon. In case anyone else wants to do it, I'm willing to help.

@whitequark, @therealprof check out fast_fmt crate. It was specifically designed to avoid this overhead.

@Kixunil any documentation would be helpful.

would be great to have USB support, i.e. some library interfacing for instance FTDI chips. seems like tock os got some generic USB code.

@mneumann Not sure I follow. Why would you use an USB<->Serial interface? Some MCUs have USB peripherals built-in but providing an HAL for creating an USB endpoint is a somewhat complex and very specific.

@therealprof : if the MCU has a built-in USB peripheral then I'd of course use that, given that it's easy to use from Rust ;-). But those devices I have at hand, need an external USB chip. Regardless of whether it's on or off-chip, I'd love to be able to use USB from Rust. This is just the last (big) missing piece to make use of Rust on embedded for me.

@mneumann There's a couple of posts about implementing USB Serial in Rust here, but the series is unfinished.

I have created a separate issue for tracking progress on a generic USB stack: #40. Please continue USB discussions over there; let's keep this thread focused on drivers built on top of embedded-hal. (I'm of the opinion that USB is complex and specialized enough that it should go into its own crate separate from embedded-hal.)

@whitequark what exactly are you missing?

DHT22 - temperature + humidity sensor (1-wire)

I already had the DHT22 working with Rust at some point, although not in the form of a reusable driver library. If anyone is interested, I can dig up the code. Caveats: It's messy code, integrated into an application, built on top of other messy unpublished code. I'm not sure how useful it's going to be, but as a starting point, it may be better than nothing.

@japaric

I meant to include this in the issue description: I'm using the embedded-hal keyword for my driver crates. That makes them easier to find. Perhaps we can just use crates.io and keywords instead of creating another registry / list. We can bikeshed the keywords to use in this thread: perhaps embedded-hal (or embedded-hal-driver) for the driver crates, embedded-hal-impl for the HAL impl crates, like the stm32f30x-hal crate, and svd2rust for the svd2rust generated device crates?

I'm in full agreement. Not sure what the best keywords would be, but we should have them. I'm already using the svd2rust keyword for lpc82x.

@therealprof

That might work but has quite a number of disadvantages:
[...]

I think your points are valid, and I would love to see a community resource like the one you describe. However, someone has to build this, and it's going to be a lot of work. crates.io is already here, and we can start using the suggested tags to ease the problems that it has right now.

I'm gonna have a go at building something for a HD44780-style (S6A0069 in my case) 16x2 LCD. @japaric I see you mention an LCD in the context of an IO expander: would a potential IO expander API expose digital::OutputPins such that the LCD module could operate generically over either the uC's pins or the expander's?

@hannobraun

I think your points are valid, and I would love to see a community resource like the one you describe. However, someone has to build this, and it's going to be a lot of work. crates.io is already here, and we can start using the suggested tags to ease the problems that it has right now.

I totally agree. One doesn't preclude the other. I fully expect that crates.io will remain the official source for all crates, including embedded ones. I was hoping we could at least get something like https://github.com/brson/stdx up.

@JJJollyjim: clerk might be of interest for you. Here are some tickets from embedded-hal
rust-embedded/embedded-hal#29
rust-embedded/embedded-hal#30

@JJJollyjim

I see you mention an LCD in the context of an IO expander

It's just that the LCD I have has an I2C port expander attached to it and the only interface that the module exposes in I2C. But ideally the port expander driver, say PCF8574<I2C> itself would implement the digital::* traits and then you be able to plug that in the LCD driver, say LCD<PCF8574<I2C1>>, but an LCD abstraction right on top of I2C would still be a good start.

dbrgn commented

For HD44780 compatible LCDs, there are mainly two IยฒC port expanders used: The PCF8574 and the MCP23008.

In case it helps, here's my Python driver for those LCDs: https://github.com/dbrgn/RPLCD/blob/master/RPLCD/i2c.py

@JJJollyjim @japaric: My current Display implementation is abstract over the underlying protocol, currently there are two impls for either 4 or 8 data line parallel mode, but it should be possible to impl the traits for I2C, too, but maybe it would need some refactoring with the new HAL traits in mind.

Thanks, this "switch to a stable embedded-hal release" fixes lots of things I was fighting with in the previous version. As soon as the blue-pill crate is updated I'll port my working "1-Wire" driver on this new version (with a 18B20 example, device enumeration).
I also have a work in progress CAN driver (that is not an easy one).

dbrgn commented

@tib888 ok, if you already have a working DS18B20 driver I won't start with writing another one :)

Are there plans to implement a generic display driver, and then device specific crates that implement that abstraction? There are so many different variations of each display type (Eg 128x64, 128x32, monochrome, yellow/blue in those AdaFruit OLED displays alone) that there is a lot of deduplication to be done.

@tib888 FYI: the blue-pill crate has been replaced by the stm32f103xx-hal crate, which implements the embedded-hal traits for the whole STM32F103XX family.

@thejpster: Maybe you want have a look at the RFCs and already implemented stuff of the embedded-hal trait and add some comments with suggestions or even new feature request for things that will be needed to implement such drivers.

wose commented

I'm currently working on a driver for the Si7021 humidity/temperature sensor (I2C).
WIP driver code: Si7021

Some other sensors I'll probably tackle later:

  • MMA8652FC - accelerometer (I2C)
  • BMP 280 - barometric pressure/temperature sensor (SPI/I2C)
  • BH1750 - ambient light sensor (I2C)

I also have a couple of SSD1306 based OLEDs in different sizes (96x32, 128x64). I think at some point we will need something like embedded-gfx which holds things like the ones @thejpster mentioned. I'm thinking of traits like MonochromeDisplay, ColorDisplay, DoubleBuffered, ... and generic functions to draw a line or print some text on either of those.

@wose I've some old and crusty Rust code for the SSD1306 in here: https://github.com/therealprof/stm32f042/blob/master/examples/i2c_ssd1306.rs

I've just released a driver for the NXP MAG3110 magnetometer here.

My SenseHat crate has drivers for the HTS221 humidity sensor and the LPS25H pressure sensor. They're written against the I2CDevice trait so should be easy enough to move out and swap to working against the HAL.

I've just released a driver for the NXP MAG3110 magnetometer here.

@therealprof neat. Want to do a small writeup about your driver covering what it does and how to use it?

@japaric Well, to be honest. I can tell you how to use it but I have no idea what a possible application might be and how to implement it since the datasheet is somewhat lacking. You can detect proximity to magnets and (so I would guess) with a bit of calibration sense and calculate the orientation in the room and cardinal direction. I just needed something to test the nrf51 I2C driver with and this on-board sensor on the micro:bit is far easier to use than the MMA8653FC accelerometer, which I'm working on now.

NB: I still haven't figured out how to use multiple sensors on the I2C bus at the same time... ๐Ÿ˜‰

I would love to help with this and create a driver for the NEO-M8 series of GPS receivers, but I will need help. I've already written a driver for them in C++, so I know the chips and the protocols (and have some known-working M8Ts on hand to test with), but I'm still at the "blink an LED" phase when it comes to embedded rust (have lost momentum due to not doing random-thing-I-don't-know-about which makes it a PITA to flash new code to the board). Would anyone here be interested in being PM and/or code-reviewer for me (I promise I won't take much bandwidth)?

I have a WIP Si5351 clock generator driver here: https://github.com/ilya-epifanov/si5351

I've added the WIP drivers that people have reported to the issue description. If yours is missing
let me know!

I've also send a PR / RFC to the embedded-hal repo that establishes a process for adding new
traits to it. If you would like to suggest a tweak to the proposed process leave a comment over
there. In that PR I'm also calling for collaborators that will help me put the proposed process in
practice. Finally, that PR is also adding a list of embedded-hal drivers (like the one we have
here) and a list embedded-hal implementations (which didn't previously exist) to the README; if
you'd like your crate to be listed there feel free to send a follow up PR.

While playing around with rust on the 'Black Pill' (stm32f103xx device like blue pill), I've created a very basic MAX7219 driver, which when development is completed should have a very similar feel to the LedControl library for Arduino.

It's still a WIP, but I've uploaded the code I currently have to: https://github.com/maikelwever/max7219

When I fix the TODOs outlined in the readme there, I'll probably push it to crates.io as well.

I've also tried a early revision on an OrangePI which also seemed to work fairly well.

I published a blog post about the l3gd20 and lsm303dlhc drivers, which are already on crates.io, so I have move them to the list of "Released" drivers. Two driver released; 50 more to go!

I've been thinking that it may not be necessary to do a blog post about the driver to consider it released. I think we can move to the released list if it has been published on crates.io and you have let the Rust community know about it via any means: a blog post, twitter, u.r-l.o post, etc.

Do let me know when you consider your driver as being "released to the community" so I can update the lists and the count!


@maikelwever That's a bit banged implementation of SPI, right? I was just thinking that we could provide generic bit banged implementations of SPI and maybe i2C in the embedded-hal crate. I think that would be a good place for them. Then others can use those implementations instead of writing a new implementation.

Not sure about this. The RFC proposes to open a new issue for each stage of trait design. I worry it might lead to confusion from having so many issues.

wose commented

I did a little writeup "Let's write an embedded-hal-driver" as part of the WIP driver for AT24C32/64 like EEPROMs. I'll finish and release it to crates.io within the next few days.

Some other WIP drivers:

  • DS3231 - real time clock (I2C)
  • BH1750 - ambient light sensor (lux meter) (I2C)

@wose Neat! If you (or any one else) want me to retweet your blog post feel free to @ me on Twitter (japaricious).

Added the MCP3008 driver by @pcein to the list of released drivers.

I will be working on an embedded-hal driver for the Decawave DW1000 module (which should also support the DWM1000 and DWM1001 modules), which is an 802.15.4 compatible UWB (3.5-6.5GHz) SPI based radio chip.

Right now the (verrrrry little) code lives here: https://github.com/jamesmunns/raumfahrer/tree/master/src/dw1000 (living next to the application code), but once it is a bit further along, I will break it out and put it up on crates.io.

It is a very complex module, so the development will be ongoing, but I hope to have support for at least basic ranging use cases in the near future (hopefully weeks).

odlg commented

I am working on a RFM95W/RFM96W lora driver, which are actually based on SX1276/SX1278 modules. So far the driver is going to be without interrupt handling, but that might be added later.

I'm implementing drivers for HC-SR04 and VL6180. The HC-SR04 driver will initially be married to the f3 crate because there are no general timers to estimate length of time. Once I have tested a bit with the f3 I want to try and generalize the needed timers and have them included in embedded-hal.

Wanted to make a driver to improve my Rust skills, but it seems there is only an SPI implementation. Any idea when I2C module will be available?

@MrBuddyCasino I2C traits do exist and some HALs also have I2C support. Anything specific you think is missing?

No, I just saw an SPI module but no I2C module. Got a link as starting point?

@MrBuddyCasino See the top comment in this thread?

The embedded-hal trait is here: https://github.com/japaric/embedded-hal/blob/master/src/blocking/i2c.rs

Support is available at least for some stm32 MCU and e.g. for the nrf51. Which ones are you trying to use?

Totally missed that, thx. I was referring to https://docs.rs/embedded-hal/0.1.2/embedded_hal/#modules which is what confused me.

I've got some blue pill boards, I'll just try and see.

So I'm trying my hands on the MCP9808 temperature sensor. The I2C sorcery required to read a value is this:

i2c_start();                         // send START command
i2c_write (AddressByte & 0xFE);     //WRITE Command 
i2c_write(0x05);                    // Write TA Register Address
i2c_start();                        //Repeat START
i2c_write(AddressByte | 0x01);      // READ Command 

//also, make sure bit 0 is Set โ€˜1โ€™
UpperByte = i2c_read(ACK);          // READ 8 bits 
//and Send ACK bit
LowerByte = i2c_read(NAK);          // READ 8 bits 
//and Send NAK bit
i2c_stop();                         // send STOP command

The Rust I2C trait only lets me do Readand Write operations, with automatic start and stop commands. But it looks like I need to have control over start and stop commands in order to implement the required protocol. Anyone got an idea? Is there a better place to discuss these issues than this issue?

The Python I2C module supports start/stop parameters, maybe the Rust HAL could be extended?
This is how they do it:

        self.buf[0] = 0x05
        with self.i2c_device as i2c:
            i2c.write(self.buf, end=1, stop=False)
            i2c.readinto(self.buf, start=1)

Source: https://github.com/adafruit/Adafruit_CircuitPython_MCP9808/blob/master/adafruit_mcp9808.py

@MrBuddyCasino: It seems, that the read/write functions from the embedded-hal traits accept u8 Slices, so you should be able to send and receive more then one byte without sending stop commands. Anyhow, a better place to discuss this would be users.rust or the #rust-embedded channel, I think.

I'm not an I2C expert, but start/stop conditions are transitions of SDA while SCL is high, while during regular data transmissions, SDA is only allowed to change while SCL is low and remains stable when SCL is high. So I suspect that won't work.

Trying my luck in #rust-embedded, thanks!

@MrBuddyCasino I think you need something like this.

let mut buff: [u8; 2] = unsafe { mem::uninitialized() };
self.i2c.write_read(AddressByte >> 1, &[0x05], &mut buff)?;
let (UpperByte, LowerByte) = (buff[0], buff[1]);

Thats exactly the code I came up with :)

dbrgn commented

I started writing a driver for the SHT{21,22,25} temperature/humidity sensors: https://github.com/dbrgn/sht2x-rs

The code is very much inspired by @wose (nice and clean code for the SI7021!). It seems that the SI7021 made their sensor compatible to the SHT2x, correct? I'd suspect that it still makes sense to create a separate driver though (there might be some details that differ?), unless @wose can convince me of the opposite.

(Edit: For example, it seems that the SI7021 has separate I2C commands to control the heating element, while the SHT2x uses the user register for that, correct?)

wose commented

@dbrgn I think the SHT2x (and HTUxx) can and should be supported by the si7021 driver crate. Actually, measurements should already work if you're using this. The SHT and HTU sensors support a subset of the SI7021 features. The heater control (on/off) is controlled by the same bit (bit 2 of the UserReg) for SI, SHT and HTU, but the SI7021 has an additional register to configure the heater. There are some other differences, but they could all be fleshed out as separate traits and implemented for those sensors who support the feature. At least that's what I had planned to do... soon-ish.


I'm still unsure about how we should name sensor crates which support many sensors from different vendors:

  • si7021 seems quite explicit and doesn't suggest it supports any other sensor
  • si702x suggests only some sensors from the same vendor are supported
  • rh-t-sensor is way too vague

I tend to keep the name as si7021 is the sensor of this family with the most features (AFAIK) and add all other supported sensors to the documentation and as keywords so they are discoverable.

@wose

I'm still unsure about how we should name sensor crates which support many sensors from different vendors

Idea: Create one crate per supported sensor, make their names extremely specific. Have all those crates consist of a single statement that re-exports everything from a weirdly named master crate.

(Not sure myself how serious I am with this suggestion. Seems a bit spammy, but definitely helps with discoverability.)

Wouldn't crates.io/Cargo.toml keywords work for this?

@lnicola To a degree, yes. But if the crate name is either too general, or specific to the wrong sensor, then a potential user might be put off at first sight, simply because they don't understand that this is the crate they need.

@hannobraun The description field (and a README) can probably clear things up, as the first is shown in the crates.io search results, and the latter is visible on the crate page and most likely in the source repository.

I feel that making a generic crate, then one per sensor would create more confusion.

Anyway, this seems a bit off-topic, maybe we could create another issue for defining some guidelines about discoverability and handling similar devices?

@lnicola

Anyway, this seems a bit off-topic, maybe we could create another issue for defining some guidelines about discoverability and handling similar devices?

Good idea! Could you open an issue an tag me there? I would do it myself, but I'm on my way to bed right now (and would already be there, if I hadn't left my email client open :-) ).

Great to hear about what everyone is working on! I hope everyone is as excited as I am.
I've pushed my first PR on the stm32f103xx-hal repo (#56) to support the different flash/ram densities on that chip. It works, but can be better. This is also a prelude to my plan to tackle stm32f103xx-hal Issue #37 to specify pin configurations.

I have finally started to re-factor my HD44780 driver clerk to use the traits from embedded-hal. The good news, it was really easy to get it working on STM32 (arm-cortex), without the embedded-hal traits at first. After that I was able to replace my custom Delay trait with the one from embedded-hal. If anyone is interested, there is an issue for discussion and tracking the current state of this re-factoring.

Just posted a new driver for the I2C based TI INA260 power monitor. It's available here: https://crates.io/crates/ina260

Drivers should be published under the same license as embedded-hal and cortex-m-rtfm which is:

Licensed under either of

at your option.

It is important that the ecosystem grows under the same license! If you agree with me, the question arises if and how we could enforce this?

One way to go: We set up an "official repository" to create an incitement for developers to become part of it. License compliance would be the first condition to get a driver accepted. In case we later add quality criteria as acceptance condition, this "official repository" should be managed in a democratic way.

@therealprof Could you consider adapting your license to Apache/MIT?

@getreu I really don't care too much about licensing. I picked 0BSD at some point because it seems to be one of the most liberal licenses out there and explicitly excludes liability which is really the only thing I actually do care about. I absolutely don't want to waste my time with licensing crap and games, so love it or leave it; or if you really care: take the source and re-release it under a different license -- 0BSD allows you to do that.

In a professional environment the license is of utmost importance. When you start a project and choose an ecosystem for embedded development you need to make sure that all code and drivers are released under a compatible license.

A common license policy is not only supporting our vision (To improve the productivity of embedded software development teams) but also constitutes the condition sine qua non for professional suitability. Linux wouldn't have been successful in a professional environment without a common license policy.

dbrgn commented

@getreu yes, the use of permissive licenses (which are generally compatible among each other) is important if you want your code to be used by companies. however, whether the library authors use MIT, or BSD, or Apache 2, or a combination of them or something else, should be up to them.

@getreu Compatible: yes, identical: no. And I absolutely don't get your "Linux" point, are you talking about the kernel or the ecosystem?

Embedded work is often Big Company work, and I've learned they hate one thing: the GPL (even LGPL). Never had issues with the permissive ones, be it MIT / BSD / Apache / Mozilla or whatever, so I don't see the value of enforcing a standard.

So maybe no GPL and a suggested but not required permissive standard license?

@therealprof

Compatible: yes, identical: no.

@MrBuddyCasino

Never had issues with the permissive ones, be it MIT / BSD / Apache / Mozilla or whatever

A license is a legal agreement. Unfortunately "permissive" and "compatible" are no legal concepts. In general when someone assembles code with different licences, he needs to make sure that his usage does not violate any of the licences. In other words, you have to comply with all of them. This needs to checked against the business model that is subject to change. Without a layer next to you, many different licenses becomes a risky enterprise because your attack surface gets bigger with every licence you add to your code base. In doubt professionals will not opt for an ecosystem where the legal side is risky or somehow unclear.

@therealprof

And I absolutely don't get your "Linux" point, are you talking about the kernel or the ecosystem?

Kernel.

In doubt professionals will not opt for an ecosystem where the legal side is risky or somehow unclear.

Is this something you have experienced or something that you think might be an issue?

If we all agree with:
@dbrgn

yes, the use of permissive licenses

... it should not hurt anybody to chose the same than the Rust language and RTFM. A professional user will always prefer a code base with a coherent, simple and clear license policy.

@getreu As an OSS developer and "professional" user for well over 20 years now I find your authoritative stance rather disconcerting. I deserve the right to publish my code under which ever license I please, especially when it's even clearer, simpler and more permissive than the ones suggested here.

@getreu @therealprof @dbrgn @MrBuddyCasino

Would you mind opening up a separate issue to discuss this? It seems that there are a couple different views here, and it might make sense to discuss that in a single place, rather than on this issue.

@therealprof
Yes, you deserve it!

My claim is that a coherent, simple and permissive license policy helps to introduce this project in the professional space.

Would you mind opening up a separate issue to discuss this?

Agreed. I opened #57 and copied my comments there. @thejpster , @dbrgn , @jamesmunns , @MrBuddyCasino , @therealprof : if you could do the same then your arguments will not get lost.

I am planning on doing an I2C driver for JHD1313M1 Controller for HD44780-based Displays and an I2C driver for MMA7660FC based 3-Axis Digital Accelerometer(ยฑ1.5g)? Is anyone already working on this?

@rahul-thakoor I don't know how the JHD1313M1 controller works, but if it only uses a non-parallel interface and the same control codes as specified in HD44780 spec, then you could use my driver clerk and you only would have to implement a couple of traits (currently three I think).

@kunerd Hey thx! I believe you are refactoring the driver to be embedded-halcompatible. I will try the implementation for JHD1313M1 controller later on

I'm working on an ssd1306 driver here

@scowcron Great stuff. I guess you beat me to it and it's much cleaner than my version. Have to check whether I can use my character display on top of it.

@therealprof thanks, still WIP but it's getting close to 0.1

dbrgn commented

Here's my MCP3425 driver. It's a low-current 16-bit IยฒC ADC with an internal voltage reference.

The driver is not yet fully done, so far only one-shot measurements work. I'll have to look into continuous mode, but I'm not actually sure how nicely that's implementable with a blocking API.

By the way, is there a nice way to mock the embedded-hal APIs? I'd like to unit test my library with different IยฒC return values to make sure that the detection of positive/negative saturation works properly...

dbrgn commented

Ok, I finished the implementation of the MCP3425 driver. Feedback is welcome. Now I have a few comments and questions about the implementation (exploring the design space). It's probably a bit long, but might be interesting for other driver implementations.

Any feedback is very welcome, since I'm using this driver as a playground to learn to write a device driver in Rust that's as close to perfect as possible ๐Ÿ™‚

(Edit: Moved text to separate issues at https://github.com/dbrgn/mcp3425-rs/issues)

@therealprof (ina260, mag3110) @yuri91 (ili9341) @dbrgn (mcp3425)

Y'all have release a driver crate on crates.io tagged with the embedded-hal-driver keyword. If any of you doesn't plan to do a blog post or any other kind of announcement about your driver crate let me know so that I can move your crate to the "Released" list! (see issue description).

@dbrgn I would suggest moving your comment to the issue tracker of your driver crate and continuing the discussion there; otherwise this thread will to go off topic.

Low level IยฒC access

That sounds like something that rust-embedded/embedded-hal#50 might be able to handle.

@japaric No plans to do a blog article on the INA260 alone. I wanted to create an application using the INA260 and the SSD1306 and write a blog article about writing real world applications but this is blocked on a decent solution for rust-embedded/embedded-hal#35.