This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

DCA1000EVM: Command response from the DCA1000EVM

Part Number: DCA1000EVM
Other Parts Discussed in Thread: IWR1642

Hi,

I am trying to issue a commands to run the DCA1000EVM from software (similar to the lua script in mmwave studio). However, I never get the expected response back. It is always a copy of the transmitted command which doesn't match the expected response from any of the docs such as the user guide or other post .

  • I'm connecting to address 192.168.33.30 and port 4096.
  • The switch sw2.5 is positioned at pin 12.
  • I've tried to issue various commands but for simplicity here just attempting the READ_FPGA_VERSION_CMD_CODE (code 0x0E).
  • The command I'm issuing is: a55a000e0000eeaa (I've converted this from bytes to hex for visualisation).
  • When I read back from the port I expect bytes 5+6 to have the version number in.

When I try to read from the UDP connection though all I ever get back is the exact same message I sent? I've also tried issuing the command as little endian (5aa50e000000aaee) but still just get the same response back. 

Any help very much appreciated as I really want to start doing some signal processing with the data in live environments.

Thanks

Just for completeness the code I'm using to send and receive for the version command :

# Setup the configuration socket.
sockConfig = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
config_address = ('192.168.33.30', 4096)
sockConfig.bind(config_address)

# Get FPGA version.
header = (0xA55A).to_bytes(2,byteorder='big',signed=False)
cmdCode = (0x0E).to_bytes(2,byteorder='big',signed=False)
dataSize = (0).to_bytes(2,byteorder='big',signed=False)
footer = (0xEEAA).to_bytes(2,byteorder='big',signed=False)
fpgaVersion = header + cmdCode + dataSize + footer

sockConfig.sendto(fpgaVersion, config_address)

# Sleep just to give time for code to be processed.
time.sleep(1)

# Receive data from the socket (up to 4096 bytes).
msg, server = sockConfig.recvfrom(4096)

# Print the sent and received message as hex.
print(fpgaVersion.hex())
print(msg.hex())

  • I will take a look and take it to our expert if needed. However, this seems beyond mmwave studio and the request may be denied.

    Thanks and Regards,
    Michelle
  • Hi Richard,

    You may have setup Ethernet connection, but here's what's recommended API

    API NAME

    ConfigureRFDCCard_RecordEthInit

    Description

    This API configures (Socket creation) the ethernet for recording and playback the data

    Implementation

    Function Synopsis

    STATUS ConfigureRFDCCard_RecordEthInit

    (

        strEthConfigMode            sEthConfigMode

    )

    INPUT

    sEthConfigMode

    OUTPUT

    NA

    RETURN

    SUCCESS/ERROR

    The configMode definition is below:

    Description

    This structure is used for ethernet configuration

    Definition

    typedef struct ETH_CONFIG_MODE

    {

        UINT8          au8MacId[6];

        UINT8          au8SourceIpAddr[4];

        UINT8         au8DestiIpAddr[4];

        UINT32        u32RecordPortNo;

        UINT32        u32ConfigPortNo;

    } strEthConfigMode;

    Data Members

    Variable Name

    au8MacId

    Data Type

    UINT8         

    Description

    MAC ID information for the DCA1000EVM

    Range

    0 – 255

    Resolution

    1

    Unit

    NA

    Default

    12-34-56-78-90-12

    au8MacId[0] = 12;

    au8MacId[1] = 34;

    au8MacId[2] = 56;

    au8MacId[3] = 78;

    au8MacId[4] = 90;

    au8MacId[5] = 12;

     

     

    Variable Name

    au8SourceIpAddr

    Data Type

    UINT8         

    Description

    Ethernet IP address of Host PC

    Range

    0 – 255

    Resolution

    1

    Unit

    NA

    Default

    192.168.33.30

    au8SourceIpAddr[0] = 192;

    au8SourceIpAddr[1] = 168;

    au8SourceIpAddr[2] = 33;

    au8SourceIpAddr[3] = 30;

     

     

    Variable Name

    au8DestiIpAddr

    Data Type

    UINT8         

    Description

    Ethernet IP destination address of DCA1000EVM

    Range

    0 – 255

    Resolution

    1

    Unit

    NA

    Default

    192.168.33.180

    au8DestiIpAddr[0] = 192;

    au8DestiIpAddr[1] = 168;

    au8DestiIpAddr[2] = 33;

    au8DestiIpAddr[3] = 180;

     

     

    Variable Name

    u32RecordPortNo

    Data Type

    UINT32       

    Description

    Port numbers for recording 5 different types of data and playback data.

    For eg: If u32RecordPortNo – 5000, then

    5000           à Port number is used to record data in Raw Mode

    5000 -5004 à Port numbers are used to record 5 different types of data in Multi Mode

    5000           à Port number is used to playback the recorded data

    Range

    1024 – 49145

    Resolution

    1

    Unit

    NA

    Default

    4098

     

     

    Variable Name

    u32ConfigPortNo

    Data Type

    UINT32       

    Description

    Configuration port number (This port is a configuration port and used to communicate for all the configuration and responses between FPGA and the application)

    Range

    1024 – 49151

    Resolution

    1

    Unit

    NA

    Default

    4096

     

     

    Hope this helps.

    Regards,

    Michelle

  • Hi Michelle,

    Not sure if I fully understand. I'm using the default FPGA ethernet configuration. I did this by setting switch 2.6 to GRND so that the ethernet configuration data hard coded in the FPGA is used. I believe that corresponds to the numbers above.

    Having a quick look at the API message in your link I believe I'm setup for all those values. I seem to successfully connect on 4096 config port, 4098 data port with IP address 192.168.33.30.

    Is there something else I should be looking at in that API?
    Thanks
  • Richard,

    Can you send a complete Python code you used? I can run it on my setup and check here.

    Thanks and Regards,
    Michelle
  • Hi Michelle,

    I've been playing with this for a while now and come up with the following recipe to stream data out live but it still requires me to have a dependency on mmwave studio which I need to remove. It at least tells me I'm doing something right.

    1) Issue reset command in mmwave studio (seems to be something ar1 requires?).

    2) In python script (or whatever language you want): Open up a UDP port on 4098 to catch ADC data. Over serial interface on the application port tell the mmwave OOB demo to start up on the IWR1642 with chosen chirp parameters.  Close the serial connection (application port).

    3) Tell mmwave studio to connect to the application port (seems to set something up with ar1 that is used for step 4).

    4) Run cut down DataCaptureDemo_xWR.lua script (at bottom of the message).

    5) Data capture card starts streaming (green light flashing). In python I can connect to the data stream and decode.

    I've been able to change the packet delay with the above approach and I don't seem to be dropping packets. What I'm desperate to do though is replace steps 1, 3 and 4 with python. I suspect it is just step 4 I need to be able to convert to python. If I can just get the send messages to the configuration port I'm there. (Matlab, python, C any language even the lua code would be fine just so I can see what happens on those commands internally).

    Thanks,

    Richard

    -- Not entirely sure what it is in lines 1 to 35 that is required in addition to adc_data_path but it doesn't like it if
    -- this section isn't run.
    
    --BSS and MSS firmware download
    info = debug.getinfo(1,'S');
    file_path = (info.source);
    file_path = string.gsub(file_path, "@","");
    file_path = string.gsub(file_path, "DataCaptureDemo_xWR.lua","");
    fw_path   = file_path.."..\\..\\rf_eval_firmware"
    
    
    --Export bit operation file
    bitopfile = file_path.."\\".."bitoperations.lua"
    dofile(bitopfile)
    
    --Read part ID
    res, efuserow9 = ar1.ReadRegister(0xffffe210, 0, 31)
    if (bit_and(efuserow9, 3) == 0) then
        partId = 1243
    elseif (bit_and(efuserow9, 3) == 1) then
        partId = 1443
    else
        partId = 1642
    end
    
    --ES version
    res, ESVersion = ar1.ReadRegister(0xFFFFE218, 0, 31)
    ESVersion = bit_and(ESVersion, 15)
    
    
    
    --ADC_Data file and Raw file and PacketReorder utitlity log file path
    data_path     = file_path.."..\\PostProc"
    adc_data_path = data_path.."\\adc_data.bin"
    Raw_data_path = data_path.."\\adc_data_Raw_0.bin"
    pkt_log_path  = data_path.."\\pktlogfile.txt"
    
    -- KEY BIT I WANT TO RUN.
    
    
    -- select Device type
    if (ar1.SelectCaptureDevice("DCA1000") == 0) then
        WriteToLog("SelectCaptureDevice Success\n", "green")
    else
        WriteToLog("SelectCaptureDevice failure\n", "red")
    end
    RSTD.Sleep(1000)
    
    --DATA CAPTURE CARD API
    if (ar1.CaptureCardConfig_EthInit("192.168.33.30", "192.168.33.180", "12:34:56:78:90:12", 4096, 4098) == 0) then
        WriteToLog("CaptureCardConfig_EthInit Success\n", "green")
    else
        WriteToLog("CaptureCardConfig_EthInit failure\n", "red")
    end
    RSTD.Sleep(1000)
    
    --AR12xx or AR14xx-1, AR16xx- 2 (second parameter indicates the device type)
    if (partId == 1642) then
        if (ar1.CaptureCardConfig_Mode(1, 2, 1, 2, 3, 30) == 0) then
            WriteToLog("CaptureCardConfig_Mode Success\n", "green")
        else
            WriteToLog("CaptureCardConfig_Mode failure\n", "red")
        end
    elseif ((partId == 1243) or (partId == 1443)) then
        if (ar1.CaptureCardConfig_Mode(1, 1, 1, 2, 3, 30) == 0) then
            WriteToLog("CaptureCardConfig_Mode Success\n", "green")
        else
            WriteToLog("CaptureCardConfig_Mode failure\n", "red")
        end
    end
    RSTD.Sleep(1000)
    
    if (ar1.CaptureCardConfig_PacketDelay(150) == 0) then
        WriteToLog("CaptureCardConfig_PacketDelay Success\n", "green")
    else
        WriteToLog("CaptureCardConfig_PacketDelay failure\n", "red")
    end
    RSTD.Sleep(1000)
    
    
    
    --Start Record ADC data
    ar1.CaptureCardConfig_StartRecord(adc_data_path, 1)
    RSTD.Sleep(1000)
    
    
    

  • Hi Michelle,

    Just seen your post (I replied back while you sent this one) . I will send my python code over to you shortly.
  • Hi Michelle,

    The shortest program I have to replicate the problem is below (I can't attach as .py extension not accepted). Any problem and I can email it directly to you. Running python V3 in case that makes a difference. I have just run this program and the two printouts I get are below (top line command sent, bottom line response which is identical to command sent).

    a55a000e0000eeaa
    a55a000e0000eeaa

    import socket
    import time
    
    # Setup the configuration port.
    sockConfig = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    config_address = ('192.168.33.30', 4096)
    sockConfig.bind(config_address)
    
    
    # Get FPGA version.
    header = (0xA55A).to_bytes(2,byteorder='big',signed=False) # SHOULD THIS BE little but that doesn't work either????
    cmdCode = (0x0E).to_bytes(2,byteorder='big',signed=False) # SHOULD THIS BE little????
    dataSize = (0).to_bytes(2,byteorder='big',signed=False) # SHOULD THIS BE little????
    footer = (0xEEAA).to_bytes(2,byteorder='big',signed=False) # SHOULD THIS BE little????
    fpgaVersion = header + cmdCode + dataSize + footer
    
    # Send the command.
    sockConfig.sendto(fpgaVersion, config_address)
    
    # Sleep for 1 second to give time before asking for a response (just in case).
    time.sleep(1)
    
    # Request data back on the config port
    msg, server = sockConfig.recvfrom(1024)
    
    # Print the sent command.
    print(fpgaVersion.hex())
    # Print the received response.
    print(msg.hex())

  • Richard,

    Just to let you know that I'm still working on setting this up.

    One thing worth mentioning is that in mmwave studio, if you put No of frames to 0, it's going to run continuously and save data in files one after another (1GB each). It might be useful for you.

    Regards,
    Michelle
  • Hi Michelle,

    Thanks for the update and letting me know about the No frame=0 option. Regrettably I need to sync a camera up with the radar frames with reasonable accuracy and there is also a strong desire to do our own radar signal processing in real time for certain trials. Mmwave studio is in general an excellent tool for use in the lab - we would have really struggled to initially set up different advanced chirp configurations without it. However, for the purposes we have such as running our software with dependencies on tensorflow, opencv and in linux it becomes a real obstacle. From the little I've used of the DCA1000EVM I think it will be a fantastic tool for both early trials where saving data is OK and advanced stage research demonstrators - if I can issue software configuration commands :)

    I don't know how much the following feature would help others but if mmwave studio had a toggle flag so that it didn't write the data to disk but relied on users to connect to the UDP ADC stream that may satisfy a lot of peoples requirements. It would let them stream off the data and do their own radar signal processing.

    An alternative to the above is if mmwave studio could capture and write data out as it currently does but also capture a webcams image to disk. If the situation is in anyway dynamic then people probably need a camera image (e.g. usb webcam) associated with the radar data . If the capability to capture a usb webcam were added into mmwave studio with the image somehow tied up with ADC sequence number I think that would probably help people - in a similar way to how if you look in the matlab of the ped/vehicle demos you can toggle a camera on. For complex fast moving environments trying to figure out what is going on when a problem occurs from the RDM without a camera image is almost impossible. Radar camera fusion is also another user case here.

    We are really hoping to use the DCA1000EVM though for radar signal processing research (hence ADC data is great), algorithm development, and finally to put together a few advanced stage demonstrators. Even with the above features though I suspect other users like us will just want access to the ADC data and for this purpose mmwave studio just gets in the way as another bit of software to configure and run (also windows only).

    Best regards,
    Richard

  • Richard,

    Just to update, I was able to repeat and get the same thing as you described. Actually, even I disconnect Ethernet cable with DCA1000, I still get msg back with the same value as I sent.

    I have to get help from the software experts and I will let you know if I find anything.

    Thanks and Regards,
    Michelle
  • I don't know if you're still working on this, but I think the issue here may be that the request has to be sent to 192.168.33.180. I've been working on something similar, and I can get a response:

    import socket
    import threading
    import time
    
    fpga_ver_req = b'\x5a\xa5\x0e\x00\x00\x00\xaa\xee' #-- "82-03"
    
    sock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
    sock.bind(("192.168.33.30",4096))
    
    def collectResponse(): 
        msg, server = sock.recvfrom(2048)
        data.append(msg)
    
    thread = threading.Thread(target = collectResponse)
    data = []
    thread.start()
    
    sock.sendto(fpga_ver_req,('192.168.33.180',4096))
    time.sleep(1)
    
    thread.join()
    
    # "data" contains [b'Z\xa5\x0e\x00\x82\x03\xaa\xee']

    I needed to add the extra capture thread because, without it, sock.recvfrom typically hangs. I'm not sure if this is necessary, though...

  • Many thanks - that solved that one for me.
  • Thanks for the helping out!

    Regards,
    Michelle
  • Hi John,

    it looks like you are sending the configuration packets to yourself:

    config_address = ('192.168.33.30', 4096)
    ... sockConfig.bind(config_address) # listen on 192.168.33.30
    ... sockConfig.sendto(fpgaVersion, config_address) # send to 192.168.33.30

    The DCA1000EVM is listening on 192.168.33.180, so you need to change the address in the sendto() line.

    Best regards

    Sebastian

  • Thanks, I've also found that I need it in a thread like E described above. Not sure what exactly blocks it though.
  • Hi,

    From the code you uploaded, it seems you are sending data to yourself and just reading it. You should make the board to send data to your computer.

    Best,
    Youngjae
  • Richard,

    One thing I just learned today about DCA1000 is that it is not designed to support synchronization. It's taking a snapshot of the ADC raw data with processing delays and Ethernet delay. Synchronization is not possible. Just to make sure you are aware of it before moving too far on the development. 

    Regards,

    Michelle

  • Hi Michelle,

    Can I double check what you mean by synchronisation? Do you mean it can't be synchronised to the beginning of a chirp?

    Thanks

  • I initially meant the timing can not be controlled because there's buffer and delay in the data path. As to your question, I guess you mean the begging of each frame, I need to check with designer to see if it is possible to correlate the external data (or image in your case) with the frame.

    Regards,
    Michelle
  • Hey,

    I've been able to successfully stream raw samples from my IWR1642+DCA1000 and do processing in realtime. Thanks for your other posts about this!

    I was wondering if you any luck automating the rest of the flow that it's required to set up in mmwave studio. Points 1, 3, and 4 in your post. I can build and send commands to the DCA1000 ethernet port, but the other configuration commands are still kind of a mystery...

    Thanks!
    Jeff
  • Hi Jeff,

    The ticket you responded to is closed and please check the posts above to get answer. If you have any question, please start a new thread. Appreciate the effort! Thanks.

    Regards,
    Michelle