Fun with e-paper and Arduino using an Adafruit Grand Central M4 and IT9851

Had some fun playing around with an e-paper display this last weekend.  Chose the Adafruit Grand Central M4 (SAM51) because of the large amount of flash and SRAM, but alas it was not enough SRAM to do what I wanted to do.  This is a GDEP097TC2 e-paper display with a parallel interface, hence the use of the IT9851 controller.  This is a really beautiful display at a diagonal size of 9.7″ but a high resolution of 1200W x 825H pixels.  As seen in the pictures below it can display 16 shades of grey.

The IT8951 has the capability of updating very quickly, however we are a little limited with SPI for now.  I plan to get the I80 (parallel interface) working on the IT9851 later, but I don’t have the flat cable and connectors right now to match the I80 interface connector.  I haven’t looked into partial updates, but I believe this is also possible if there is enough SRAM to create an image buffer.  I am hoping to do this after I receive an SDRAM module.

Adruino GDEP097TC2 epaper

Was planning on creating a buffer in SRAM for the display so that the image could be edited then displayed, but due to how the IT9851 accepts data, its 4 bits per pixel (16 shades of grey) or half a byte per pixel.  Calculating this out the display is 1200W x 825H which comes out to 990,000 pixels, and we would need a buffer of 990,000 / 2 = 495,000 bytes.  The Grand Central M4 only has 256k of SRAM.  This is defiantly out, at least for now.  I have an SDRAM module on order that I am going to use to expand the memory available for a later project, listing that below if there is any interest.

https://www.waveshare.com/sdram-board-b.htm

For this the following parts are used:
+ Adafruit Grand Central M4
+ WaveShare 1200×825, 9.7inch E-Ink display HAT for Raspberry Pi
+ 2GB SD card

The Adafruit Grand Central M4 is really handy to have around for various Arduino (or Circuit Python) projects where you don’t want to worry about flash and SRAM limits (most of the time).  I would recommend picking a couple up if you are ordering anything from Adafruit and want a beefy board around to do projects in Arduino or Circuit Python.  I have not tried Circuit Python yet, but it has peaked my interest on a few occasions.

Even though we can’t load the entire image into SRAM, no worry we will work around it for this project.  We have an SD card slot on the Adafruit Grand Central M4 so we are going to use a 2GB SD card to hold the image data for us and send it to the IT8951 as we read it from the SD card.  There is a small buffer of 1200 * 54 = 64800 bytes (57 lines) to speed this up.  I believe the SD card functions are limited to 65k due to the use of a uint16_t in the read function for size.

For whatever reason I can’t figure out why the image I load into the IT8951 is reversed, it could be that the image data is reversed in the BMP file, anyway I did some fancy coding to reverse the pixels of each line as its sent to the IT8951.  This is a little wonky, but works for now.  Maybe I can somehow get the IT8951 to load the memory backwards, but I haven’t investigated too far into the IT8951’s inner workings yet.

The image data is in BMP format and has to be formatted specifically, more detail is on the WaveShare wiki at the following webpage.

https://www.waveshare.com/wiki/9.7inch_e-Paper_HAT

However, we are assuming these images are formatted correctly and we will go ahead and use the provided images and copy them to an SD card.  I would recommend a 2GB SD card, not sure if others will work.  I formatted it to FAT16, not sure if FAT32 will work so I recommend using a FAT16 format.  You could go about and find images, crop them, etc, but I am providing the three that I used for this project in the zip file below.

Let me note that I have not really cleaned up the code for reasons that I might use those function in the future or just didn’t get around to cleaning some parts.  You will find some function are not connected to anything but were used during the development cycle to test things.

m4_GDEP097TC2_hwspi_sd_202102202200.zip

Unzip this above file and place it in your Arduino sketch folder.  You should already have Arduino setup to use the Adafruit M4 Grand Central.  If not, you can review the setup procedure on their website.  The files in the “images_for_sd_card” should be copied to the SD card, then they can be deleted from the Arduino project folder if you wish, they don’t appear to harm anything by leaving them there.  Remember to change your board type to “Adafruit Grand Central M4 (SAM51)” in the tools menu.  There are no extra libraries required.

I first wrote this with the software SPI library, hence it is still present, but switched over to hardware SPI later on, it works much smoother.  The IT9851 supports up to 24Mhz SPI speed, but high speed SPI does not appear to like these long wires, connectors, and other stuff, so its throttled back to 12Mhz, do experiment with it though if you wish.  Also it is purposely not using the default SPI interface to leave it free for other things, the SERCOM6 interface is being used for the SPI interface, it is trivial to change it back by changing the various options in the software_spi.h file as shown below, uncomment only one of these.

//#define USE_SOFTWARE_SPI 1
//#define USE_HARDWARE_SPI_DEFAULT 1
#define USE_HARDWARE_SPI_SERCOM6 1

Now on to the wiring, it is trivial to also find the wiring information in the files software_spi.h and IT8951.h files.  The wiring is listed below, also note the IT8951 board DOES need 5V for power, but the logic is 3.3V.

Arduino digital IO function
6 IT8951 RST
7 IT8951 HRDY
8 IT8951 CS
47 IT8951 MISO
48 IT8951 MOSI
49 IT8951 CLK
5V IT8951 5V
GND IT8951 GND

Do make sure you are connecting to the “digital” pins and not the “analog” pins as I did the first time and couldn’t figure out why it wasn’t working.

That’s about it, connect things up, insert the SD card, load the Arduino code and that should be about it.  Below are some more pictures.

Adruino GDEP097TC2 epaper

Adruino GDEP097TC2 epaper

Adruino GDEP097TC2 epaper

Adruino GDEP097TC2 epaper

Adruino GDEP097TC2 epaper

Adruino GDEP097TC2 epaper

Investigating Blue 125khz RFID tags (from China) bought off Amazon with a Proxmark3

My Proxmark3 RDV40.1 finally arrived yesterday and I have been busy investigating this RFID reader/writer/copier bought off Amazon.  It came bundled with soem blue plastic RFID tags (125khz and 13.56Mhz) and some 125khz RFID cards.  Before the Proxmark3 came I played around with reading and writing some of the included cards but had no way to really verify anything.

Finally I got a hold of a Proxmark3 and it took the better part of yesterday to get it up and going.  This was mostly getting the built from source software working then programming the firmware to the Proxmark3 hardware.

Searching for hours on end about these mysterious tags that I could program with the Chinese copier, read with the Proxmark3, but not program with the Proxmark3 was quite frustrating.  One thing to mention about the strategy here, this works IF you have own or have access to the programmer that programmed the tags.

From internet searching (picture searches are useful) for these blue tags I ran across some possible candidates for them.  I found mentions of TK4100, EM4100, EM4305, T5577 and EM4305

While looking around these two posts provided a wealth of information of where to get started in figuring out the password how how to program the blue tags.
http://www.proxmark.org/forum/viewtopic.php?id=6388
http://www.proxmark.org/forum/viewtopic.php?id=6245

I few lessons learned, these blue 125khz tags do not have the best of antennas in them, even if they can be read, writing data is a whole different story.  These tags are powered from the magnetic field generated by the reader/writer and if not enough power can be drawn from the electromagnetic field the writes will fail.  They need to be positioned in the “sweet spot” of the Proxmark3 to be written to correctly, or attach an antenna with higher gain.

This is the proxmark3 client source that I am using, commands will be slightly different with a different version.

https://github.com/RfidResearchGroup/proxmark3

After some investigation it is not uncommon for these copiers from China to put passwords on the tags they copy.  Once the tag has a password it can not be reprogrammed without that password.  Good thing for us that this data is not encrypted and we can just sniff it with the Proxmark3 and read off the password.

The Proxmark3 client has a brute force script that tries common passwords, but lets go through the sniffing method.

First we are going to read the tag and see what additional data is returned.

Startup the Proxmark3 software, this is the version output from what I am using for reference.

[=] Session log /Users/user/.proxmark3/logs/log_20210219.txt
[+] loaded from JSON file /Users/user/.proxmark3/preferences.json
[=] Using UART port /dev/tty.usbmodemiceman1
[=] Communicating with PM3 over USB-CDC


  ██████╗ ███╗   ███╗█████╗ 
  ██╔══██╗████╗ ████║╚═══██╗
  ██████╔╝██╔████╔██║ ████╔╝
  ██╔═══╝ ██║╚██╔╝██║ ╚══██╗
  ██║     ██║ ╚═╝ ██║█████╔╝       Iceman ☕
  ╚═╝     ╚═╝     ╚═╝╚════╝    ❄️ bleeding edge

  https://github.com/rfidresearchgroup/proxmark3/


 [ Proxmark3 RFID instrument ]

 [ CLIENT ]
  client: RRG/Iceman/master/v4.9237-3016-gf6bca6e3a 2021-02-06 18:19:42
  compiled with Clang/LLVM Apple LLVM 12.0.0 (clang-1200.0.32.28) OS:OSX ARCH:x86_64

 [ PROXMARK3 ]
  firmware.................. PM3RDV4
  external flash............ present
  smartcard reader.......... present
  FPC USART for BT add-on... absent

 [ ARM ]
  bootrom: RRG/Iceman/master/release (git) 
       os: RRG/Iceman/master/v4.9237-3016-gf6bca6e3a 2021-02-06 18:20:33
  compiled with GCC 10.2.1 20201103 (release)

 [ FPGA ] 
  LF image built for 2s30vq100 on 2020-07-08 at 23: 8: 7
  HF image built for 2s30vq100 on 2020-07-08 at 23: 8:19
  HF FeliCa image built for 2s30vq100 on 2020-07-08 at 23: 8:30

 [ Hardware ]
  --= uC: AT91SAM7S512 Rev A
  --= Embedded Processor: ARM7TDMI
  --= Nonvolatile Program Memory Size: 512K bytes, Used: 310789 bytes (59%) Free: 213499 bytes (41%)
  --= Second Nonvolatile Program Memory Size: None
  --= Internal SRAM Size: 64K bytes
  --= Architecture Identifier: AT91SAM7Sxx Series
  --= Nonvolatile Program Memory Type: Embedded Flash Memory

I previously copied an HID 125khz card using the copier from China, and now I am going to read that card and attempt to erase/write it.  First of all here is the output from the LF search.

[usb] pm3 --> lf search

[=] NOTE: some demods output possible binary
[=] if it finds something that looks like a tag
[=] False Positives ARE possible
[=] 
[=] Checking for known tags...
[=] 
[+] [H10301] - HID H10301 26-bit;  FC: 118  CN: 16038    parity: valid
[=] raw: 000000000000002006ec7d4c

[+] Valid HID Prox ID found!

[+] Chipset detection: T55xx
[?] Hint: try `lf t55xx` commands
[usb] pm3 --> 

We notice it detected a T55xx chip, which gives us a hint of what kind of chip is in this card, so lets try to dump the card.

[usb] pm3 --> lf t55xx dump
[+] Reading Page 0:
[+] blk | hex data | binary                           | ascii
[+] ----+----------+----------------------------------+-------
[+]  00 | 80000000 | .0000000000000000000000000000000 | ....
[+]  01 | 80000000 | .0000000000000000000000000000000 | ....
[+]  02 | 80000000 | .0000000000000000000000000000000 | ....
[+]  03 | 80000000 | .0000000000000000000000000000000 | ....
[+]  04 | 80000000 | .0000000000000000000000000000000 | ....
[+]  05 | 80000000 | .0000000000000000000000000000000 | ....
[+]  06 | 80000000 | .0000000000000000000000000000000 | ....
[+]  07 | 80000000 | .0000000000000000000000000000000 | ....
[+] Reading Page 1:
[+] blk | hex data | binary                           | ascii
[+] ----+----------+----------------------------------+-------
[+]  00 | 80000000 | .0000000000000000000000000000000 | ....
[+]  01 | 80000000 | .0000000000000000000000000000000 | ....
[+]  02 | 80000000 | .0000000000000000000000000000000 | ....
[+]  03 | 80000000 | .0000000000000000000000000000000 | ....
[+] saved to json file lf-t55xx-80000000-80000000-80000000-80000000-80000000-80000000-80000000-dump.json
[+] saved 12 blocks to text file lf-t55xx-80000000-80000000-80000000-80000000-80000000-80000000-80000000-dump.eml
[+] saved 48 bytes to binary file lf-t55xx-80000000-80000000-80000000-80000000-80000000-80000000-80000000-dump.bin
[usb] pm3 --> 

We aren’t getting any data from the chip but retrying the LF search command we know there is data on it.  We won’t be able to dump the chip if there is a password on it.  Let’s try to figure out what password the reader put on the tag.  To do this we can capture the data being sent from the Chinese copier.  Here is how to set it up and do the capture.

[usb] pm3 --> lf config --trig 64 --dec 2 --bps 64

[#] LF Sampling config
[#]   [q] divisor.............95 ( 125.00 kHz )
[#]   [b] bits per sample.....8
[#]   [d] decimation..........2
[#]   [a] averaging...........No
[#]   [t] trigger threshold...64
[#]   [s] samples to skip.....0 
[#] LF Sampling Stack
[#]   Max stack usage.........4232 / 8480 bytes
[usb] pm3 --> lf snif

This will setup the Proxmark3 to capture the data coming from the Chinese copier. Read the chip that we want to unlock using the Chinese copier and then “write” it into the Proxmark3 (as of the Proxmark3 is a chip). The Proxmark3 should capture the write attempt and return the prompt, then execute the following two commands and a waveform should appear, we are going to decipher this waveform bit by bit.

[usb] pm3 --> data samples
[usb] pm3 --> data plot

Proxmark3 T55xx password waveform

This is the password that the Chinese copier is trying to set, all we have to do is decipher the bits.  Apply a filter on the waveform above as shown below to help with visualization.

Proxmark3 T55xx password waveform

Our waveform should have some red lines over it which make it easier to read now.

Proxmark3 T55xx password waveform

Now we just read off the bits off according to the protocol (which I don’t have handy at the moment).

Proxmark3 T55xx password waveform

Here is a decode of the bits.

bits byte description
1100 password OP code
0001 1001 0x19 password byte
1001 0010 0x92 password byte
0000 0100 0x04 password byte
0010 0111 0x27 password byte
111 trailing bits

Our password is therefore 0x19920427.  Lets try again to dump the chip with the correct password. First run lf search so the Proxmark3 sets configures for the card, we can also manually configure with lf t55xx config if we know the parameters.

[usb] pm3 --> lf search

[=] NOTE: some demods output possible binary
[=] if it finds something that looks like a tag
[=] False Positives ARE possible
[=] 
[=] Checking for known tags...
[=] 
[+] [H10301] - HID H10301 26-bit;  FC: 118  CN: 16038    parity: valid
[=] raw: 000000000000002006ec7d4c

[+] Valid HID Prox ID found!

[+] Chipset detection: T55xx
[?] Hint: try `lf t55xx` commands
[usb] pm3 --> lf t55 detect -p19920427
[=]      Chip Type      : T55x7
[=]      Modulation     : FSK2a
[=]      Bit Rate       : 4 - RF/50
[=]      Inverted       : Yes
[=]      Offset         : 33
[=]      Seq. Term.     : No
[=]      Block0         : 0x00107070 (Auto detect)
[=]      Downlink Mode  : default/fixed bit length
[=]      Password Set   : Yes
[=]      Password       : 19920427

We see the chip, and the password is correct as it responds.  We found a T55x7 chip (actually a T5577 chip in in this tag). The chip is in an emulation mode for HID 125khz now so its modulation and such has been changed to match the chip it copied.  Let’s attempt to dump its data.

[usb] pm3 --> lf t55xx dump p 19920427
[+] Reading Page 0:
[+] blk | hex data | binary                           | ascii
[+] ----+----------+----------------------------------+-------
[!] ⚠️  Safety check: Could not detect if PWD bit is set in config block. Exits.
[!] ⚠️  Safety check: Could not detect if PWD bit is set in config block. Exits.
[!] ⚠️  Safety check: Could not detect if PWD bit is set in config block. Exits.
[!] ⚠️  Safety check: Could not detect if PWD bit is set in config block. Exits.
[!] ⚠️  Safety check: Could not detect if PWD bit is set in config block. Exits.
[!] ⚠️  Safety check: Could not detect if PWD bit is set in config block. Exits.
[!] ⚠️  Safety check: Could not detect if PWD bit is set in config block. Exits.
[!] ⚠️  Safety check: Could not detect if PWD bit is set in config block. Exits.
[+] Reading Page 1:
[+] blk | hex data | binary                           | ascii
[+] ----+----------+----------------------------------+-------
[!] ⚠️  Safety check: Could not detect if PWD bit is set in config block. Exits.
[!] ⚠️  Safety check: Could not detect if PWD bit is set in config block. Exits.
[!] ⚠️  Safety check: Could not detect if PWD bit is set in config block. Exits.
[!] ⚠️  Safety check: Could not detect if PWD bit is set in config block. Exits.

We are getting a safety check to make sure we know what we are doing. Attempting to use a password on a card that does not have one set can damage it hence the warning. We know the password is correct and we can dump the card (at your own risk) since we are going to override this warning.

[usb] pm3 --> lf t55xx dump p 19920427 o
[+] Reading Page 0:
[+] blk | hex data | binary                           | ascii
[+] ----+----------+----------------------------------+-------
[=] Safety check overridden - proceeding despite risk
[+]  00 | 00107070 | 00000000000100000111000001110000 | ..pp
[+]  01 | EAAACAAA | 11101010101010101100101010101010 | ....
[+]  02 | AB4D4D2B | 10101011010011010100110100101011 | .MM+
[+]  03 | 55332D28 | 01010101001100110010110100101000 | U3-(
[+]  04 | 00000000 | 00000000000000000000000000000000 | ....
[+]  05 | 00000000 | 00000000000000000000000000000000 | ....
[+]  06 | 00000000 | 00000000000000000000000000000000 | ....
[+]  07 | 19920427 | 00011001100100100000010000100111 | ...'
[+] Reading Page 1:
[+] blk | hex data | binary                           | ascii
[+] ----+----------+----------------------------------+-------
[+]  00 | 00107070 | 00000000000100000111000001110000 | ..pp
[+]  01 | E01500D0 | 11100000000101010000000011010000 | ....
[+]  02 | 3075F62B | 00110000011101011111011000101011 | 0u.+
[+]  03 | 00A00003 | 00000000101000000000000000000011 | ....
[+] saved to json file lf-t55xx-EAAACAAA-AB4D4D2B-55332D28-dump.json
[+] saved 12 blocks to text file lf-t55xx-EAAACAAA-AB4D4D2B-55332D28-dump.eml
[+] saved 48 bytes to binary file lf-t55xx-EAAACAAA-AB4D4D2B-55332D28-dump.bin

Here is our dump. Next let’s try to erase the card (to clear the password also). There are password set/clear commands, but if you just want to recover card so it can be used on another reader it is easy to just wipe it.

Lets first search for the card, then attempt to erase it, then try to search for it again. If we erased it it should not return any data.

[usb] pm3 --> lf search

[=] NOTE: some demods output possible binary
[=] if it finds something that looks like a tag
[=] False Positives ARE possible
[=] 
[=] Checking for known tags...
[=] 
[+] [H10301] - HID H10301 26-bit;  FC: 118  CN: 16038    parity: valid
[=] raw: 000000000000002006ec7d4c

[+] Valid HID Prox ID found!

[+] Chipset detection: T55xx
[?] Hint: try `lf t55xx` commands
[usb] pm3 --> lf t55xx wipe
[=] Target T55x7 tag
[=] Default configuration block 000880E0

[=] Begin wiping...
[=] Writing page 0  block: 00  data: 0x000880E0 
[=] Writing page 0  block: 01  data: 0x00000000 
[=] Writing page 0  block: 02  data: 0x00000000 
[=] Writing page 0  block: 03  data: 0x00000000 
[=] Writing page 0  block: 04  data: 0x00000000 
[=] Writing page 0  block: 05  data: 0x00000000 
[=] Writing page 0  block: 06  data: 0x00000000 
[=] Writing page 0  block: 07  data: 0x00000000 
[usb] pm3 --> lf search

[=] NOTE: some demods output possible binary
[=] if it finds something that looks like a tag
[=] False Positives ARE possible
[=] 
[=] Checking for known tags...
[=] 
[+] [H10301] - HID H10301 26-bit;  FC: 118  CN: 16038    parity: valid
[=] raw: 000000000000002006ec7d4c

[+] Valid HID Prox ID found!

[+] Chipset detection: T55xx
[?] Hint: try `lf t55xx` commands

It appears the wipe command didn’t work, this is because there is a password set, we need the password to change data on the card, let’s try again with the password.

[usb] pm3 --> lf search

[=] NOTE: some demods output possible binary
[=] if it finds something that looks like a tag
[=] False Positives ARE possible
[=] 
[=] Checking for known tags...
[=] 
[+] [H10301] - HID H10301 26-bit;  FC: 118  CN: 16038    parity: valid
[=] raw: 000000000000002006ec7d4c

[+] Valid HID Prox ID found!

[+] Chipset detection: T55xx
[?] Hint: try `lf t55xx` commands
[usb] pm3 --> lf t55xx wipe -p 19920427
[=] Target T55x7 tag
[=] Using password 19920427
[=] Default configuration block 000880E0

[=] Begin wiping...
[=] Writing page 0  block: 00  data: 0x000880E0 pwd: 0x19920427
[=] Writing page 0  block: 01  data: 0x00000000 
[=] Writing page 0  block: 02  data: 0x00000000 
[=] Writing page 0  block: 03  data: 0x00000000 
[=] Writing page 0  block: 04  data: 0x00000000 
[=] Writing page 0  block: 05  data: 0x00000000 
[=] Writing page 0  block: 06  data: 0x00000000 
[=] Writing page 0  block: 07  data: 0x00000000 
[usb] pm3 --> lf search

[=] NOTE: some demods output possible binary
[=] if it finds something that looks like a tag
[=] False Positives ARE possible
[=] 
[=] Checking for known tags...
[=] 
[-] ⛔ No known 125/134 kHz tags found!
[+] Chipset detection: T55xx
[?] Hint: try `lf t55xx` commands

It looks like we change something on the card. Assuming the card is now wiped, lets try to detect it again then dump its contents (without the password).

[usb] pm3 --> lf t55xx detect
[=]      Chip Type      : T55x7
[=]      Modulation     : ASK
[=]      Bit Rate       : 2 - RF/32
[=]      Inverted       : No
[=]      Offset         : 33
[=]      Seq. Term.     : Yes
[=]      Block0         : 0x000880E0 (Auto detect)
[=]      Downlink Mode  : default/fixed bit length
[=]      Password Set   : No

[usb] pm3 --> lf t55xx dump
[+] Reading Page 0:
[+] blk | hex data | binary                           | ascii
[+] ----+----------+----------------------------------+-------
[+]  00 | 000880E0 | 00000000000010001000000011100000 | ....
[+]  01 | 00000000 | 00000000000000000000000000000000 | ....
[+]  02 | 00000000 | 00000000000000000000000000000000 | ....
[+]  03 | 00000000 | 00000000000000000000000000000000 | ....
[+]  04 | 00000000 | 00000000000000000000000000000000 | ....
[+]  05 | 00000000 | 00000000000000000000000000000000 | ....
[+]  06 | 00000000 | 00000000000000000000000000000000 | ....
[+]  07 | 00000000 | 00000000000000000000000000000000 | ....
[+] Reading Page 1:
[+] blk | hex data | binary                           | ascii
[+] ----+----------+----------------------------------+-------
[+]  00 | 000880E0 | 00000000000010001000000011100000 | ....
[+]  01 | E01500D0 | 11100000000101010000000011010000 | ....
[+]  02 | 3075F62B | 00110000011101011111011000101011 | 0u.+
[+]  03 | 00A00003 | 00000000101000000000000000000011 | ....
[+] saved to json file lf-t55xx-dump.json
[+] saved 12 blocks to text file lf-t55xx-dump.eml
[+] saved 48 bytes to binary file lf-t55xx-dump.bin

Looks like the card is now blank (without a password) so we are free to use it as we please. Notice the modulation is also now default, hence why we needed to run detect first before the dump so the Proxmark3 knows which modulation to use. These programmable chips (like the T55x7 or EM4x05 series chips) are special in a way in that they can emulate a number of modulations depending on which card it is emulating. Not all chips can be programmed or reprogrammed.

One other method I would like to discuss is a slightly faster method that can be tried to recover the password. This method only worked because we have the device that set the password in our hands and we could examine the password it is sending with the Proxmark3. The Promark3 can also brute force the password which can take a while, however, a lot of these Chinese copier’s passwords are well known and common so the Proxmark3 has a script that will try all the common known passwords. Here is how that works below, it so happens this Chinese copier uses one of the well knows passwords.

I again copied the card with the Chinese copier, then tried the brute force method below.

[usb] pm3 --> lf search

[=] NOTE: some demods output possible binary
[=] if it finds something that looks like a tag
[=] False Positives ARE possible
[=] 
[=] Checking for known tags...
[=] 
[+] [H10301] - HID H10301 26-bit;  FC: 118  CN: 16038    parity: valid
[=] raw: 000000000000002006ec7d4c

[+] Valid HID Prox ID found!

[+] Chipset detection: T55xx
[?] Hint: try `lf t55xx` commands
[usb] pm3 --> lf t55xx chk
[=] press 'enter' to cancel the command

[+] loaded 112 keys from dictionary file /Users/user/Documents/dev_proxmark3/repo/proxmark3/client/dictionaries/t55xx_default_pwds.dic
[=] press 'enter' to cancel the command
[=] testing 51243648
[=] testing 000D8787
[=] testing 19920427
[=]      Chip Type      : T55x7
[=]      Modulation     : FSK2a
[=]      Bit Rate       : 4 - RF/50
[=]      Inverted       : Yes
[=]      Offset         : 33
[=]      Seq. Term.     : No
[=]      Block0         : 0x00107070 (Auto detect)
[=]      Downlink Mode  : default/fixed bit length
[=]      Password Set   : Yes
[=]      Password       : 19920427

[+] found valid password: [ 19920427 ]

[+] time in check pwd 1 seconds

We were able to find the password easily with just trying common passwords with the “lf t55xx chk” command. Since we know the password we can go ahead and dump or wipe the card as shown above.

Hope this has been helpful to recover passwords set from an RFID copier.

Reading FeliCa RFID with a RC-S620S and Arduino

FeliCa reader project

After some more playing around with RFID tags and trying to read some FeliCa tags with the Proxmark3 it was obvious I needed a reader designed for FeliCa.  FeliCa was designed by SONY and has a very long history of usage starting in the 1990’s and beginning wide use in 2001 with the SUICA prepaid rail card.  It is similar to a ISO/IEC 14443, and is closer to a ISO/IEC 18092 (Near Field Communication, NFC TYPE-F) in its communications but its specification actually follows specification JIS: X6319-4.

The card offers very high level encryption and security, I have not seen a single instance of it being hacked even after all these years (yet).

To read the card and get the card id, called the IDm, I found a RC-S620S FeliCa reader at the local shop and searched around to see if anyone had attempted to connect it up to an Arduino platform.  Not suppressing I found some information on this site below with some sample Arduino code.

https://deviceplus.jp/hobby/entry_f02/

With this information I used the Arduino platform to successfully retrieve the IDm from various FeliCa cards in my possession.  After this, I found out that it is not that difficult to retrieve the current balance of the electronic money on the card as well after running across the following below site.  FeliCa is very commonly used in Japan and this can retrieve the unique 8 byte card id (IDm) and balance information for Suica, Icoca, PiTaPa, nanao, edy, and others.

https://www.orsx.net/archives/3835

I then proceeded to create a reader with an OLED display to display the IDm of the card along with the remaining electronic money balance.  This uses an Arduino Feather M0 basic along with a 128×64 OLED display to show the results.  Surprisingly, SONY released an Arduino library for the RC-S620S, which is still up on their website for download, but needs a few fixes since it is from so many years back (2000).

http://blog.felicalauncher.com/sdk_for_air/?page_id=2699

Download the above library and place it in the Arduino “libraries” folder.  In the file “RCS620S.cpp” the following changes need to be made.

Line Search for Replace with
10 #include “Wprogram.h” #include “Arduino.h”
312 Serial.write(data, len); Serial1.write(data, len);
327 if (Serial.available() > 0) { if (Serial1.available() > 0) {
328 data[nread] = Serial.read(); data[nread] = Serial1.read();
338 Serial.flush(); Serial1.flush();

The following hardware items were used in this project:

Adafruit Feather M0 Basic Proto – ATSAMD21 Cortex M0
+ https://www.adafruit.com/product/2772
Adafruit FeatherWing OLED – 128×64 OLED Add-on For Feather
+ https://www.adafruit.com/product/4650
FeatherWing Tripler Mini Kit – Prototyping Add-on For Feathers
+ https://www.adafruit.com/product/3417
NFC FeliCa Reader/Writer Module RC-S620/S
+ https://international.switch-science.com/catalog/353/
FeliCa RC-S620/S and FeliCa Link RC-S730 pitch converter board set (with flat cable)
+ https://international.switch-science.com/catalog/1029/

Here is the pinout of the RC-S602S.  It can work on either 3.3V or 5.0V.  Connect to the “uart1” of the Arduino device being used.  In the case of the Adafruit Feather m0 Basic this is D0 (UART1 RX) and D1 (UART1 TD).  There are two grounds, connect them both to ground.  The RC-S620S can be powered by 5.0v or 3.3v.  An Arduino Uno would work, but it has only one hardware UART, the softserial won’t be able to keep up with the 115200 BAUD of the RC-S620S.  I believe the limit for the softserial is around 9600 or 19200.

Connect the flat cable as shown here in the picture.

RC-S620S flat cable

RC-S620S

RC-S620S pinout

pin color description
1 red VCC (5v or 3.3v)
2 green RXD
3 white TXD
4 black GND
5 n/c do not connect, reserved
6 black GND

A version with the OLED display functions is in the below ZIP file, it is rather big to copy paste here.  Credit for the parts that I copy pasted is these two sources below.

https://deviceplus.jp/hobby/entry_f02/
https://www.orsx.net/archives/3835

https://www.drassal.net/filestore/m0_felica_oled_20210209.zip

The following code is a very simple serial only version that can be pasted.  A zip fie is also available to download.

https://www.drassal.net/filestore/m0_felica_uart_20210209.zip

#include <RCS620S.h>

#define COMMAND_TIMEOUT               400
#define POLLING_INTERVAL              500
#define RCS620S_MAX_CARD_RESPONSE_LEN 30

// FeliCa Service/System Code
#define CYBERNE_SYSTEM_CODE           0x0003
#define COMMON_SYSTEM_CODE            0xFE00
#define PASSNET_SERVICE_CODE          0x090F
#define EDY_SERVICE_CODE              0x170F
#define NANACO_SERVICE_CODE           0x564F
#define WAON_SERVICE_CODE             0x680B

RCS620S rcs620s;

// UNO
#define SERIAL_DEBUG Serial
// Due
// #define SERIAL_DEBUG SerialUSB

void setup() {
  int ret;
  while (!Serial && millis() < 10000);
  Serial.begin(115200);
  Serial.println("Serial init done!");

  // RC-S620Sの初期化
  Serial1.begin(115200);
  Serial.println("Serial1 init done!");
  ret = rcs620s.initDevice();
  while (!ret) {}
  rcs620s.timeout = COMMAND_TIMEOUT;
  Serial.println("RC-S620S init ok");
}

void polling(void) {
  int ret;
  char temp[3];
  char cardid[17];

  // FeliCaのタッチ状態を得る
  ret = rcs620s.polling();

  // FeliCaがタッチされた場合
  if(ret) {
    // IDmを取得する
    for(int i = 0; i < 8; i++){
      sprintf(temp, "%02X", rcs620s.idm[i]);
      cardid[i * 2] = temp[0];
      cardid[(i * 2) + 1] = temp[1];
    }
    cardid[16] = 0;

    printId(cardid);
  }
  
  rcs620s.rfOff();
}

void polling_balance(void) {
  char temp[3];
  char cardid[17];
  uint32_t balance;
  uint8_t buf[RCS620S_MAX_CARD_RESPONSE_LEN];
   
  rcs620s.timeout = COMMAND_TIMEOUT;
   
  // サイバネ領域
  if(rcs620s.polling(CYBERNE_SYSTEM_CODE)){
    // Suica PASMO
    if(requestService(PASSNET_SERVICE_CODE)){
      if(readEncryption(PASSNET_SERVICE_CODE, 0, buf)){
        // Little Endianで入っているPASSNETの残高を取り出す
        balance = buf[23];                  // 11 byte目
        balance = (balance << 8) + buf[22]; // 10 byte目

        // IDmを取得する
        for(int i = 0; i < 8; i++){
          sprintf(temp, "%02X", rcs620s.idm[i]);
          cardid[i * 2] = temp[0];
          cardid[(i * 2) + 1] = temp[1];
        }
        cardid[16] = 0;

        // 残高表示
        printBalance(cardid, "PASSNET", &balance);
      }
    }
  }
   
  // 共通領域
  else if(rcs620s.polling(COMMON_SYSTEM_CODE)){
    // Edy
    if(requestService(EDY_SERVICE_CODE)){
      if(readEncryption(EDY_SERVICE_CODE, 0, buf)){
        // Big Endianで入っているEdyの残高を取り出す
        balance = buf[26];                  // 14 byte目
        balance = (balance << 8) + buf[27]; // 15 byte目

        // IDmを取得する
        for(int i = 0; i < 8; i++){
          sprintf(temp, "%02X", rcs620s.idm[i]);
          cardid[i * 2] = temp[0];
          cardid[(i * 2) + 1] = temp[1];
        }
        cardid[16] = 0;

        // 残高表示
        printBalance(cardid, "Edy", &balance);
      }
    }
     
    // nanaco
    else if(requestService(NANACO_SERVICE_CODE)){
      if(readEncryption(NANACO_SERVICE_CODE, 0, buf)){
        // Big Endianで入っているNanacoの残高を取り出す
        balance = buf[17];                  // 5 byte目
        balance = (balance << 8) + buf[18]; // 6 byte目
        balance = (balance << 8) + buf[19]; // 7 byte目
        balance = (balance << 8) + buf[20]; // 8 byte目

        // IDmを取得する
        for(int i = 0; i < 8; i++){
          sprintf(temp, "%02X", rcs620s.idm[i]);
          cardid[i * 2] = temp[0];
          cardid[(i * 2) + 1] = temp[1];
        }
        cardid[16] = 0;
        
        // 残高表示
        printBalance(cardid, "nanaco", &balance);
      }
    }
     
    // waon
    else if(requestService(WAON_SERVICE_CODE)){
      if(readEncryption(WAON_SERVICE_CODE, 1, buf)){
        // Big Endianで入っているWaonの残高を取り出す
        balance = buf[17];                  // 21 byte目
        balance = (balance << 8) + buf[18]; // 22 byte目
        balance = (balance << 8) + buf[19]; // 23 byte目 balance = balance & 0x7FFFE0; // 残高18bit分のみ論理積で取り出す balance = balance >> 5;             // 5bit分ビットシフト

        // IDmを取得する
        for(int i = 0; i < 8; i++){ sprintf(temp, "%02X", rcs620s.idm[i]); cardid[i * 2] = temp[0]; cardid[(i * 2) + 1] = temp[1]; } cardid[16] = 0; // 残高表示 printBalance(cardid, "waon", &balance); } } } rcs620s.rfOff(); } // request service int requestService(uint16_t serviceCode){ int ret; uint8_t buf[RCS620S_MAX_CARD_RESPONSE_LEN]; uint8_t responseLen = 0; buf[0] = 0x02; memcpy(buf + 1, rcs620s.idm, 8); buf[9] = 0x01; buf[10] = (uint8_t)((serviceCode >> 0) & 0xff);
  buf[11] = (uint8_t)((serviceCode >> 8) & 0xff);
 
  ret = rcs620s.cardCommand(buf, 12, buf, &responseLen);
   
  if(!ret || (responseLen != 12) || (buf[0] != 0x03) ||
      (memcmp(buf + 1, rcs620s.idm, 8) != 0) || ((buf[10] == 0xff) && (buf[11] == 0xff))) {
    return 0;
  }
 
  return 1;
}
 
int readEncryption(uint16_t serviceCode, uint8_t blockNumber, uint8_t *buf){
  int ret;
  uint8_t responseLen = 0;
   
  buf[0] = 0x06;
  memcpy(buf + 1, rcs620s.idm, 8);
  buf[9] = 0x01; // サービス数
  buf[10] = (uint8_t)((serviceCode >> 0) & 0xff);
  buf[11] = (uint8_t)((serviceCode >> 8) & 0xff);
  buf[12] = 0x01; // ブロック数
  buf[13] = 0x80;
  buf[14] = blockNumber;
 
  ret = rcs620s.cardCommand(buf, 15, buf, &responseLen);
 
  if (!ret || (responseLen != 28) || (buf[0] != 0x07) ||
      (memcmp(buf + 1, rcs620s.idm, 8) != 0)) {
    return 0;
  }
 
  return 1;
}

void printId(char *card_id){
  Serial.print("IDm      : ");
  Serial.println(card_id);
  return;
}

void printBalance(char *card_id, char *service_name, uint32_t *balance){
  char result[8];
  Serial.print("IDm      : ");
  Serial.println(card_id);

  Serial.print(" SERVICE : ");
  sprintf(result, "%u", *balance);
  Serial.println(service_name);
  
  Serial.print(" BALANCE : ");
  Serial.println(result);
  
  return;
}

void loop() {
  // put your main code here, to run repeatedly:
  //polling();
  polling_balance();
  delay(POLLING_INTERVAL);
}

RFID development with a Proxmark3 RDV4.01 – first time use on MacOs

As I am occasionally doing more and more RFID related tasks at work, and curious about the data stored on all these RFID devices that I see more and more I got ahold of a Proxmark3 RDV 4.01 to gain more insight to RFID and help out with development.

Running on MacOS am completely new to the Proxmark3, take that back, about 10 years ago I got a Proxmark3 but at the time RFID was not as wide spread and never got a change to get a lot of use out of it.  Fast forward, what really peaked my interest is the use of RFID in some interesting products such as the recently released Savi’s Workshop Handbuilt Star Wars Lightsabers at Hollywood Studios Disney World.  It is easy to find information on YouTube or search engines about the RFID use in these cool new items.

Anyway, opening up the (really nice) case, this is what the inside looks like.

Proxmark3 RDV 4.01

Proxmark3 RDV 4.01

 

It looks like I am being forced to use “brew” to do this, I am not a fan of brew because I don’t know where it is putting files and want to keep my laptop clean.  I already wiped the laptop last month to git rid of a lot of “garbage” installed by things like brew.  I created a throw away account on the laptop and going to use it to do the things that require brew.  I just finished setting up brew and wrote up the below post as I was doing it.

https://www.drassal.net/wp/index.php/2021/02/05/installing-macos-brew-without-sudo

I am following this guide to setup the proxmark3 software, and after setting up brew, it was actually quite straight forward.

Based on this guide
https://github.com/RfidResearchGroup/proxmark3/blob/master/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md

After entering the terminal, and setting up your path for brew (if necessary) running the following three commands should get everything automatically setup, it will take a while to download and compile so grab a drink or coffee while waiting.

brew tap RfidResearchGroup/proxmark3

If you have don’t have the “Blue Shark” accessory run this command next.
brew install proxmark3

If you do have the “Blue Shark” accessory run this command.
brew install –with-blueshark proxmark3

Go grab a drink or coffee while it runs and hopefully there are no errors.  Once this is done use the below command to update the the proxmark3 hardware.  Hold the button as the USB is connected, if the LEDs turn off when the button is released the bootloader is old, repeat the process but hold the button down through the whole bootloader update process.

pm3-flash-all

In my case I got this error message
[!!] 🚨 ====================== OBS ! ===========================================
[!!] 🚨 Note: Your bootloader does not understand the new CMD_BL_VERSION command
[!!] 🚨 It is recommended that you first update your bootloader alone,
[!!] 🚨 reboot the Proxmark3 then only update the main firmware

So, according to the guide I ran the command for updating the bootloader only.

proxmark3 /dev/tty.usbmodemiceman1 –flash –unlock-bootloader –image ~/usr/local/share/proxmark3/firmware/bootrom.elf

After it completes release the USB button, put the proxmark3 back into bootloader mode by holding the button while plugging in the USB, this time two LEDs should stay lit after releasing the button.

Proceed to update the main firmware by the following command
proxmark3 /dev/tty.usbmodemiceman1 –flash –unlock-bootloader –image ~/usr/local/share/proxmark3/firmware/fullimage.elf

Note, “fullimage.elf” refers to the main application image, not including the bootloader, confusing, but this is how the proxmark3 does it.

After this is done just to be sure you are on the right firmware version reconnect the USB without holding down the button then run the following command to enter the client.

pm3

Enjoy playing with the proxmark3!
I’ll be posting some things later about the proxmark3 as I have time to test things out with it.

Installing MacOs brew without sudo

In trying to setup the proxmark3 environment I ran into a frustrating problem, it was setup to be installed with brew… oh no.

My current MacOs version is MacOs BigSur 11.1, so this works with that version, Intel anyway, I don’t have an Apple silicon machine to test with, but it could require some tweaks to work.

I have used brew before and I have always had issues with how it works and where it puts files, and the way that the brew developers were uploading analytics was kinda sneaky as in this post.

https://news.ycombinator.com/item?id=11566720

Yeah this is a while ago, but, how the dev team of brew, being open source and all appealing to developers and the open source community would be a little sneaky about this was not cool.  Not to drag on this topic, but I really don’t think brew needs sudo access to my whole computer, just last month I completly wiped and reinstalled MacOs (latest version too) to rid myself of all the development “junk” that I just allowed to be installed anywhere… yeah development software will turn your computer into a trash can of random files and junk eventually if you don’t carefully watch it.

According to brew itself it says it does not require sudo, but it STILL wants sudo access to install… meh.

https://superuser.com/questions/655113/understanding-homebrew-no-sudo-philosophy-and-questioning-faq

Anyway, being forced into a corner to install brew to install the proxmark3 development tools I decided I would play it safe, I created a new non-admin user account called “proxmark3” to play it safe, and installed brew on that account without sudo with the following script, I had to modify it slightly though which I will explain here.  Original is below.

https://gist.github.com/skyl/36563a5be809e54dc139

I have zipped it up and archived it incase it disappears or changes.  I haven’t tested all possible setups, so you might need to install XCode or other support files before this will work correctly too.

https://www.drassal.net/filestore/brew_without_sudo_20210205.zip

You will notice I blew away a couple if conditions, for some reason it was not detecting the macos version correctly so I just chose for it and deleted the if statements that checked for the macos version.  It will put the executeables under your hold folder in /home/proxmark3/usr, etc.  For some reason the create directory fails so just make them yourself if you get an error.

Also, with how I tweaked the script it defaults to /home/prosmark3 for the home directory, edit as necessary.  Set the execute permission using

mkdir /user/proxmark3/usr
mkdir /user/proxmark3/usr/local
chmod u+x install.rb
./install.rb

After installation is done run the following command to get everything up to date.  We also need to set the path.  Remember to either set the path each time you open a terminal and want to use brew things, or put it somewhere to auto execute each time terminal opens.  I couldn’t get .bash_profile to work for me.

PATH=”$PATH:/Users/proxmark3/usr/local/bin”
brew doctor

This will take a while to run, after it finishes enjoy running brew without sudo!!!

Back to playing with the proxmark3!

nRF9160 ESP32-CAM JPEG image uploader through LTE

This is a guide in progress and is no where near complete, but did want to get some initial information and links to the project files up while I work on the rest of the guide.

Have been working on a few project involving the nRF9160 lately and am trying to get support added into TinyGSM for the nRF9160, there is a discussion over here that I started for that at the address below.

https://github.com/vshymanskyy/TinyGSM/issues/486

Feel free to join in and help out of you have interest in using TinyGSM with the nRF9160.

This project uses an ESP32-CAM development board to take pictures and use the Feather nRF9160 to upload the JPEG images to a server through a form post to a PHP script.  The images can then be immediately viewed in a web browser.

Also this project will also need a SIM card that will allow it to connect to an LTE network.  These JPEG images can be up to 10k in size and will easily eat through a SIM card that does not have enough data.  I just bought a prepaid data only LTE SIM card at a local shop and it works fine, but the LTE network you are connecting to needs to have either NB-IoT or LTE-M support.  It is possible to “borrow” the SIM card from your cell phone too.

Also you will need to know the SIM card’s APN information, if the nRF9160 does not automatically figure it out.  For the few SIM cards I have been working with I have had to manually specify the APN information and sometimes authentication information as well.  More on that later.

esp32_nrf9160_camera_http

A note about the ESP32-CAM, so far I have run into one that was a little glitchy, it would be unstable and freeze/reset randomly.  These ESP32-CAM boards are pretty cheap so I would grab a couple from different vendors, they are common to find on Amazon.  They also should come with the camera, double check that it does.

Here are the three main parts and some links:

ESP32-CAM (the ESP32-CAM board plus camera, I have had good luck with HiLetgo)
+ https://www.amazon.com/HiLetgo-ESP32-CAM-Development-Bluetooth-Raspberry/dp/B07RXPHYNM
+ https://www.amazon.com/ESP32-CAM-Bluetooth-Camera-Module-Development/dp/B07S5PVZKV
Feather nRF9160 (board containing the new LTE radio from Nordic)
https://www.jaredwolff.com/store/nrf9160-feather/
FTDI 3V3 cable (to program the ESP32-CAM, make sure it is 3V3)
https://www.amazon.com/Converter-Terminated-Galileo-BeagleBone-Minnowboard/dp/B06ZYPLFNB
https://www.digikey.com/en/products/detail/ftdi-future-technology-devices-international-ltd/TTL-234X-3V3/6823715

 

esp32_nrf9160_camera_http
esp32_nrf9160_camera_http

esp32_nrf9160_camera_http

esp32_nrf9160_camera_http

esp32_nrf9160_camera_http

Here is how to wire it all up.  There are some pictures to show the wiring if its easier to visualize, and below the pictures are tables with the pinout details.

esp32_nrf9160_camera_http

esp32_nrf9160_camera_http

There are two buttons also visible, the top button is a “take picture” button, shorted so pictures are automatically taken.  The bottom button is the “bootloader” button.  Press this button and hold it while pressing the reset button (on the bottom side of the ESP32-CAM board).  After the ESP32-CAM reset button is pressed release the “bootloader” button.  Wiring between the nRF9160 and the ESP32-CAM and pinout descriptions is shown below.

Feather nRF9160  ESP32-CAM
Pin Desciption Pin Desciption
 RST  reset IO15 nRF9160 reset
 D5  UART2 RX  IO12 UART TX
 D7  UART2 TX  IO13 UART RX
Feather nRF9160
Pin Desciption Info
 GND ground connect to the common ground
 RST reset connect to ESP32-CAM pin IO015
 D5 UART2 RX connect to ESP32-CAM pin IO12
 D7 UART2 TX connect to ESP32-CAM pin IO13
ESP32-CAM
Pin Desciption Info
 5V0 5.0v power input connect to FTDI pin 3 (red)
 GND GND connect to the common ground
 U0R UART0 RX connect to FTDI pin 4 (orange)
 U0T UART0 TX connect to FTDI pin 5 (yellow)
 IO0 GPIO D0 bootloader enable pin, active low
 IO12 GPIO D12 connect to nRF9160 pin D5
 IO13 GPIO D13 connect to nRF9160 pin D7
 IO14 GPIO D14 “take picture” switch, active low
 IO14 GPIO D15 connect to nRF9160 pin RST
FTDI 3V3 6-pin connector
Pin Description Info
 1 (black) GND connect to the common ground
 2 (brown)  CTS#  not used
 3 (red)  5V0  connect to ESP32-CAM 5V0 pin
 4 (orange)  TXD  connect to ESP32-CAM U0R pin
 5 (yellow)  RXD  connect to ESP32-CAM U0T pin
 6 (green)  RTS#  not used

Please do make sure the FTDI cable you are using is a 3.3v version.  The signal lines will be 3.3v but red pin will still have 5.0v on it.  We will power the ESP32-CAM 3V3 regulator from with the 5.0v on the FTDI cable.  Also notice the nRF9160 has its own USB cable, it is powered from that cable.  Since there is no pin on the Feather nRF9160 that we can use to power the Feather nRF9160 we are powering the Feather nRF9160 with a second USB cable.

The Arduino hardware support and some libraries will also need to be installed, to install the Arduino library for the ESP32-CAM open up the Arduino preferences add the following URL to the “Additional Boards Manager URLs box, there is a button to the right that will open up a text box to easily add more than one URL.

https://dl.espressif.com/dl/package_esp32_index.json

esp32_nrf9160_camera_http

Press the “OK” buttons and then open up the “Board Manger” from the “Tools” “board” menu.

esp32_nrf9160_camera_http

Type “esp32” into the search box and install the “esp32” board package.  This will add support for many ESP32 based boards including the “AI Thinker ESP32-CAM.” the board that we are working with.  Be sure to select the board after installing it.

There are a couple other libraries that can be installed through the “Library Manager” if they are not installed, these are:
+ StreamDebugger
+ Time

Additionally, we use TinyGSM, but the version in the Library Manager does not have nRF9160 support, please download that from here and extract the contents into the “library” folder, generally located in “My Documents/Arduino/libraries”.

https://www.drassal.net/filestore/esp32_nrf9160_camera_http_20210203/TinyGSM_20210203.zip

Also grab the Arduino sketch from the below link, unzip this in your Arduino sketch folder.

https://www.drassal.net/filestore/esp32_nrf9160_camera_http_20210203/esp32_nrf9160_camera_http_20210203.zip

These next steps will involve getting the Feather nRF9160 programmed so it will work with TinyGSM (as a AT command driven serial LTE modem).  Getting the nRF9160 programmed might take a little patience.  I found the easiest way is to use “nrfjprog” from Nordic, however, there are GUI based programming tools available also.

I have not had luck with the bootloader for the Feather nRF9160 as the hex file we will load is a little too big.  We may need to use a hardware JLink programmer, or an nRF9160DK, I also hear an nRF53 series DK will also work. A 6-pin TagConnect cable will also be required to connect the Feather nRF9160 programming pins to the programmer.

For the TagConnect, there are a couple routes to go, this cable should connect directly to the nRF9160DK but I have not personally tested it.  Also the smaller thinner wires might break easier with heavy use.

https://www.tag-connect.com/product/tc2030-ctx-nl-6-pin-no-legs-cable-with-10-pin-micro-connector-for-cortex-processors

The connector that I have is the the following, I made an adapter board so I can use it for other projects in the future.  The pins on this connector are routed straight through, pin-for-pin.  There are links to a couple other useful items that can be used to make the adapter board.

https://www.tag-connect.com/product/tc2030-idc-nl
https://www.adafruit.com/product/2743
https://www.adafruit.com/product/1675

The TagConnect cables are not cheap, but are very useful to have around, I am seeing more and more development boards with TagConnect pads.  If you are buying one I would recommend grabbing both of the generic 6-pin and 10-pin versions for future use, these two links below.

https://www.tag-connect.com/product/tc2030-idc-nl
https://www.tag-connect.com/product/tc2050-idc-nl-10-pin-no-legs-cable-with-ribbon-connector

There two files to program, one is to update the nRF9160’s baseband (modem) firmware, the other is to program the actual nRF9160’s main MCU.  If the nRF9160DK is being used instead of the Feather nRF9160 there is one additional hex file to program for the nRF9160DK’s “board controller” nRF52840.

 

https://www.drassal.net/filestore/esp32_nrf9160_camera_http_20210203/nrf9160_baseband_20210203.zip

https://www.drassal.net/filestore/esp32_nrf9160_camera_http_20210203/nrf9160_firmware_20210203.zip

Detailed instructions for programming the nRF9160 is a discussion in itself and I will write up another post with all the details about how to program the three types of nRF9160 boards that I have run into so far.

There are details in the baseband zip file on how to program the baseband, along with the firmware files in the firmware zip file.  For the firmware files there are many to choose from, for the Feather nRF9160 to program it through the nrfjprog utility or the GUI programmer) it would be serial_lte_modem_circuitdojo_feather_nrf9160_115200_merged.hex, 115200 referring to the speed the UART is running at.

For the time being the programming of the nRF9160 is a little above the scope of this guide and will cover it in another post and link to it here when that post is finished.  For now try to search online to get setup for programming.

Setting up the sketch

Lets go back now to the Arduino IDE and load the sketch, there are a couple things we will need to setup.  First will be the APN information for your SIM card, the APN name and then authentication if required,  TinyGSM is setup to use CHAP now, it can be changed over to PAP if necessary.

esp32_nrf9160_camera_http

Next we need to decide where we are going to send the images to, this is setup at the top of the sketch.  The “UPLOAD_TOKEN” and “UPLOAD_MESSAGE” are not used, but left in as placeholders for some kind of authentication system later.

esp32_nrf9160_camera_http

Here is a simple upload.php that can receive the uploaded images.

<?php
$uploadfile = "";
echo "Receiving file [";
echo $_FILES["imageFile"]["name"];
echo "]\r\n";
if(strlen(basename($_FILES["imageFile"]["name"])) > 0)
{
 $uploadfile = basename($_FILES["imageFile"]["name"]);
 if(move_uploaded_file($_FILES["imageFile"]["tmp_name"], $uploadfile))
 {
 echo "saved ";
 } else {
 echo "error moving file";
 }
} else {
 echo "error image data does not exist";
}
?>

After this build and program the ESP32-CAM.  If everything is setup right you should see the Feather nRF9160 connect to the LTE network and see images being uploaded.  It takes time to connect (6 seconds alone for the Feather nRF9160 hardware reset to finish).

There is a lot more detail I want to add to this but going to post this guide up as it is now and add the rest of the information in a little bit.  The required files and source code are all linked above and that is mostly what I wanted to get posted up while I finish fixing up this guide.