Giter VIP home page Giter VIP logo

cc1101's Introduction

cc1101

A platform agnostic driver to interface with the CC1101 (Sub-1GHz RF Transceiver)

What works

  • Configuring radio for reception, and reading data.

TODO

  • Sending data, but only have one module.

License

Apache License, Version 2.0 (LICENSE or http://www.apache.org/licenses/LICENSE-2.0)

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be licensed as above, without any additional terms or conditions.

cc1101's People

Contributors

andrei-basarab avatar chocol4te avatar dsvensson avatar qwandor avatar sebkuzminsky avatar zancas avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cc1101's Issues

Add support for Wake-On-Radio

Wake-On-Radio is a low energy mode that would be nice to utilize, especially when running on battery. As I'm using my CC1101 with a Raspberry Pi, this is outside my current use case.

Read Status Byte when communicating on SPI

According to the CC1101 datasheet, chapter 10.1 Chip Status Byte

When the header byte, data byte, or command strobe is sent on the SPI interface, the chip status byte is sent by the CC1101 on the SO pin. The status byte contains key status signals, useful for the MCU.

  • Read status byte on each SPI transaction
  • Interpret status byte with corresponding data typing
  • Implement a function for the user to get the last chip status byte

Try to trim down what data goes into buffer on receive

When calling receive(...) the buffer is filled like:

| len | addr | payload ...............   |

It would be nice if buf[0] was the first byte of the payload as an API user. Perhaps len could be returned, as is common with read functions. It's probably interesting to access addr, if address filtering is set to both self and various broadcast addresses, it could be an ref param just like buffer, rssi, and lqi. Should experiment with multiple reads/transfers or something.

An alternative that I'm not sure if it works, would be to change set_packet_length to take ownership of a buffer, rather than just setting a length. This would set the length according to the buffer and use this buffer in receive. For this to work, there would have to be some lifetime voodoo to guarantee that receive(...) is not called again as long as the buffer is borrowed from the API. The buffer could be wrapped in something with methods for requesting address, length, LQI, and RSSI... but it has to have a known lifetime, I doubt it would work, but who knows. If it works, it has the upside that it would only require one SPI transfer.

Unify the read/write functions

(read|write|modify)_register, _strobe, _burst takes narrowly typed as arguments. This is somewhat annoying as the only difference is that they or in some access offset to the address, and transfer buffers of various sizes. Probably quite a few loc's to remove.

Experiment with removing more defaults

Most defaults should be removed in favor of adding proper API methods. As the primary user of this crate is my sparsnas-rs, investigate if it still works if I leave more registers at their default values. The original list of defaults were extracted from various other project, and many have been removed thanks to API methods, and general reasoning / docs reading.

Add timer support for various timeouts

The embedded-hal eco system defines a concept of timers. This should be passed into the constructor like the SPI and CS structures, and used in for example receive(...).

Create a lowlevel module that the cc1101 module uses

Move all low level types, register declarations etc to a lowlevel module, perhaps even a separate crate, that only exposes register interaction functions and the types.

The high level API will likely never be able to fully cover what the radio module is capable of, so better to have a nice high level API that fits common use cases, and then a way into the guts where API user will perform all initialization, but at least have register fields and low level types available.

Add support for CC1111

Are there any plans to support the CC1111 or any other similar chips in the same family with this crate? Interested in using something like this to play with the Yardstick One from Great Scott Gadgets.

Create a low level SPI interaction owner

The idea is to make the current cc1101::Cc1101 type a simple high level API on top of a low level API. The low level API should provide the basic hand holding and constraints that can be modelled in rust without making any radio module usage impossible. #21 moved all the raw types and register declarations to a sub module, this is the remaining work on top of that.

Come up with better names for SyncMode::*

Right now SyncMode members are defined as follows:

pub enum SyncMode {
    Disabled,
    Check15of16(u16),
    Check16of16(u16),
    Check30of32(u16),
    DisabledCarrierSense,
    Check15of16CarrierSense(u16),
    Check16of16CarrierSense(u16),
    Check30of32CarrierSense(u16),
}

These names are close to the CC1101 spec, but they're not particularly meaningful.

The CheckXXofYY denote that XX number of bits should be checked in the YY bits of the sync word. The sync word is 16 bits long, and in the case of YY=32, the sync word is repeated. Then the *CarrierSense versions are the same as the first ones, except that they add CarrierSense into the mix. There must be better names, and perhaps it's possible to split it, or perhaps it should be two functions. set_sync_mode(SyncMode), and set_sync_mode_carrier_sense(SyncMode).

Maybe:

pub enum SyncMode {
    Disabled,
    MatchPartial(u16), // 15of16
    MatchRepeated(u16), // 30of32
    MatchFull(u16), // 16of16
}

..and it would map to the corresponding with/without CarrierSense register values.

Maybe just remove the CarrierSense for now. It could be that there should be some other API for controlling CarrierSense, which also controls gain etc (17.4 in spec), and this other function works in tandem with the current sync mode setting.

(read|modify|write)_register should take/return typed structures rather than u8

The following code:

        self.modify_register(config::Register::MDMCFG2, |r| {
            MDMCFG2(r).modify().sync_mode(mode.value()).bits()
        })?;

... should ideally not mention MDMCFG2 in the body, nor modify():

        self.modify_register(config::Register::MDMCFG2, |r| {
            r.sync_mode(mode.value()).bits()
        })?;

And similarily, calling self.read_register(config::Register.:MDMCFG2) should return a MDMCFG2 rather than an u8.

Can probably be fixed by introducing some good traits. Figure out how.

CRC check may stop working, requiring power cycle

Sample from sparsnas-rs:

len: 11 addr: 3e data: 070ea27ae979e7dc66d447dbe79ce4 len: 15, ok: true, 73 c2
 11 3e 7c  40de   0009693e 377e 1554    000b45ef 64 # Current power: 675
len: 11 addr: 3e data: 070ea27ae979e7dd66dc47dbe781e4 len: 15, ok: true, e8 c2
 11 3e 7f  40de   0009693e 377f 155c    000b45f2 64 # Current power: 674
len: 11 addr: 3e data: 070ea27ae979e72266dc47dbe786e4 len: 15, ok: true, d4 c2
 11 3e 00  40de   0009693e 3780 155c    000b45f5 64 # Current power: 674
len: 11 addr: 3e data: 070ea27ae979e726676247dbe472e4 len: 15, ok: true, da c2
 11 3e 04  40de   0009693e 3784 14e2    000b4601 64 # Current power: 689
len: 11 addr: 3e data: 070ea27ae979e72766c047dbe470e4 len: 15, ok: true, e9 c2
 11 3e 05  40de   0009693e 3785 1540    000b4603 64 # Current power: 677
len: 11 addr: 3e data: 070ea27ae979e72a67e047dbe47ee4 len: 15, ok: true, d7 c2
 11 3e 08  40de   0009693e 3788 1460    000b460d 64 # Current power: 706
len: 15 addr: 3e data: 070ea27ae979e72b677c47dbe47ce4 len: 15, ok: false, 1e 22 // bad?
len: 11 addr: 3e data: 070ea27ae979e728677a47dbe461e4 len: 15, ok: false, e8 1e
len: 11 addr: 3e data: 070ea27ae979e729669047dbe466e4 len: 15, ok: false, e1 1e
len: 11 addr: 3e data: 070ea27ae979e72e67f047dbe46be4 len: 15, ok: false, e7 1e
len: 11 addr: 3e data: 070ea27ae979e72f601447dbe468e4 len: 15, ok: false, e8 1e
len: 11 addr: 3e data: 070ea27ae979e72c60cc47dbe46de4 len: 15, ok: false, db 1e
len: 01 addr: 3e data: 47470ea27ae979e72c60cc47dbe46d len: 15, ok: false, db 1e // bad
len: 11 addr: 3e data: 070ea27ae979e73367f447dbe454e4 len: 15, ok: false, eb 1e
len: 11 addr: 3e data: 070ea27ae979e73067b647dbe459e4 len: 15, ok: false, e5 1e

Restarting the app does nothing. Fixed by power cycling. Not sure why. The 15 length seems a bit funny, could it be that something needs to be done when CRC fails, that stays even SRES is strobed. There is also some register flag to filter packets that don't pass CRC-check iirc.

Maybe the trigger of this is an RX overflow. The buffer passed in is just 21 bytes, and 0x15 = 21, but then there's also the length byte and address byte. Perhaps max packet length should be set to 23 here, and some packets are actually larger in the Sparsnäs protocol.

Add a simple Linux example

Add an example that transmits one packet, and another example that receives this packet using linux-embedded-hal.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.