Open TheChrysi opened 4 years ago
Other problem is with Linux loader. Program Bus_Pirate/package/BPv3-firmware/pirate-loader_lnx
doesn't work, it reports that it receives wrong response to 0xc1 request. I spent some time on this issue and I found that my BusPirate device (clone from eBay) replies with correct sequence to 0xc1.
I tried it on 64-bit Ubuntu 18.04, on 32-bit Ubuntu 16.04 and 32-bit Ubuntu 14.04. No difference, it just doesn't work.
I am not sure if that program ever worked. It is possible it worked in the time when BusPirate was created and that Linux API evolved from that time and pirate-loader.c
has to be modified to match modern API. This is the best explanation I have... Maybe that new flasher written in Python can be created...
I have found that I can flash my BusPirate with ds30 flasher wine "ds30 Loader GUI.exe"
, it works. Alias from serial port /dev/ttyUSB0
to com1
has to be created, ask Google how to do it (create a symbolic link in .wine directory).
pirate-loader_lnx receives wrong answer to 0xc1 request:
$ ./pirate-loader_lnx --dev=/dev/ttyUSB0 --hello
+++++++++++++++++++++++++++++++++++++++++++
Pirate-Loader for BP with Bootloader v4+
Loader version: 1.0.2 OS: Linux
+++++++++++++++++++++++++++++++++++++++++++
Opening serial device /dev/ttyUSB0...OK
Configuring serial port settings...OK
Sending Hello to the Bootloader...ERROR
No reply from the bootloader, or invalid reply received: 4
Please make sure that PGND and PGC are connected, replug the devide and try again
The issue was described long time ago. http://dangerousprototypes.com/forum/index.php?topic=7022.0
I have found an article that uses pirate-loader_lnx
to flash firmware and it worked http://cholla.mmto.org/stm32/pirate.html
I have clone of BusPirate from eBay, UART chip is Profilic PL2303. Genuine BusPirate have FTDI FT232RL.
My BusPirate response to 0xC1 request is 0xD4 0x01 0x02 0x4B. That is expected response.
When I debug pirate-loader_lnx
, I see it receives 0x02 0x11 0x0A 0x13 and I cannot explain why...
I checked what is sent from pirate-loader_lnx
to UART. It should be 0xC1 but in the real it sends 0xE1!
When BusPirate bootloader receives 0xE1, it replies with 0x42 0x4C 0x34 0x2B and pirate-loader_lnx
reads from serial port 0x02 0x11 0x0A 0x13!!
Simple Python3 test, it prints d4 01 02 4b
:
$ cat test.py
#!/usr/bin/env python3
import serial
with serial.Serial('/dev/ttyUSB0', 115200, timeout=1) as ser:
#print(ser.name)
ser.write(b'\xc1')
x = ser.read(4)
print(" ".join("{:02x}".format(c) for c in x))
This is FIX for pirate-loader
for Linux:
$ git diff package/BPv3-firmware/pirate-loader-source/makefile package/BPv3-firmware/pirate-loader-source/source/pirate-loader.c
diff --git a/package/BPv3-firmware/pirate-loader-source/makefile b/package/BPv3-firmware/pirate-loa
index d44a40a..75ebd86 100644
--- a/package/BPv3-firmware/pirate-loader-source/makefile
+++ b/package/BPv3-firmware/pirate-loader-source/makefile
@@ -2,7 +2,7 @@ OS := $(shell uname)
SOURCEPATH=.
CC=gcc
CFLAGS=-O2 -Wall
-OSFLAGS= -DOS=$OS
+OSFLAGS= -DOS=$(OS)
SOURCES=$(SOURCEPATH)/pirate-loader.c
ifeq ($(OS),Linux)
diff --git a/package/BPv3-firmware/pirate-loader-source/source/pirate-loader.c b/package/BPv3-firmw
index 654f85b..15e5cff 100644
--- a/package/BPv3-firmware/pirate-loader-source/source/pirate-loader.c
+++ b/package/BPv3-firmware/pirate-loader-source/source/pirate-loader.c
@@ -42,7 +42,7 @@
#include <fcntl.h>
#include <errno.h>
-#define PIRATE_LOADER_VERSION "1.0.2"
+#define PIRATE_LOADER_VERSION "1.0.3"
#define STR_EXPAND(tok) #tok
#define OS_NAME(tok) STR_EXPAND(tok)
@@ -551,15 +551,9 @@ int configurePort(int fd, unsigned long baudrate)
#else
struct termios g_new_tio;
- memset(&g_new_tio, 0x00 , sizeof(g_new_tio));
+ memset(&g_new_tio, 0x00, sizeof(g_new_tio));
cfmakeraw(&g_new_tio);
- g_new_tio.c_cflag |= (CS8 | CLOCAL | CREAD);
- g_new_tio.c_cflag &= ~(PARENB | CSTOPB | CSIZE);
- g_new_tio.c_oflag = 0;
- g_new_tio.c_lflag = 0;
+ g_new_tio.c_cflag |= (CLOCAL | CREAD);
g_new_tio.c_cc[VTIME] = 0;
g_new_tio.c_cc[VMIN] = 1;
BOOTLOADER mode of BP is detected correctly with the fix:
$ ./pirate-loader_lnx --dev=/dev/ttyUSB0 --hello
+++++++++++++++++++++++++++++++++++++++++++
Pirate-Loader for BP with Bootloader v4+
Loader version: 1.0.3 OS: Linux
+++++++++++++++++++++++++++++++++++++++++++
Opening serial device /dev/ttyUSB0...OK
Configuring serial port settings...OK
Sending Hello to the Bootloader...OK
Device ID: PIC24FJ64GA002 [d4]
Bootloader version: 1,02
Python script to emulate BP BOOTLOADER, I used it for troubleshooting:
#!/usr/bin/env python3
import serial
with serial.Serial('/dev/ttyUSB1', 115200, timeout=1) as ser:
while True:
x = ser.read(1)
if x == b'\xc1':
ser.write(b'\xD4\x01\x02\x4B')
elif len(x) > 0:
ser.write(b'\x42\x4C\x34\x2B')
UPDATE. The source of these tricky trouble is termbits.h
that defines CS8 and CSIZE as the same number 060 (octal number!). The original code first sets CS8 bits to the c_cflags and then it clears CSIZE bits, so just removes CS8 bits set in the previous step. When I just swap these operations, the problem is fixed... This is what describes man cfmakeraw
in the paragraph about raw mode. It first clears flags, than sets flags, that is why that example works:
termios_p->c_cflag &= ~(CSIZE | PARENB);
termios_p->c_cflag |= CS8;
So this is other way how to fix the issue, just swap lines (I do not like it):
- g_new_tio.c_cflag |= (CS8 | CLOCAL | CREAD);
- g_new_tio.c_cflag &= ~(PARENB | CSTOPB | CSIZE);
+ g_new_tio.c_cflag &= ~(PARENB | CSTOPB | CSIZE);
+ g_new_tio.c_cflag |= (CS8 | CLOCAL | CREAD);
I am not sure about that but I think that the best fix should just remove this bit setting game and hope that function cfmakeraw()
sets all bits correctly (that works and I like it!):
cfmakeraw(&g_new_tio);
- g_new_tio.c_cflag |= (CS8 | CLOCAL | CREAD);
- g_new_tio.c_cflag &= ~(PARENB | CSTOPB | CSIZE);
- g_new_tio.c_oflag = 0;
- g_new_tio.c_lflag = 0;
+ g_new_tio.c_cflag |= (CLOCAL | CREAD);
g_new_tio.c_cc[VTIME] = 0;
the page needs addition that if the pirate-loader gives a checksum error it is because the text in the HEX file is in lowercase, and the whole content of the file needs to be converted to uppercase for the checksum to pass. For example notepad++ can handle it quickly.