Close
0%
0%

RPUpi - a shield for tool-chain at network edge

Connects a Raspberry Pi to a serial multi-drop bus.

Similar projects worth following
This Shield connects a Raspberry Pi to a serial multi-drop bus. It has a bus manager to select bootload targets.

A shield or mezzanine that is used to connect an SBC and my controller board to full-duplex serial using RS485 transceivers. The SBC's serial hardware is connected as a host to communicate with multiple controller targets (if their bus manager connected them). A half-duplex management line is used by the managers. The board has two RJ45 style connectors for use with CAT5 in either the T568A scheme or the T568B scheme.

  • ^5 Test Mode Self-Test Style From RPUno

    ronald.sutherland07/11/2019 at 18:38 0 comments

    If the RPUpi were to be integrated onto an RPUno, I would want it tested with a self-test.

    https://github.com/epccs/RPUno/tree/master/XcvrTest

    That was a lot of effort; the good news is that it should mostly copy to my other boards which I plan to gradually integrate this into (and then ditch all sorts of headers). The 40 pin R-Pi interface will be my path forward, I have grown comfortable with what the R-Pi foundation is doing.

    picocom -b 38400 /dev/ttyUSB0
    picocom v2.2
    ...
    Terminal ready
    RPUpi Transceiver Test date: Jul 11 2019
    avr-gcc --version: 5.4.0
    I2C provided address 0x31 from manager
    SMBUS cmd 0 provided address 49 from manager
    MISO loopback to MOSI == HIGH
    MISO loopback to MOSI == LOW
    SCK with Shutdown loopback == HIGH
    I2C Shutdown cmd is clean {5, 1}
    SCK with Shutdown loopback == LOW
    I2C Shutdown Detect cmd is clean {4, 1}
    
    Testmode: default trancever control bits
    I2C Start Test Mode cmd was clean {48, 1}
    I2C End Test Mode hex is Xcvr cntl bits {49, 0xD5}
    Testmode: read  Xcvr cntl bits {50, 0xE2}
    PWR_I /w no load using INTERNAL_1V1: 0.024 A
    
    Testmode: nCTS loopback to nRTS
    I2C Start Test Mode cmd was clean {48, 1}
    I2C End Test Mode hex is Xcvr cntl bits {49, 0xD5}
    Testmode: set  Xcvr cntl bits {51, 0xA2}
    Testmode: read  Xcvr cntl bits {50, 0x22}
    
    Testmode: Enable TX pair driver
    I2C Start Test Mode cmd was clean {48, 1}
    I2C End Test Mode hex is Xcvr cntl bits {49, 0xD5}
    Testmode: set  Xcvr cntl bits {51, 0xF2}
    Testmode: read  Xcvr cntl bits {50, 0xF2}
    PWR_I /w TX pair load: 0.044 A
    
    Testmode: Enable TX & RX(loopback) pair drivers
    I2C Start Test Mode cmd was clean {48, 1}
    I2C End Test Mode hex is Xcvr cntl bits {49, 0xD5}
    Testmode: set  Xcvr cntl bits {51, 0xD1}
    Testmode: read  Xcvr cntl bits {50, 0xD1}
    PWR_I /w TX and RX pairs loaded: 0.066 A
    RX loopback checked
    
    Testmode: Enable DTR pair driver
    I2C Start Test Mode cmd was clean {48, 1}
    I2C End Test Mode hex is Xcvr cntl bits {49, 0xD5}
    Testmode: set  Xcvr cntl bits {51, 0xE6}
    Testmode: read  Xcvr cntl bits {50, 0xE6}
    PWR_I /w DTR pair load: 0.044 A
    [PASS]
    

    RPUpi^5 Self-Test Style

  • ^5 SMBus with the R-Pi

    ronald.sutherland06/17/2019 at 18:20 0 comments

    First: on ^4 I should have connected the SPI nSS to R-Pi's CE00 pin (oops).


    I have been working on the Remote FW for this board, splitting the hulk into smaller parts so they can fit in my brain. Also adding I2C commands that control the bus manager, and trying out the SMBus interface... and then it happened. I did not have a clue what was going on, and it has taken far to long to understand. In short, the R-Pi zero has a problem with clock-stretching.

    http://www.advamation.com/knowhow/raspberrypi/rpi-i2c-bug.html

    After finally understanding the problem and getting past the sinking feeling, I had an idea.

    Interleaving between two buffers (A and B) within the twi ISR used by SMBus interface. And without much testing yet, it seems to have done the trick.  

    https://github.com/epccs/RPUpi/commit/089455a040c1aaae76031a735f9558047b78a573#diff-5bd95c1d69122d988a6f85757b66c817

    The buffer used by the ISR is swapped after passing it to the user (e.g., with receive callback function). The user receive function runs within the ISR context, but now it can be concise (e.g., save the pointer and byte count). Then all the work can be done outside of ISR context since the buffer is no longer in the risk of being changed, at least until a subsequent receive event when it will be swapped back into service.

    https://github.com/epccs/RPUpi/commit/089455a040c1aaae76031a735f9558047b78a573#diff-e5edda6dc80c252451acc1b2be91d078

    The quick receive event seems to be tolerated by the R-Pi's clock, but more testing is needed. The handle_smbus function is run in the main loop if there are SMBus bytes available.

    https://github.com/epccs/RPUpi/tree/master/Remote

  • ^4 updates

    ronald.sutherland09/22/2018 at 21:38 0 comments

    This update really only needed the SPI nSS connected to the Raspberry Pi's CE10 pin. The change of the transceiver was not really important, other than showing a different one that should work (if it works it cost less, but that is likely bait). Removed stuff (terminations, manager ADC6, and ADC7) for simplification. Routed I2C1 to the R-Pi SMBus so only populate this board with a ATmega328pb which was proven with RPUadpt^6 (a 328p will damage the R-Pi SMBus pins).

    What do you think about the slogan? I think "Intelligence at the network edge" was Intel's but my interest is more in having the tool-chain at the edge. It means I can bootload directly (not through an adversary) and no network stack so simpler microcontrollers are viable.

  • ^3 SPI Interface

    ronald.sutherland08/24/2017 at 06:16 0 comments

    Firmware SpiSlv is used to enable the SPI port on a RPUno (ATmega328p).

    After loading the firmware on an RPUno and enabling the AVR's SPI I next need the Raspberry Pi SPI hardware setup. Raspian needs its interface master driver enabled (e.g. raspi-config).

    Raspibin has an spi group setup in /etc/udev/rules.d/99-com.rules. So I can add my user name to that group for the system to allow me to use the interface.

    sudo usermod -a -G spi rsutherland
    # logout for the change to take
    

    Next I compile and run spidev_test.c on the Pi with:

    wget https://raw.githubusercontent.com/raspberrypi/linux/rpi-3.10.y/Documentation/spi/spidev_test.c
    gcc -o spidev_test spidev_test.c
    # run with
    ./spidev_test -s 100000 -D /dev/spidev0.0
    ./spidev_test -s 500000 -D /dev/spidev0.0
    ./spidev_test -s 1000000 -D /dev/spidev0.0
    ./spidev_test -s 2000000 -D /dev/spidev0.0
    spi mode: 0
    bits per word: 8
    max speed: 500000 Hz (500 KHz)
    0D FF FF FF FF FF
    FF 40 00 00 00 00
    95 FF FF FF FF FF
    FF FF FF FF FF FF
    FF FF FF FF FF FF
    FF DE AD BE EF BA
    AD F0
    

    Note: The output is offset a byte since it was sent back from the AVR. I see errors at 1MHz and 2MHz. The RPUpi^3 has a 74LVC07 buffer that pulls down through a 10kOhm resistor on SCK and MOSI. The circuit between that resistor and the AVR has some capacitance which will limit the speed (if there is a need for higher speed it may be possible to swap in a 1k resistor).

    SPI Evaluation

  • ^3 Bootload Remote AVR

    ronald.sutherland08/24/2017 at 06:12 0 comments

    Bootload Remote AVR

    The hostname of the Pi Zero is pi3, it was the third Pi Zero I have setup (it is a bad hostname). The default bootload address on the RPUftdi (e.g. my multi-drop RS-422 board) is '0', and I have not changed it, I keep the i2c-debug firmware on an ATmega328p board under the RPUftdi for use on my test bench, so I will just upload that same program compiled from the Pi Zero.

    rsutherland@pi3:~/Samba/RPUno/i2c-debug $ uname -a
    Linux pi3 4.9.41+ #1023 Tue Aug 8 15:47:12 BST 2017 armv6l GNU/Linux
    rsutherland@pi3:~/Samba/RPUno/i2c-debug $ make bootload
    avr-gcc -Os -g -std=gnu99 -Wall -ffunction-sections -fdata-sections  -DF_CPU=16000000UL   -DBAUD=38400UL -I.  -mmcu=atmega328p -c -o main.o main.c
    avr-gcc -Os -g -std=gnu99 -Wall -ffunction-sections -fdata-sections  -DF_CPU=16000000UL   -DBAUD=38400UL -I.  -mmcu=atmega328p -c -o i2c-scan.o i2c-scan.c
    avr-gcc -Os -g -std=gnu99 -Wall -ffunction-sections -fdata-sections  -DF_CPU=16000000UL   -DBAUD=38400UL -I.  -mmcu=atmega328p -c -o i2c-cmd.o i2c-cmd.c
    avr-gcc -Os -g -std=gnu99 -Wall -ffunction-sections -fdata-sections  -DF_CPU=16000000UL   -DBAUD=38400UL -I.  -mmcu=atmega328p -c -o ../Uart/id.o ../Uart/id.c
    avr-gcc -Os -g -std=gnu99 -Wall -ffunction-sections -fdata-sections  -DF_CPU=16000000UL   -DBAUD=38400UL -I.  -mmcu=atmega328p -c -o ../lib/timers.o ../lib/timers.c
    avr-gcc -Os -g -std=gnu99 -Wall -ffunction-sections -fdata-sections  -DF_CPU=16000000UL   -DBAUD=38400UL -I.  -mmcu=atmega328p -c -o ../lib/uart.o ../lib/uart.c
    avr-gcc -Os -g -std=gnu99 -Wall -ffunction-sections -fdata-sections  -DF_CPU=16000000UL   -DBAUD=38400UL -I.  -mmcu=atmega328p -c -o ../lib/twi.o ../lib/twi.c
    avr-gcc -Os -g -std=gnu99 -Wall -ffunction-sections -fdata-sections  -DF_CPU=16000000UL   -DBAUD=38400UL -I.  -mmcu=atmega328p -c -o ../lib/rpu_mgr.o ../lib/rpu_mgr.c
    avr-gcc -Os -g -std=gnu99 -Wall -ffunction-sections -fdata-sections  -DF_CPU=16000000UL   -DBAUD=38400UL -I.  -mmcu=atmega328p -c -o ../lib/adc.o ../lib/adc.c
    avr-gcc -Os -g -std=gnu99 -Wall -ffunction-sections -fdata-sections  -DF_CPU=16000000UL   -DBAUD=38400UL -I.  -mmcu=atmega328p -c -o ../lib/parse.o ../lib/parse.c
    avr-gcc -Wl,-Map,I2c-debug.map  -Wl,--gc-sections  -mmcu=atmega328p main.o i2c-scan.o i2c-cmd.o ../Uart/id.o ../lib/timers.o ../lib/uart.o ../lib/twi.o ../lib/rpu_mgr.o ../lib/adc.o ../lib/parse.o -o I2c-debug.elf
    avr-size -C --mcu=atmega328p I2c-debug.elf
    AVR Memory Usage
    ----------------
    Device: atmega328p
    Program:    8684 bytes (26.5% Full)
    (.text + .data + .bootloader)
    Data:        375 bytes (18.3% Full)
    (.data + .bss + .noinit)
    rm -f I2c-debug.o main.o i2c-scan.o i2c-cmd.o ../Uart/id.o ../lib/timers.o ../lib/uart.o ../lib/twi.o ../lib/rpu_mgr.o ../lib/adc.o ../lib/parse.o
    avr-objcopy -j .text -j .data -O ihex I2c-debug.elf I2c-debug.hex
    rm -f I2c-debug.elf
    avrdude -v -p atmega328p -c arduino -P /dev/ttyAMA0 -b 115200 -U flash:w:I2c-debug.hex
    avrdude: Version 6.1, compiled on Jul  7 2015 at 10:29:47         Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/         Copyright (c) 2007-2014 Joerg Wunsch
             System wide configuration file is "/etc/avrdude.conf"         User configuration file is "/home/rsutherland/.avrduderc"         User configuration file does not exist or is not a regular file, skipping
             Using Port                    : /dev/ttyAMA0         Using Programmer              : arduino         Overriding Baud Rate          : 115200         AVR Part                      : ATmega328P         Chip Erase delay              : 9000 us         PAGEL                         : PD7         BS2                           : PC2         RESET disposition             : dedicated         RETRY pulse                   : SCK         serial program mode           : yes         parallel program mode         : yes         Timeout                       : 200         StabDelay                     : 100         CmdexeDelay                   : 25         SyncLoops                     : 32         ByteDelay                     : 0         PollIndex                     : 3         PollValue                     : 0x53         Memory Detail                 :
     Block Poll Page Polled Memory Type Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- --------- eeprom 65 20 4 0 no 1024 4 0 3600 3600 0xff 0xff flash 65 6 128 0 yes 32768 128 256 4500 4500 0xff 0xff lfuse 0 0 0 0 no 1 0 0 4500 4500 0x00 0x00 hfuse 0 0 0 0 no 1 0 0 4500 4500 0x00 0x00 efuse 0 0 0 0 no 1 0 0 4500 4500 0x00 0x00 lock 0 0 0 0 no 1 0...
    Read more »

  • ^2 Board Arrived

    ronald.sutherland06/04/2017 at 04:02 0 comments

    OSHPark did a great job as always, unfortunately, I had a brain fart and forgot that the AVR microcontroller under the shield connects to the RS-422 transceiver through the 74LVC07 buffers I used. I was trying to use the buffers IOFF state to allow the Pi Zero to be powered off without pulling down the RS-422 bus.

    When U3 (74LVC07) does not have power the serial RX and TX from shield can not reach the RS-422 transceivers.

    For testing, I need to cut U3 power from the PI3V3 node and bridge it to the +3V3 node.

    Power RS-422 Buffer

    So far this hack is working, but I have another board on the way so this will soon be back on a spin loop thread.

View all 6 project logs

Enjoy this project?

Share

Discussions

stife8266 wrote 12/21/2023 at 16:06 point

A major factor in 8Rental's success is its group of committed experts that make sure the business is among the most driven in the sector.  https://8rental.com/

  Are you sure? yes | no

ronald.sutherland wrote 06/08/2017 at 20:58 point

It helps to be able to iterate the board. Mistakes can be made and the cost is not that painful. I don't even do projects on prototype boards nowadays (but still doing test setups with them).

  Are you sure? yes | no

oshpark wrote 06/08/2017 at 20:34 point

Great idea!

  Are you sure? yes | no

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates