Device mockups overview - PW-Sat2/PWSat2OBC GitHub Wiki

Purposes

Mockups hardware schematic

 ---------          -----------------------------          ----------
 |       |   I2C    |                           |    USB   |        |
 |  OBC  | <======> |        DeviceMock         | <======> |   PC   |
 |       |    ||    |                           |          |        |
 ---------    ||    -----------------------------          ----------
              ||
              vv
         ------------
         |          |
         |  Logic   |
         | Analyzer |
         |          |
         ------------

Hardware parts:

  • OBC dev board - EFM32GG990F1024
  • DeviceMock
    • ATmega88PA
    • FT-X
  • [Optional] Logic Analyzer (Saleae etc.)

Interfaces

  • Mock exposes I2C interface as slave
  • Communication with PC is done using serial port (FT-X chip)

Headers

_ TODO: Photo _

  • H1 - 2x all interfaces (GND, I2C, SPI, 2xCS) for connection with other devices
  • H2 - 2x all interfaces (GND, I2C, SPI, 2xCS) for logic analyzer
  • H3 - Power (GND, 3.3V)
  • H4, H5 - GPIO
  • H6 - Serial port lines (TXD, RXD, CTS, RTS)

Overview

AVR acts as a catch-all slave device. Relaying on I2C clock streching is communicates with PC using UART. Software on PC can interpret and prepare response that will be sent back to master device. It is also possible to cause some faults on I2C bus like disabling address acknowledge (resulting in NAK) or freezing (resulting in SCL latched at low level).

Control protocol

Overview

PC is communicating with DeviceMock using serial port (baudrate 100000, RTS/CTS flow control) with protocol based on commands.

Each command send from DeviceMock to PC is in format:

1 byte 1 byte DataLength bytes
Command Code DataLength Data

Commands send from PC to DeviceMock uses similar format

1 byte 1 byte 1 byte DataLength bytes
S Command Code DataLength Data

To allow recovery from invalid state (like partially received command) extra start character is needed (S) at the begining of command. Also each S in size/data needs to be escaped by prepending it with another S (e.g. XSZ should be sent as XSSZ).

Commands

Direction Name Code Data
Mock -> PC Version 0x1 Version
Mock -> PC Write 0x2 Address Data
PC -> Mock ReadResponse 0x3 Data
PC -> Mock I2C Disable 0x4 None
PC -> Mock I2C Enable 0x5 None
PC -> Mock Restart 0x6 None
PC -> Mock I2C Free 0x7 None
PC -> Mock Stop 0x8 None
Mock -> PC Stopped 0x9 None

I2C transfer flow

I2C write-read transfer is composed by few steps:

I2C bus DeviceMock action PC action
Write address issued Data collecting start
N-bytes received Data is being accumulated
STOP condition Data is sent to PC Data is received and response is generated
Read address issues (clock stretching) Awaiting data When response is ready, it is sent back to Mock
Clock stretching Response received from PC
N-bytes written Data is sent byte-by-byte to I2C

Python mocks

Usage of DeviceMock allows easy mocking of I2C devices. Actual implementation of all devices are handled with Python code.

Each device is represented by subclass for I2CDevice class. Writes to that devices are translated to calls of methods decorated with i2cMock.command. Parameter passed to that decorator are used to determine which method should be called. For example, given following methods:

@i2cMock.command([0x01, 0x02])
def method_1(a, b):
  pass

@i2cMock.command([0x03])
def method_2(a, *args):
  pass

transfers will result in:

  • [0x01, 0x02, 0xA0, 0xB0] -> method1(0xA0, 0xB0)
  • [0x03, 0xAB, 0x10, 0x20, 0x30] -> method2(0xAB, (0x20, 0x30))

Return value of each method must be None or byte array and will be sent to master in next read transfer

Mock is controled using I2CMock class which handles all details of communication protocol. After creation, objects handling each supported devices should be added using method add_device. It is possible to share the same object between mocks.

When mock is configured, background thread can be started by calling start method. This also ensures clean state of mock and enables I2C bus.

It is possible to disable I2C slave address acknowledge by calling disable method. Device can freeze itself using freeze method. Recovery from that situation is possible by using unfreeze method of I2CMock class

⚠️ **GitHub.com Fallback** ⚠️