Teensy 3.1 as BusPirate 5 hardware hacking CTF style teaching tool

I’ve got a small little .ino program for a Teensy 3.1 mcu that allows it to provide an i2c device, a uart port, and gpio. The program functions as a CTF game of sorts with configurable parameters at the start of the code. It would be easily expandable to add other functionality. the i2c device the Teensy presents to the BP5 are just simulated.

if anyone is interested, let me know.

4 Likes

Sounds like a fun training/challenge tool for teaching. I could see using it at a hardware having village at a conference or training at a makerspace.

2 Likes

Yeah, that sounds really cool.

1 Like

Can’t upload but it’s on github. I’m not much of a programmer… Claude helped me a lot.. GitHub - jrsphoto/TeensyPirate: a Teensy 3.1-based educational tool that teaches hardware reverse engineering using a Bus Pirate 5

3 Likes

Wow! Nicely documented.

Maybe we should make a Arduino plank for this and the glitch hacking demo?

2 Likes

Thanks, Ian. I should have mentioned that I’m using a Teensy 3.x adapter board from SparkFun. The only modification is substituting SIP pins for the standard SIP header. I’ve also designed a 3D-printed case with magnets on the bottom to complement the setup. Along with that, I created a 3D-printed slanted base for the Bus Pirate 5, also featuring magnetic mounting. Together, they work quite well. I kept both models compact to fit in my carrying case alongside the rest of the kit. I’ve updated the GitHub repo with links to the 3D print files.

1 Like

One odd thing that I see when doing i2c> scan -v.. I see what I think are just phantom i2c devices, because in the code, only a device at address 0x42 should show up. I haven’t searched here to see if this is common but I’ll do that. Otherwise things seem to work great. Glad you like it.

2 Likes

I am unable to get your .ino file to compile on Arduino 2.3.7 at all.

D:\TeensyPirate-main\TeensyPirate\TeensyPirate.ino: In function 'void setup()':
D:\TeensyPirate-main\TeensyPirate\TeensyPirate.ino:141:14: error: 'I2C_SLAVE' was not declared in this scope
  141 |   Wire.begin(I2C_SLAVE, I2C_ADDR_MAIN, I2C_PINS_18_19, I2C_PULLUP_EXT, 100000);
      |              ^~~~~~~~~
D:\TeensyPirate-main\TeensyPirate\TeensyPirate.ino:141:40: error: 'I2C_PINS_18_19' was not declared in this scope
  141 |   Wire.begin(I2C_SLAVE, I2C_ADDR_MAIN, I2C_PINS_18_19, I2C_PULLUP_EXT, 100000);
      |                                        ^~~~~~~~~~~~~~
D:\TeensyPirate-main\TeensyPirate\TeensyPirate.ino:141:56: error: 'I2C_PULLUP_EXT' was not declared in this scope
  141 |   Wire.begin(I2C_SLAVE, I2C_ADDR_MAIN, I2C_PINS_18_19, I2C_PULLUP_EXT, 100000);
      |                                                        ^~~~~~~~~~~~~~
D:\TeensyPirate-main\TeensyPirate\TeensyPirate.ino:142:18: warning: invalid conversion from 'void (*)(size_t)' {aka 'void (*)(unsigned int)'} to 'void (*)(int)' [-fpermissive]
  142 |   Wire.onReceive(i2cReceiveEvent);
      |                  ^~~~~~~~~~~~~~~
      |                  |
      |                  void (*)(size_t) {aka void (*)(unsigned int)}
In file included from C:\Users\kd7ei\AppData\Local\Arduino15\packages\teensy\hardware\avr\1.58.2\libraries\Wire/Wire.h:29,
                 from D:\TeensyPirate-main\TeensyPirate\TeensyPirate.ino:16:
C:\Users\kd7ei\AppData\Local\Arduino15\packages\teensy\hardware\avr\1.58.2\libraries\Wire/WireKinetis.h:155:31: note:   initializing argument 1 of 'void TwoWire::onReceive(void (*)(int))'
  155 |         void onReceive(void (*function)(int numBytes)) {
      |                        ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~
D:\TeensyPirate-main\TeensyPirate\TeensyPirate.ino: In function 'void i2cReceiveEvent(size_t)':
D:\TeensyPirate-main\TeensyPirate\TeensyPirate.ino:375:29: error: 'class TwoWire' has no member named 'readBytess'; did you mean 'readBytes'?
  375 |     current_register = Wire.readBytess();
      |                             ^~~~~~~~~~
      |                             readBytes
D:\TeensyPirate-main\TeensyPirate\TeensyPirate.ino:382:35: error: no matching function for call to 'TwoWire::readBytes()'
  382 |     uint8_t value = Wire.readBytes();
      |                     ~~~~~~~~~~~~~~^~
In file included from C:\Users\kd7ei\AppData\Local\Arduino15\packages\teensy\hardware\avr\1.58.2\cores\teensy3/HardwareSerial.h:274,
                 from C:\Users\kd7ei\AppData\Local\Arduino15\packages\teensy\hardware\avr\1.58.2\cores\teensy3/WProgram.h:47,
                 from C:\Users\kd7ei\AppData\Local\arduino\sketches\5330309672F1D4379C0EA4BCF4E76C9D\pch\Arduino.h:6:
C:\Users\kd7ei\AppData\Local\Arduino15\packages\teensy\hardware\avr\1.58.2\cores\teensy3/Stream.h:55:16: note: candidate: 'size_t Stream::readBytes(char*, size_t)'
   55 |         size_t readBytes(char *buffer, size_t length);
      |                ^~~~~~~~~
C:\Users\kd7ei\AppData\Local\Arduino15\packages\teensy\hardware\avr\1.58.2\cores\teensy3/Stream.h:55:16: note:   candidate expects 2 arguments, 0 provided
C:\Users\kd7ei\AppData\Local\Arduino15\packages\teensy\hardware\avr\1.58.2\cores\teensy3/Stream.h:56:16: note: candidate: 'size_t Stream::readBytes(uint8_t*, size_t)'
   56 |         size_t readBytes(uint8_t *buffer, size_t length) { return readBytes((char *)buffer, length); }
      |                ^~~~~~~~~
C:\Users\kd7ei\AppData\Local\Arduino15\packages\teensy\hardware\avr\1.58.2\cores\teensy3/Stream.h:56:16: note:   candidate expects 2 arguments, 0 provided
exit status 1

Compilation error: 'I2C_SLAVE' was not declared in this scope
1 Like

Are you using a Teensy? if not add this library: GitHub - nox771/i2c_t3: Enhanced I2C library for Teensy 3.x devices

This library is included with the Teensyduino addon for the Arduino ide so my guess is your not using a Teensy 3.1? Either way, the last line in that points you in the right direction, I2C_SLAVE not declared in this scope. That is defined in the i2c_t3 library. Add that and you should be good.

1 Like

I reopened the Arduino IDE, and was met with this

Processing Teensy (for Arduino IDE 2.0.4 or later):1.59.0: Replacing platform
teensy:avr@1.58.2 with teensy:avr@1.59.0

Updating boards ...

and now it compiles

1 Like

Man, Teensy 3’s are nearly unobtanium!

1 Like

yeah its an older design. I just had some left over from another project. Paul at PRJC (the Teensy creator) has them in stock. Teensy® 3.2

2 Likes

the the Teensy 3.1 and 3.2 are pin compatible. Actually, the 4.0 is pin compatible, though different i2c library would be needed I believe.

2 Likes

Yeah, 4.0 and above use Wire.

2 Likes

Since PJRC decided to move its operations to Sparkfun, I’ve noticed that many Teensy-specific parts are consistently out of stock. I really hope that Sparkfun isn’t planning on killing off Teensy.

1 Like

If I weren’t so inept, I’d try to rewrite it to use Wire. I started, but my ancient, Alzheimer’s-riddled brain vetoed that idea. I’m ordering a 3.2 from PJRC.

The problem is that the wire library doesn’t support slave node with i2c, so a library for this would still be needed. There are a few. There is also a fork of i2c_t3 library for the t4 but they seem unsupported at the moment. I’ll look at this this weekend. Not tough to convert as most of the code is already done.

1 Like

Ok it seems that i2c slave mode was added to wire library back in 2022 so that’s good. I’ll dive into this this weekend

1 Like

What speed are you using?

I love our cable material, but it is a lot of metal and it seems to like low-ish speeds on open-drain bus like I2C. I find 100kHz to be pretty solid.

1 Like

I may not be seeing what you are seeing, or perhaps the UI could be clarified. Your image shows a single device at 0x42. I believe (but am not certain) that it then shows you four device types that are commonly found at that address. But at the end, it confirms a single R/W address pair was found.


I don't think that you're wondering why it shows two addresses...

I2C defines the address as the 7 most significant bits, and the least significant bit as an indicator of which direction the data should flow.

If you instead consider the entire byte as the address, then there’s a pair of addresses that start with an even number … that’s still one device.

0x42           Device address (hex)
0b0100'0010    Device address (binary)
0b1000'010x    7-bit address with 'x' for data direction
0b1000'0100    7-bit address for write commands == 0x84
0b1000'0101    7-bit address for read  commands == 0x85

3 Likes