Sunday, November 10, 2019

Gateway 2 software updates

I've started to port some of the old libraries written for AVR architecture to new STM32 for new gateway with compatibility in mind. My goal is to still use Arduino based nodes for senors, authentication or relays, just because it's easy to implement new features quickly.

One of my the first and probably most used is RS485 wired library that manages communication over one pair of twisted wires. USART STM32 libraries in ChibiOS are divided to Low Level Driver and API. There are two ready to use USART both of the suitable for different kind of messages. One DMA based somehow preferring fixed messages and second, similar to Arduino serial, with queues and it's based on interrupts. I started to play with both, but I found rather difficult to build logic on top these APIs without changing internals. And because of this, I started with provided serial interrupt driven driver and created new RS485 library for STM32F4 MCU.

Luckily for me, really :), the SMT32F4 has build in logic that fully support my old RS485 library functionality. STM32F4 support not only 9 bit Multi Processor Communication as AVR, but it also provide interrupt on address match. Luckily again, the address register uses 4 bits wide target address, same as my old library, and it verifies 4 least significant bits of incoming header to 4 bits of defined address. Just perfect match, except the STM32 cannot reply the broadcast packets. Which is in reality not a problem for master at all, since only master do send broadcast packets, and every node know master address (0).

But of course writing a new driver for a new architecture was not easy. Thankfully to ChibiOS, I've managed to do so. As side effect, I must say that AVR debugging really sucks, because there is simply none. And once you learn to add breakpoints, stop program at certain line, and see at least some variables and registers, you do not want to go back. But back to new driver, in addition to compatibility between Arduino and STM32, I have also implemented acknowledgment, a feature that was not finalized in old library. And the ACK functionality is automatically performed by LLD on both receiving and sending.

Such ACK functionality also require appropriate changes in AVR side. At first I created incoming and outgoing ACKs directly in sketch. It was functional, but somehow slow, and I was a bit worried about the sketch complexity. And I've decided to update the AVR library according to STM32, I've added driver state and after a few long evenings, I hope I finally manged to do so.

The final packet structure is same to existing one:

* A * P * X * D0 ~ D63 * C0 ~ C1

- Required part
~ Optional data and CRC

A Address - 4 bits from and 4 bits to address.
   0  is master.
   15 is broadcast to all.
   14 addresses left for nodes.

P Packet definition - 2 bits type and 6 bits length.  
  Types: CMD - Command - user defined general commands value 0 - 6
          DTA - Data - user data length D0 - D63 and CRC S0, S1
          ACK, NACK - flags for data, using signature of data packet
X XOR of A and P, for basic transfer safety.

D0 - D63 user data.    
C0 ~ C1  CRC for user data or signature for ACK, NAK. 
Basically it allows two kinds of transfers. First is command mode with value 1 to 63. Command 0 is reserved for ACK functionality. These can be used for some simple repetitive messages and expect predefined action or response. I use, for example, command = 1 to request full node functionality descriptor, i.e. request for registration. When gateway receive valid sensor data from unknown node, it issue CMD 1 to that address to receive its full descriptor.

Second use, is data transfer with maximum length of 64 bytes. It is completely up to the user, what kind of data are transferred. Every data packed is secured by CRC16 and ACK functionality compare these CRC and in case of mismatch invalidates the packet.

On the end I'm happy that new OHS gateway is slowly adopting old functionalities and further improving them.