biemster / st17h66_RF

Low power experiments with RF only init for st17h66, no SDK or BLE stack
5 stars 1 forks source link

Try ZigBee! #7

Open biemster opened 1 year ago

biemster commented 1 year ago

The code mentions zigbee baseband:

#define PKT_FMT_ZIGBEE                              0
#define PKT_FMT_BLE1M                               1
#define PKT_FMT_BLE2M                               2
#define PKT_FMT_BLR500K                             3

try to get it to send zigbee packets.

natschil commented 1 year ago

I tried to adapt the code from https://github.com/thinnect/node-platform/tree/master/h1000 to this setting, but unfortunately did not reach a state where my zigbee packet sniffer registered anything. Would really exciting if this were possible though.

biemster commented 1 year ago

I ordered a CC2531 dongle to help test this, but I'm not sure anymore if that was the right choice. What sniffer are you using?

natschil commented 1 year ago

I'm also using a CC2531 dongle. There are number of firmwares you can use, but be aware that you need either a CC debugger or an ESP8266 to flash it. The dongle I'm using runs some kind of weird firmware that is quite poorly documented, but lsusb shows it as "0451:16a8". I'm able to sniff traffic with

./zboss_sniffer -i /dev/ttyACM0 0 12 - | wireshark -k -i -

I'm not sure where the zboss_sniffer executable is from, a friend shared it with me and it seems to work.

biemster commented 1 year ago

Great! when mine arrives, I'm going to prioritize this.

natschil commented 1 year ago

Good news! I'm able to send IEE 802.15.4 packets and receive them with the sniffer :)

biemster commented 1 year ago

That's awesome work @natschil! Looking forward to a repo/PR :smile:

natschil commented 1 year ago

The current implementation is a bit flaky because it stop working if there isn't a debug statement right after I send the packet.

natschil commented 1 year ago

Here is the branch: https://github.com/natschil/ST17H66_Experiments/tree/zigbee_experiments

Somewhat bizarrely, in the following code:

    ZigbeeSetChannel(g_physicalLayerInformation.channel);
          prepareZigbeeBroadcastPacket(&g_physicalLayerInformation, &g_currentPacketInformation);
          PhysicalLayerSendRawPacket(&g_currentPacketInformation);

         dbg_printf("For some reason I need this here");
          osal_start_timerEx(g_physicalLayerTaskId, PPP_PERIODIC_TX_EVT, g_physicalLayerInformation.txIntervalMs);

Both ZigbeeSetChannel and dbg_printf is necessary.

biemster commented 1 year ago

Does a WaitRTCCount(nTicks) work as well instead of the dbg_printf? This might be some timing issue, or something with interrupts. Very curious indeed. Where did you find the ZigbeeSetChannel? (wait I'll check your code first)

natschil commented 1 year ago

it's somewhat similar to https://github.com/thinnect/node-platform/tree/master/h1000 (see zb_set_channel radio.c there).

natschil commented 1 year ago

yes, e.g. WaitRTCCount(100) does the trick.

natschil commented 1 year ago

I find it a bit hard to follow the naming in embedded C projects since there seems to be an abbreviation for everything. I tried for a while to be able to compile with C++, but then gave up. Apologies for the significant change in naming to your code.

biemster commented 1 year ago

Yeah for exactly this reason I'm rewriting all the SDK stuff to single file, and when it works the way I want I (plan) to structure it a bit again. Also, this SDK is from a time before naming conventions were invented I think..

natschil commented 1 year ago

Zigbee is working quite nicely, I'm able to send/receive packets to the point where I can associate with the network. Actually sending "real" zigbee packets is quite challenging because the devices I have all seem to support encryption; something I would prefer to avoid for now...

biemster commented 1 year ago

Very impressive, great work! I hope my cc2531 arrives soon :)

natschil commented 1 year ago

You probably know this already, but you'll additionally need a zigbee coordinator as the main node of your network if you don't already have one.

biemster commented 1 year ago

That's good to know, I actually don't have any zigbee things yet. My plan is to just run the cc2531 as a monitor, and have the tags send a single and unique packet (maybe with some extra data like pin state). And have the machine with the dongle push that to MQTT. So I guess this is basically raw 802.15.4 instead of zigbee.

biemster commented 1 year ago

Got my cc2531 today! fun weekend ahead!

biemster commented 1 year ago

I'm also using a CC2531 dongle. There are number of firmwares you can use, but be aware that you need either a CC debugger or an ESP8266 to flash it. The dongle I'm using runs some kind of weird firmware that is quite poorly documented, but lsusb shows it as "0451:16a8". I'm able to sniff traffic with

./zboss_sniffer -i /dev/ttyACM0 0 12 - | wireshark -k -i -

I'm not sure where the zboss_sniffer executable is from, a friend shared it with me and it seems to work.

This repo: https://github.com/MartinoTommasini/ZBOSS_extended seems to contain a zboss_sniffer, I'm going to try that.

pavel-baka commented 6 months ago

I'm not sure I understand this issue, but I see that zigbee is being mentioned and the CC2531 on a project that mentions GCC - have you discovered a way to compile zigbee code on GCC for the CC2531?

biemster commented 6 months ago

No, this is about the Lenze st17h66. This is a bluetooth chip but the SDK had references to a Zigbee mode, and @natschil brilliantly managed to have the st17h66 send and receive Zigbee frames. The cc2531 is only mentioned because I had 0 Zigbee devices, and I needed one to start debugging this mode on st17h66.

pavel-baka commented 6 months ago

interesting. this is using some kind of Zigbee library? Is it compatible with linux development?

pavel-baka commented 6 months ago

i have been looking for a zigbee library for a diy project for cc2531. If this chip works also I use it instead

biemster commented 6 months ago

there is no zigbee library or anything, you should check out @natschil 's fork (I still did not have time to look into this at all). It should compile with GCC, but again, I did not try it yet.

natschil commented 6 months ago

@pavel-baka : There is unfortunately no ZigBee library/sdk, but in principle it is possible to send zigbee frames with the ST17H66. It's actually quite a versatile chip, and since it has AES support it's possible to send encrypted zigbee frames (see also https://www.lenzetech.com/public/store/pdf/jsggs/ST17H66B2_BLE_SoC_Datasheet_v1.1.2.pdf for further capabilities). If you go through the issues here and through some of the related projects on github and the issues there you'll find some more discussion including how to source this chip (you can get a full system you can flash on some ble dongles for O(3€).

Unfortunately I haven't had time to work on this and won't have time in the near future either. Therefore sharing some of the technical details below so that they can be used by others. I screwed up my local repo unfortunately so I don't really have a working code state anymore :see_no_evil:

As @biemster mentioned it is possible to send IEE 802.15.4 frames, basically you need to call something like

    ll_hw_rst_rfifo();
    ll_hw_rst_tfifo();
        ll_hw_set_stx();
    ll_hw_set_trx_settle(PHYSICAL_LAYER_HW_BB_DELAY, PHYSICAL_LAYER_HW_AFE_DELAY, PHYSICAL_LAYER_HW_PLL_DELAY); 

     ll_hw_write_tfifo(&packet->bufferTransmit[0], packet->bufferTransmit[0]);
     ll_hw_go();

To receive you need to constantly set the zigbee channel, otherwise it doesn't work.


 if (g_physicalLayerInformation.Status == PHYSICAL_LAYER_RX_ONLY || g_physicalLayerInformation.Status == PHYSICAL_LAYER_TXACK)
    {
        return;
    } 
    else if (g_physicalLayerInformation.Status == PHYSICAL_LAYER_TX_ONLY)
    { 
        // not ok in irq zb_hw_stop(); // if in tx state, abort the tx first
    } 
    g_physicalLayerInformation.Status = PHYSICAL_LAYER_RX_ONLY;
    ll_hw_set_rx_timeout(rxTimeoutUs);
    ll_hw_set_srx();
    ll_hw_set_trx_settle(PHYSICAL_LAYER_HW_BB_DELAY, PHYSICAL_LAYER_HW_AFE_DELAY, PHYSICAL_LAYER_HW_PLL_DELAY);

    // reset Rx/Tx FIFO
    ll_hw_rst_rfifo();
    ll_hw_rst_tfifo();
    ll_hw_go();

  uint32_t rfChnIdx = (chn - 10) * 5;

  if (g_rfPhyFreqOffSet >= 0) {
    PHY_REG_WT(0x400300B4,
               (g_rfPhyFreqOffSet << 16) + (g_rfPhyFreqOffSet << 8) + rfChnIdx);
  } else {
    PHY_REG_WT(0x400300B4, ((255 + g_rfPhyFreqOffSet) << 16) +
                               ((255 + g_rfPhyFreqOffSet) << 8) +
                               (rfChnIdx - 1));
  }             
  ll_hw_ign_rfifo(LL_HW_IGN_CRC);

  uint8_t channelIndexNow = PHY_REG_RD(0x400300B4) & 0xFF;

    ll_hw_rst_tfifo();
    ll_hw_rst_rfifo();
    //set_max_length(0xff);

    ll_hw_go();

    llWaitingIrq=TRUE;

One thing I spent a long time debugging is that if you send and ACK packet you really don't have much time to do it. Basically you need to immediately send an ACK back before any further processing, otherwise the receiving hardware won't accept it.

I tried to implement part of the zigbee encryption, see here: https://gist.github.com/natschil/976e0685aa49e7d2956fee1df9084862

The other thing I discovered (if you want to go down this rabbit hole) is that you can use the XIP part of the flash memory to store more code, the relevant files are here: https://gist.github.com/natschil/12f90320ff3c2a70711f378eef7738cb

Apart from that I didn't go too much beyond @biemster's very cool repo at https://github.com/biemster/st17h66_RF . There is a lot of information in various threads around here.

pavel-baka commented 6 months ago

i will see if i can buy this chip somewhere and have a look what can be done

biemster commented 6 months ago

You might have already come across this as well, but the esp32-c6 supports zigbee too. I just received mine in the mail, I'll start testing it soon. Support for the esp32 line is of course orders of magnitude better than the st17h66, and to be honest way better than for the cc2531 as well.

natschil commented 6 months ago

That's interesting. But the power consumption there seems almost an order of magnitude higher than the ST16H66, right?

biemster commented 6 months ago

They indeed burn a lot of power, if that's a concern the esp32 is not the best choice. Although they are pretty good at sleeping nowadays, so if it does not have to be always on in your application it still might be worth a look.

pavel-baka commented 6 months ago

@natschil : the flashing script you shared doesn't work, its stuck at Response is: b'by hex mode:' sent c2 (len=0)

natschil commented 6 months ago

It's been a while since I touched this code, but the flashing code I linked essentially adds the ability to write to the xip sections. Maybe those are empty (len=0)? See also the discussion in https://github.com/biemster/st17h66_FindMy/issues/4

natschil commented 6 months ago

not sure if it's of any help, but there may also be relevant information here: https://github.com/biemster/st17h66_blinky/issues/4

natschil commented 5 months ago

@pavel-baka : with the upcoming github 2fa changes I'm cleaning up my github a bit since I'm not sure I'll make the switch. Since I don't think anyone is using it, I'll probably also delete my fork of @biemster 's repo. It doesn't contain anything ground-breaking (just some relatively small changes to the repo that send out IEEE802.15.4/Zigbee packets), but if you need it please copy it before.