# Need Help with Python Script - ' 4 Dollar Programmer'

I am working on an embedded project and have made my first PCB with a processor mounted on board. The trouble seems to be actually getting my code onto that processor! I was sort of banking on being able to use the method described here: https://community.cypress.com/docs/DOC-10852
But as you can see from this forum post I made:
I am having some issues. I have moved the question to this forum as it seems to be more of a general programming problem than a specific PSOC problem.

I will copy the script at the end of the post (Without my changes) as It wouldn't format nicely.

I have tried adding parenthesis around the 'data array' value in the print statements, and adding semicolons but the script still gives the error

Python 3.6.5 (v3.6.5:f59c0932b4, Mar 28 2018, 16:07:46) [MSC v.1900 32 bit (Intel)] on win32

>>>

RESTART: F:\GigaTech\PSOC\Workspace02\4DollarProgrammer\Python Programmer.py

Traceback (most recent call last):

File "F:\GigaTech\PSOC\Workspace02\4DollarProgrammer\Python Programmer.py", line 204, in <module>

SendAcquireCommand();

File "F:\GigaTech\PSOC\Workspace02\4DollarProgrammer\Python Programmer.py", line 171, in SendAcquireCommand

ser.write(data_array);

File "C:\Users\Jamie\AppData\Local\Programs\Python\Python36-32\lib\site-packages\serial\serialwin32.py", line 308, in write

data = to_bytes(data)

File "C:\Users\Jamie\AppData\Local\Programs\Python\Python36-32\lib\site-packages\serial\serialutil.py", line 66, in to_bytes

return bytes(bytearray(seq))

TypeError: an integer is required

>>>


I'm not too familiar with python and I suspect it's an issue with dependencies but I don't really know how to proceed with this one. Any help would be greatly greatly appreciated.

### Python Script

from serial import Serial
import time
ser = Serial("com40"); #replace with your COM port number
ser.baudrate = 115200

#Extract Protection Settings
def SendFlashProtectionData(hexFile, function):
data_array = ["S"];
hexFile.seek(0);
current_pos = hexFile.tell();
elementsPerHexFileRow = 141;
hexFileRows = 521;
deviceFlashRows = 256;
hexFlashDataRows = 2*deviceFlashRows;
dataBytesPerFlashRow = 128;
rel_pos = 0;
current_pos = hexFile.tell();
hexFile.seek(current_pos);
for positon_index in range(0,3):
current_pos = hexFile.tell();

#Extract Protection Data
protectionDataLoc = current_pos + 9;
hexFile.seek(protectionDataLoc);
current_pos = hexFile.tell();
for rowsize in range(0,32):
hexFile.seek(current_pos + rel_pos);
tempflashvalhigher = hexfilehigher - 0x30;
if(tempflashvalhigher > 9):
tempflashvalhigher -= 7;
tempflashvallower = hexfilelower - 0x30;
if(tempflashvallower > 9):
tempflashvallower -= 7;
flashvalue = (((tempflashvalhigher << 4) & 0xF0)|(tempflashvallower & 0x0F));
data_array.append(flashvalue)
rel_pos = rel_pos + 2;
for i in range(0,97):
data_array.append(0);
data_array.append("P");
if(function == 0):
data_array.insert(1, "R");
if(function == 1):
data_array.insert(1, "T");
ser.write(data_array);
print data_array

def SendFlashData(hexFile, flashrow, function):
data_array = ["S"];
elementsPerHexFileRow = 141;
hexFile.seek((2*(flashrow - 1)) * elementsPerHexFileRow);
current_pos = fo.tell();
for flashRowToggle in range(0,2):
hexFile.seek(current_pos);
rel_pos = 9;
for rowsize in range(0,64):
hexFile.seek(current_pos + rel_pos);
tempflashvalhigher = hexfilehigher - 0x30;
if(tempflashvalhigher > 9):
tempflashvalhigher -= 7;
tempflashvallower = hexfilelower - 0x30;
if(tempflashvallower > 9):
tempflashvallower -= 7;
flashvalue = (((tempflashvalhigher << 4) & 0xF0)|(tempflashvallower & 0x0F));
data_array.append(flashvalue)
rel_pos = rel_pos + 2;
hexFile.seek(current_pos);
data_array.append("P");
if(function == 0):
data_array.insert(1, "P");
if(function == 1):
data_array.insert(1, "V");
data_array.insert(2, flashrow-1)
ser.write(data_array);
print data_array

#Send the Silicon ID
def SendSiliconID(hexFile):
data_array = ["S"];
hexFile.seek(0);
current_pos = fo.tell();
elementsPerHexFileRow = 141;
hexFileRows = 521;
deviceFlashRows = 256;
hexFlashDataRows = 2*deviceFlashRows;
dataBytesPerFlashRow = 128;
current_pos = fo.tell();
hexFile.seek(current_pos);
for positon_index in range(0,5):
current_pos = hexFile.tell();

#Extract Silicon ID from hex file
silicon_ID_pos = hexFile.tell() + 13;
rel_pos = 0;
for rowsize in range(0,4):
hexFile.seek(silicon_ID_pos + rel_pos);
tempflashvalhigher = hexfilehigher - 0x30;
if(tempflashvalhigher > 9):
tempflashvalhigher -= 7;
tempflashvallower = hexfilelower - 0x30;
if(tempflashvallower > 9):
tempflashvallower -= 7;
flashvalue = (((tempflashvalhigher << 4) & 0xF0)|(tempflashvallower & 0x0F));
data_array.append(flashvalue)
rel_pos = rel_pos + 2;
for i in range(0, 125):
data_array.append(0);
data_array.append("P");
data_array.insert(1, "I");
ser.write(data_array);
print data_array;

#Send Checksum values
def SendCheckSumData(hexFile):
hexFile.seek(0);
current_pos = hexFile.tell();
elementsPerHexFileRow = 141;
hexFileRows = 521;
deviceFlashRows = 256;
hexFlashDataRows = 2*deviceFlashRows;
dataBytesPerFlashRow = 128;
current_pos = fo.tell();
current_pos = fo.tell();

#Extract Checksum from hex file
checkSumDataPos = current_pos + 9;
rel_pos = 0;
data_array = ["S"];
for rowsize in range(0,4):
hexFile.seek(checkSumDataPos + rel_pos);
tempflashvalhigher = hexfilehigher - 0x30;
if(tempflashvalhigher > 9):
tempflashvalhigher -= 7;
tempflashvallower = hexfilelower - 0x30;
if(tempflashvallower > 9):
tempflashvallower -= 7;
flashvalue = (((tempflashvalhigher << 4) & 0xF0)|(tempflashvallower & 0x0F));
data_array.append(flashvalue)
rel_pos = rel_pos + 2;
for i in range(0, 125):
data_array.append(0);
data_array.append("P");
data_array.insert(1, "S");
ser.write(data_array);
print data_array;

#Acquire target
def SendAcquireCommand():
data_array = ["S", "A"];
for i in range(0, 129):
data_array.append(0);
data_array.append("P");
ser.write(data_array);
print data_array;

#Erase All Flash
def SendEraseAllCommand():
data_array = ["S", "E"];
for i in range(0, 129):
data_array.append(0);
data_array.append("P");
ser.write(data_array);
print data_array;

def SendChecksumPrivilegedCommand():
data_array = ["S", "C"];
for i in range(0, 129):
data_array.append(0);
data_array.append("P");
ser.write(data_array);
print data_array;

#Reset the target
def ExitProgramming():
data_array = ["E"];
for i in range(0, 130):
data_array.append(0);
data_array.append("P");
ser.write(data_array);
print data_array;

#main code
#provide path to your .hex file
SendAcquireCommand();
time.sleep(3);
SendSiliconID(fo);
time.sleep(3);
SendEraseAllCommand();
time.sleep(3);
SendChecksumPrivilegedCommand();
time.sleep(3);
for index in range(1, 257):
SendFlashData(fo, index, 0);
time.sleep(0.05);
for index in range(1, 257):
SendFlashData(fo, index, 1);
time.sleep(0.05);
SendFlashProtectionData(fo, 0);
time.sleep(2);
SendFlashProtectionData(fo, 1);
time.sleep(2);
SendCheckSumData(fo);
time.sleep(2);
ExitProgramming();

• Raw Python Script: – GigaJoules May 18 '18 at 9:35
• You probably already knew this, but there are about 145 unnecessary semi-colons you can get rid of. – evildemonic May 18 '18 at 15:40

What I can see here is that the first attempt to try to send some data over the serial line (SendAquireCommand) fails because the data it has to send has an invalid format. Is your .hex file properly formatted? I think you will have to debug the code a bit and print out the data that this command is trying to send over the serial line.

• Yeah the hex file should be totally fine. I've tested it by directly bootloading another 049 kit with that exact file. – GigaJoules May 18 '18 at 17:37

Checking the source code in serialutil.py, this is to_bytes:

def to_bytes(seq):
"""convert a sequence to a bytes type"""
if isinstance(seq, bytes):
return seq
elif isinstance(seq, bytearray):
return bytes(seq)
elif isinstance(seq, memoryview):
return seq.tobytes()
elif isinstance(seq, unicode):
raise TypeError('unicode strings are not supported, please encode to bytes: {!r}'.format(seq))
else:
# handle list of integers and bytes (one or more items) for Python 2 and 3
return bytes(bytearray(seq))


As can be seen, the instance of 'seq' is checked before conversion occurs. If seq is already 'bytes' no conversion is needed. If it is 'bytearray' or 'memoryview', the conversion method that is called is very straight forward. If seq is none of the above, then it first attempts to create a bytearray from seq. This conversion is what triggers the error you are seeing.

In the context of your code, the argument seq is:

data_array = ["S", "A"];


I believe the error lies in this line (and all others that are alike this one). You should attempt to create a data_array that can be converted to a bytearray, or a bytearray directly. Experiment this (thanks, Ignacio Vazquez-Abrams):

data_array = b"SA";


And tell us if this works.

• That will fail since it's a unicode (well, a str technically). Try b"SA". – Ignacio Vazquez-Abrams May 18 '18 at 11:33
• Thank you very much for this, I'll be sure to try this out by monday at the latest. Having a little bit of an issue with the 3D printer I'm using to make a programming jig with so the rush is off a little! Greatly appreciated nonetheless. – GigaJoules May 18 '18 at 17:39
• So swap out the line "data_array = ["S"];" for = b"SA"; and then change the format of the rest of the code to match? Sorry if I'm barking up the wrong tree here, I'm not familiar with python at all. – GigaJoules May 21 '18 at 12:59
• @GigaJoules Actually change ["S"]; for b"S" and ["E"]; for b"E"; as well as ["S", "A"]; for b"SA"; and ["S", "E"]; for b"SE"; and so on. In python, the type of an object is determined upon assignment. The b indicates that the following sequence is byte-literal. – Vicente Cunha May 21 '18 at 13:25
• Ok I'll give this a try at some point and let you know how it goes. In the end I bit the bullet and purchased a miniprog3 just because I need something that I know is going to be reliable. – GigaJoules May 23 '18 at 13:41

ser.write(arg) expects arg to be a list of integers. 'X' is a string object, not the value of ascii number of it as if it were on C language. Simply convert it by ord() function.

For example;

 data_array.append(ord("P"))

• Will be sure to try this out :) – GigaJoules May 18 '18 at 17:40
• Tried this with both "print data_array" and" print (data_array);" versions but I get a syntax error that complains if I put a semicolon on the end and also complains if I don't. Like I said guys I'm not familiar with python at all, more embedded C, VHDL and similar languages :S – GigaJoules May 21 '18 at 12:31
• Doing ord("P"); followed by data_array.append("P"); seems to resolve the issue, however I am now getting the complaint about serial once again (I reinstalled python so I can take everything from the top again) – GigaJoules May 21 '18 at 12:34
• No, this seems to output the exact same errors as the original post I'm afraid. – GigaJoules May 21 '18 at 12:51