pine64 / ArduinoCore-bouffalo

BL602 Arduino Core for Arduino IDE
GNU Lesser General Public License v2.1
68 stars 13 forks source link

Can't upload code #4

Closed AgentSmith0 closed 1 year ago

AgentSmith0 commented 3 years ago

I have a problem uploading my code. I already changed the permissions of the executable files, but now I'm getting the following errors:

/home/username/.arduino15/packages/bouffalo/tools/flasher/0.0.1/bl602-flasher.py: 1: from: not found
/home/username/.arduino15/packages/bouffalo/tools/flasher/0.0.1/bl602-flasher.py: 2: from: not found
import-im6.q16: unable to grab mouse `': File or directory not found @ error/xwindow.c/XSelectWindow/9184.
import-im6.q16: unable to grab mouse `': File or directory not found @ error/xwindow.c/XSelectWindow/9184.
import-im6.q16: unable to grab mouse `': File or directory not found @ error/xwindow.c/XSelectWindow/9184.
import-im6.q16: unable to grab mouse `': File or directory not found @ error/xwindow.c/XSelectWindow/9184.
: not foundn/.arduino15/packages/bouffalo/tools/flasher/0.0.1/bl602-flasher.py: 9: 
import-im6.q16: unable to grab mouse `': File or directory not found @ error/xwindow.c/XSelectWindow/9184.

/home/username/.arduino15/packages/bouffalo/tools/flasher/0.0.1/bl602-flasher.py: 10: Syntax error: "(" unexpected

Compiling does work but when I try to upload the code the cursor changes to a crosshair, probably I have to select a window or something. Is there a way to fix this?

gamelaster commented 3 years ago

Hello, what Python version do you have?

AgentSmith0 commented 3 years ago

I have installed Python 3.9.2 and Python 2.7.18.

gamelaster commented 3 years ago

Hmm, pretty strange. Can you send your version of /home/username/.arduino15/packages/bouffalo/tools/flasher/0.0.1/bl602-flasher.py here? Thanks

AgentSmith0 commented 3 years ago

This is how the file looks like:

from serial import Serial
from tqdm import tqdm
import binascii
import hashlib
import struct
import time
import sys
import os

def if_read(ser, data_len):
    data = bytearray(0)
    received = 0
    while received < data_len:
        tmp = ser.read(data_len - received)
        if len(tmp) == 0:
            break
        else:
            data += tmp
            received += len(tmp)

    if len(data) != data_len:
        return (0, data)
    return (1, data)

def reset(ser):
    ser.setRTS(0)
    time.sleep(0.2)
    reset_cnt = 2
    while reset_cnt > 0:
        ser.setRTS(1)
        time.sleep(0.005)
        ser.setRTS(0)
        time.sleep(0.1)
        ser.setRTS(1)
        time.sleep(0.005)
        ser.setRTS(0)
        time.sleep(0.005)
        reset_cnt -= 1

def handshake(ser):
    ser.setRTS(1)
    time.sleep(0.2)
    ser.setRTS(0)
    time.sleep(0.05)
    ser.setRTS(1)
    ser.setDTR(1)
    time.sleep(0.1)
    ser.setDTR(0)
    time.sleep(0.1)

def expect_ok(ser):
    data = ser.read(2)
    if data[0] != 0x4f or data[1] != 0x4b:
        err = ser.read(2)
        raise ValueError(binascii.hexlify(err))

def expect_data(ser):
    expect_ok(ser)
    len = ser.read(2)
    len = struct.unpack('<h', len)[0]
    data = ser.read(len)
    return data

def cmd_load_seg_header(ser, file):
    header = file.read(0x10)
    ser.write(b'\x17\x00\x10\x00' + header)
    data = expect_data(ser)
    seg_addr, seg_len = struct.unpack('<II', data[0:8])
    print(f'{seg_len} bytes @ {hex(seg_addr)}')
    return seg_len

def cmd_load_seg_data(ser, data):
    ser.write(b'\x18\x00' + struct.pack('<H', len(data)) + data)
    expect_ok(ser)

def cmd_load_boot_header(ser, file):
    header = file.read(0xb0)
    ser.write(b'\x11\x00\xb0\x00' + header)
    expect_ok(ser)

def cmd_check_image(ser):
    ser.write(b'\x19\x00\x00\x00')
    expect_ok(ser)

def cmd_run_image(ser):
    ser.write(b'\x1a\x00\x00\x00')
    expect_ok(ser)

def load_image(ser, file):
    image = open(file, 'rb')
    cmd_load_boot_header(ser, image)
    total = cmd_load_seg_header(ser, image)
    sent = 0
    with tqdm(total=total, unit='byte', unit_scale=True) as pbar:
        while sent != total:
            chunk = image.read(min(total-sent, 4080))
            cmd_load_seg_data(ser, chunk)
            sent = sent + len(chunk)
            pbar.update(len(chunk))
    cmd_check_image(ser)
    cmd_run_image(ser)

def empty_buffer(ser):
    timeout = ser.timeout
    ser.timeout = 0.1
    if_read(ser, 10000)
    ser.timeout = timeout

def send_sync(ser):
    empty_buffer(ser)
    ser.write(b'\x55' * int(0.006 * ser.baudrate / 10))
    expect_ok(ser)

def efl_write_cmd(ser, id, payload = b''):
    plen = len(payload)
    plen_data = struct.pack('<h', plen)
    checksum = struct.pack('<h', sum(plen_data + payload) & 0xff)[0:1]
    data = bytes([id]) + checksum + plen_data + payload
    ser.write(data)

def efl_cmd_read_memory(ser, addr):
    # there is a length parameter here but it doesn't seem to work correctly
    efl_write_cmd(ser, 0x51, struct.pack('<II', addr, 0x4))
    return expect_data(ser)

def efl_cmd_write_memory(ser, addr, data):
    efl_write_cmd(ser, 0x50, struct.pack('<I', len(data)) + data)
    expect_ok(ser)

def efl_cmd_read_jid(ser):
    efl_write_cmd(ser, 0x36)
    return expect_data(ser)

def efl_cmd_flash_erase(ser, addr, len):
    end_addr = addr + len - 1
    efl_write_cmd(ser, 0x30, struct.pack('<II', addr, end_addr))
    timeout = ser.timeout
    ser.timeout = 10.0
    expect_ok(ser)
    ser.timeout = timeout
    print(f'Erased {len} bytes @ {hex(addr)}')

def efl_cmd_flash_write(ser, addr, data):
    efl_write_cmd(ser, 0x31, struct.pack('<I', addr) + data)
    expect_ok(ser)

def efl_cmd_flash_write_check(ser):
    efl_write_cmd(ser, 0x3a)
    expect_ok(ser)

def efl_cmd_flash_xip_read_start(ser):
    efl_write_cmd(ser, 0x60)
    expect_ok(ser)

def efl_cmd_flash_xip_read_sha(ser, addr, len):
    efl_write_cmd(ser, 0x3e, struct.pack('<II', addr, len))
    return expect_data(ser)

def efl_cmd_flash_xip_read_finish(ser):
    efl_write_cmd(ser, 0x61)
    expect_ok(ser)

def efl_cmd_reset(ser):
    efl_write_cmd(ser, 0x21)
    expect_ok(ser)

def efl_program_img(ser, addr, data):
    data_len = len(data)
    efl_cmd_flash_erase(ser, addr, data_len)

    print(f'Programming {data_len} bytes @ {hex(addr)}')
    sent = 0
    with tqdm(total=data_len, unit='byte', unit_scale=True) as pbar:
        while sent != data_len:
            buf_len = min(2048, data_len - sent)
            buf = data[sent:sent + buf_len]
            efl_cmd_flash_write(ser, addr + sent, buf)
            sent = sent + buf_len
            pbar.update(buf_len)
    efl_cmd_flash_write_check(ser)

    sha256sum = hashlib.sha256(data).digest()
    efl_cmd_flash_xip_read_start(ser)
    device_sum = efl_cmd_flash_xip_read_sha(ser, addr, data_len)
    efl_cmd_flash_xip_read_finish(ser)
    if device_sum != sha256sum:
        print('Verification failed')
        print('Host SHA256:', binascii.hexlify(sha256sum))
        print('BL   SHA256:', binascii.hexlify(device_sum))
        return False
    print('Verified by XIP SHA256 hash')
    return True

def prepend_fw_header(img, header_file):
    if img[0:4] == b'BFNP':
        print('Image already has FW header')
        return img
    with open(header_file, 'rb') as f:
        header = f.read()
    img = header + (b'\xFF' * (4096-len(header))) + img
    return img

def get_contrib_path(name):
    sep = os.path.sep
    return os.path.dirname(sys.executable) + sep + 'contrib' + sep + name

def main():
    if len(sys.argv) < 3:
        print(f'Usage: {sys.argv[0]} <serial port> <firmware bin>')
        sys.exit(1)

    ser = Serial(sys.argv[1], baudrate=500000, timeout=2)
    handshake(ser)
    reset(ser)
    send_sync(ser)
    time.sleep(0.1)
    print('Loading helper binary')
    load_image(ser, get_contrib_path('eflash_loader_40m.bin'))
    time.sleep(0.2)
    print()

    # at this point, the eflash loader binary is running with efl_ commands
    # (which seems to work with a higher baudrate)
    ser.baudrate = 2000000
    send_sync(ser)
    with open(sys.argv[2], 'rb') as f:
        data = f.read()
    data = prepend_fw_header(data, get_contrib_path('bootheader.bin'))
    efl_program_img(ser, 0x10000, data)
    efl_cmd_reset(ser)

if __name__ == "__main__":
    main()
AgentSmith0 commented 2 years ago

Any updates to this?

UncleGrumpy commented 2 years ago

I have a suggestion - check if you have brltty installed (a requirement of QEMU.) I was having trouble with the PineNut flasher not being found by PlatformIO. So I'm not sure if this is related or not... The same problem might behave differently in ArduinoIDE. After looking at dmsg I could see it was being taken over by brltty, so I tried disabling and masking the systemd brltty.path unit, but this made no difference. But looking in /usr/lib/udev/rules.d/90-brltty-device.rules I found a device with a device entry that matched the output of lsusb: Bus 001 Device 014: ID 1a86:7523 QinHeng Electronics CH340 serial converter I commented out the conflicting device:

Device: 1A86:7523

    # Baum [NLS eReader Zoomax (20 cells)]
    ## ENV{PRODUCT}=="1a86/7523/*", ENV{BRLTTY_BRAILLE_DRIVER}="bm", GOTO="brltty_usb_run"

This fix requires sudo and will be overwritten by system upgrades, but it worked for me.

AgentSmith0 commented 2 years ago

@UncleGrumpy Thank you very much for your response. I installed brltty, but now I get the followng error when trying to compile my sketch:

Arduino: 1.8.16 (Linux), Board: "PINE64 PineCone, 2000000"

Assembler messages:
Fatal error: invalid -march= option: `rv32imfc'
exit status 1
Error compiling for board PINE64 PineCone.
UncleGrumpy commented 2 years ago

If you do not need brltty for some specific reason I would not install it. That suggestion was a work around in case it was already installed as a requirement for other packages. (It was installed on my system as a qemu dependency) Not sure what to suggest about the compilation error… I have had mixed success with the demos… many have errors compiling that I do not understand yet, this is completely new territory to me. But looking closer at your original post it looks like the flasher was not able to import something it could not find. It only imports from two modules, serial and tqdm. The error does not look like it was serial… you could check that tqdm is installed… or maybe it imports a python module that you are missing?

AgentSmith0 commented 2 years ago

Thank you so much for trying to help me! But no matter what I do, I now always get the error message from above. I will try it again with a fresh OS installation.

AgentSmith0 commented 1 year ago

Hello again, with Arduino IDE 2.0.0 and a fresh OS installation I was able to compile programs for the PineCone, unfortunately when I try to upload the program, I get the following error message on upload: Failed uploading: cannot execute upload tool: fork/exec /home/user/.arduino15/packages/bouffalo/tools/flasher/0.0.1/bl602-flasher.py: exec format error So I added #!/usr/bin/python3 at the start of the file and now I get again this error message, even though the file exists: /home/user/.arduino15/packages/bouffalo/tools/flasher/0.0.1/bl602-flasher.py: no such file or directory I tried executing this python script manually and it seems to start without problems, does anybody know a solution for this problem?

AgentSmith0 commented 1 year ago

I will open a new issue for this.