Closed nathankp closed 5 years ago
I sent my script via email. I realized I programmed the wrong SCROD, which was why I was not getting any response. It appears the script I wrote works, but I need to evaluate the response message and make sure there weren't any error flags.
That sounds like progress :)
once you get an answer from the SCROD the rest is really straight forward.
btw. you can just add files to an issue that makes it easier to talk about them.
if you need to convert hex IP addresses to normal ip adresses you can use this website:
It says it couldn't accept my python file for some reason. Here's the response to my ping:
Sent message... 0xbe11e2 0x5 0x646f6974 0x0 0x12 0x70696e67 0x70696e79
recv message... 0xbe11e2 0x5 0x7768613f 0xa200ab 0x12 0x80000001 0xd263c4b8
"0x80000001": It looks like I got the ERR_BIT_SIZE_C_8 error during checksum. If I understand the CommandInterpreter SM correctly, it looks like it expects 8 words minimum, however the ping command only has 7 since there is no data.
ok the error bit is
constant ERR_BIT_SIZE_C_8 : slv(31 downto 0) := x"80000001";
which means it is triggered by this lines
when COMMAND_CHECKSUM_S =>
if rxDataValid = '1' then
rxDataReady <= '1';
v.wordsLeft := r.wordsLeft - 1;
-- Possible errors:
-- This is last, go back to IDLE
if rxDataLast = '1' then
v.errFlags := r.errFlags + ERR_BIT_SIZE_C_8;
v.state := ERR_RESPONSE_S;
-- Bad checksum
elsif r.checksum /= rxData then
v.errFlags := r.errFlags + ERR_BIT_COMM_CS_C;
v.state := ERR_RESPONSE_S;
-- Command accepted, move to execute state
elsif r.command = WORD_PING_C then
v.state := PING_S;
elsif r.command = WORD_WRITE_C then
v.state := WRITE_S;
elsif r.command = WORD_READ_C then
v.state := READ_S;
-- Unrecognized command
else
v.errFlags := r.errFlags + ERR_BIT_COMM_TY_C;
v.state := ERR_RESPONSE_S;
end if;
end if;
this means that the message is missing something and ends to early.
can you just add another word after the checksum
No, that seems to throw off the SCROD's Checksum calculation. I get the ERR_BIT_COMM_CS_C error in the command checksum state.
Oh wait, I realize my mistake, have to adjust what elements get summed in the script's checksum calculation.
I hard coded the checksum to be CommandID + WORD_PING_C that didn't help. I also went ahead and sent a read command so that the packet was 8 bits long, but that's futile. The issue is the command_checksum flags an error if rx_Datalast is '1', but that should always be the case at the command_checksum state, as checksum is the last word in any packet, according the the Data Formatting instructions. Why would that be an error?
OK, I sent the read command again after commenting out the rxDatalast = '1' exception in the command checksum. I no longer receive that error (duh). Still got the bad checksum error, but I know why. The SCROD's checksum always includes the command ID, command type, and command data. From the data formatting instructions I thought we only include command ID for a ping operation, so I left it out of the read operation checksum.
After including the command ID in the checksum, I successfully read one of the registers! Also able to write. If you don't see any problem with leaving leaving out the rxDatalast error in checksum then I say your module passes the Hardware test!
Great! really good work!
For the time being i say we leave it like this even though i am sure that there must be an (easy) solution for this.
can you show me the print outs from the commandline?
Thanks
I understand now why you had the command interpreter throw an exception when rxDatalast = '1' in command checksum. A checksum of the entire packet must be included at the end of the message, which is what you had in the script originally. The funny thing is that the command interpreter doesn't check the packet check_sum, it just passes through an empty state. Kurtis told me that for now that is OK, as the command checksum should catch (almost) any error in the link. So, I restored the exception in FW, and reprogrammed the SCROD. Also, I restored your packet_checksum construction, and labelled the string to int conversion "packet_checksum" instead of assigning it to the variable, s. I confused the s with the packet size originally, so figured a variable name change would help avoid future confusion. Attached is my revised script. Below is the output for a write operation to the 0x0001 register (wrote value = 0x0001). The write happened successfully! No error flags were raised.
[Running] python -u "/tmp/mozilla_belle20/UDP_Client_NP.py"
command checksum is: 0x726a7478
proto_message is: [12456418, 6, 1685023092, 0, 18, 1919513701, 65537, 1919579256, 1229214314]
0xbe11e2
0x6
0x646f6974
0x0
0x12
0x72697465
0x10001
0x726a7478
0x4944526a
UDP Target Address: 192.168.1.33
UDP Target Port: 2001
Sent message...
0xbe11e2
0x6
0x646f6974
0x0
0x12
0x72697465
0x10001
0x726a7478
0x4944526a
recv message...
0xbe11e2
0x6
0x6f6b6179
0xa200ab
0x12
0x72697465
0x10001
0xe335e884
[Done] exited with code=0 in 0.11 seconds
On Tue, Apr 2, 2019 at 7:19 PM RPeschke notifications@github.com wrote:
Great! really good work!
For the time being i say we leave it like this even though i am sure that there must be an (easy) solution for this.
can you show me the print outs from the commandline?
Thanks
— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/RPeschke/SCROD_ETHERNET_V3/issues/4#issuecomment-479343790, or mute the thread https://github.com/notifications/unsubscribe-auth/AVIdYKLIb6znV3rBhbY5LmDFeI0vPLbHks5vdDnzgaJpZM4cZc_V .
# /py_scripts/udp_client_new.py)
import socket import array def ToEventNumber(Data,Index): ret_h = 0
ret_h += (Data[Index])
ret_h += 0x100*(Data[Index+1])
ret_h += 0x10000*(Data[Index+2])
ret_h += 0x1000000*(Data[Index+3])
return ret_h
def ToEventNumber1(Data,Index): ret_h = 0 d = data[Index] ret_h += 256256256(Data[Index]) ret_h += 256256(Data[Index+1]) ret_l =0 ret_h += 256(Data[Index+2]) ret_h += (Data[Index+3]) return ret_h
def ToEventNumber2(Data,Index): ret_h = ''
ret_h += chr(Data[Index+3])
ret_h += chr(Data[Index+2])
ret_h += chr(Data[Index+1])
ret_h += chr(Data[Index])
return ret_h
def ArrayToHex(Data): #displays data in Hex on the terminal, does not do actual conversion. for j in range(0,len(Data),4):
#print(EventToHex(data,j))
print(hex(ToEventNumber(Data,j)))
def EventToHex(Data,Index): return hex(Data[Index+3]),hex(Data[Index+2]),hex(Data[Index+1]),hex(Data[Index])
import numpy as np UDP_IP = "192.168.1.33" #IP of the SCROD UDP_PORT = 2001 #UDP port connecting to the SCROD ######### Transmitted Packet Words#######
WORD_HEADER_C = 0x00BE11E2 #word 0, header word, fixed value WORD_COMMAND_C = 0x646F6974 #word 2, packet type, fixed value to indicate this is a SCROD cmd packet
wordScrodRevC = 0x00000000 #word 3, Device number: SCROD rev and ID, currently set to broadcast address Word_command_ID = 0x00000012 #word 4, verbosity setting and command ID, currently verbos. off.
WORD_PING_C = 0x70696E67 #note: 0x... are type-int, though written in hex form
WORD_READ_C = 0x72656164
WORD_WRITE_C = 0x72697465
WORD_ACK_C = 0x6F6B6179
WORD_ERR_C = 0x7768613F
Rd_reg = 0x00000001 # Rd_reg[31:16] are reserved 0x0000, Rd_reg[15:0] =
Wr_reg = 0x00010001 #Wr_reg[31:16] =
NumOfCmdID = 1 #number of command groups, each has a unique ID and one command type. Sending one command group for this test.
NumOfOp = 1 #total number of operations. Each command group can have multiple operations of the same type (i.e. write to multiple registers). Test: only one operation.
NumOfCmdWords = NumOfCmdID*2+NumOfOp #total number of command related words
packet_size = NumOfCmdWords + 3 #packet type + Device num + packet checksum + num of cmd words
proto_message = [packet_size, WORD_COMMAND_C, wordScrodRevC, Word_command_ID, WORD_WRITE_C, Wr_reg] #not included yet: Header, command checksums, packet checksum
checksum = sum(proto_message[3:len(proto_message)]) #word 7: Command checksum print("command checksum is: ",hex(checksum)) proto_message.append(checksum) #add command checksum to end of command group
s = str(sum(proto_message)) # packet_checksum = int(np.uint32(s)) #Last word: packet_checksum proto_message.append(packet_checksum)#add packet_checksum
proto_message = [WORD_HEADER_C] + proto_message #concatenate header so it is the first word in the packet print("proto_message is: ", proto_message) message = [] for x in proto_message: message+=(x.to_bytes(4,'little'))
ArrayToHex(message) #display all words to be sent in Hex format
print("UDP Target Address:", UDP_IP) print("UDP Target Port:", UDP_PORT)
clientSock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) str1=array.array('B', message).tostring()
print("Sent message...") ArrayToHex(str1) #display final message to be sent clientSock.sendto(str1, (UDP_IP, UDP_PORT)) #send packet to SCROD data, addr = clientSock.recvfrom(4096) #get response print("\n\nrecv message...") ArrayToHex(data) #display response
I am following the data formatting instructions here: https://www.phys.hawaii.edu/~kurtisn/doku.php?id=itop:documentation:data_format
I replaced the nonsense proto_message with a packet that should ping the SCROD. Here are some potential errors I see with your code.
the packet size word is missing. I think you were trying to create it by summing the elements of proto_message that come after the header (word 0) and packet size (word 1).
Order of words in proto_message is wrong. You append the proto_message list, which works for checksum, since it's at the end, but this places the header and packet size at the end of the list. If I understand correctly, word 0 should be in proto_message[0] and word 1 should be in proto_message[1].
My revisions:
checksum = sum([Word_command_ID, WORD_PING_C]) instead of proto_message([4:7]
before adding the header and packet size, I concatenated the length of the proto_message (s) with proto_message : proto_message = [s]+proto_message
concatenated header and proto_message after all other words were placed: proto_message: [WORD_HEADER_C] + proto_message
Unfortunately, I still get stuck wait for a message from the SCROD. I am not sure if I put the words in the wrong order, or in what order does the socket send the elements of message. From reading the firmware, we must be going straight to the dump_s state in the command interpreter. If there are errors beyond IDLE, then we should get back an error message.
I am wondering if I am even properly connect to the SCROD. What is it's IP address? Could I ping it?