RPeschke / SCROD_ETHERNET_V3

0 stars 2 forks source link

Revised UDP Client #4

Closed nathankp closed 5 years ago

nathankp commented 5 years ago

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.

  1. 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).

  2. 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:

  1. checksum = sum([Word_command_ID, WORD_PING_C]) instead of proto_message([4:7]

  2. before adding the header and packet size, I concatenated the length of the proto_message (s) with proto_message : proto_message = [s]+proto_message

  3. 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?

nathankp commented 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.

RPeschke commented 5 years ago

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.

RPeschke commented 5 years ago

if you need to convert hex IP addresses to normal ip adresses you can use this website:

this

nathankp commented 5 years ago

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

nathankp commented 5 years ago

"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.

RPeschke commented 5 years ago

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.

RPeschke commented 5 years ago

can you just add another word after the checksum

nathankp commented 5 years ago

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.

nathankp commented 5 years ago

Oh wait, I realize my mistake, have to adjust what elements get summed in the script's checksum calculation.

nathankp commented 5 years ago

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?

nathankp commented 5 years ago

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!

RPeschke commented 5 years ago

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

nathankp commented 5 years ago

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 .

This script interfaces with the fiber optic module on the PC to send and receive packets to/from the SCROD

It is a modification of the UDP_Client_new.py script found in the Peschke/SCROD_ETHERNET_Example_SendBack repo:

                                                                                # /py_scripts/udp_client_new.py)

UDP_client_new issues: Message is incorrect, but the packet words are correct.

Suspect order is incorrect.

Following instructions on data formatting for the Ethernet Module:

https://www.phys.hawaii.edu/~kurtisn/doku.php?id=itop:documentation:data_format

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(str(Data[j]),str(Data[j+1]),str(Data[j+2]),str(Data[j+3]))

    #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#######

value/description follows the data formatting instructions

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

SCROD Cmd packet data:

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.

(?)"24-bit identifier assigning unique ID to this command." Meaning this packet

word 5: command type

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

word 6: command data

no data for ping

read command: read register 0x0001 "waitCyclesHigh"

Rd_reg = 0x00000001 # Rd_reg[31:16] are reserved 0x0000, Rd_reg[15:0] =

write command: "0x0001" to register 0x0001

Wr_reg = 0x00010001 #Wr_reg[31:16] = , Wr_reg[15:0] =

packet size calc:

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

Initial packet construction

proto_message = [packet_size, WORD_COMMAND_C, wordScrodRevC, Word_command_ID, WORD_WRITE_C, Wr_reg] #not included yet: Header, command checksums, packet checksum

later add a for loop to construct multiple command groups

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

after all command groups are added: get packet_checksum

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.append(WORD_HEADER_C)

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