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.

How can I communicate directly with the MSP430 on the LDC1614 EVM?

Other Parts Discussed in Thread: LDC1614, LDC1612, LDC1312, LDC1000EVM

I am wondering if there is such interface for LDC1614 EVM in the same way as it implemented in the LDC1000 EVM.

See the following post from FAQ: http://e2e.ti.com/support/sensor/inductive-sensing/f/938/t/295036#Q27

  • Hello John,

    MSP430 and LDC1614 communicate via I2C protocol.

    Best Regards,
    Natallia Holubeva
  • Hi Natallia,

    I know that.
    I want to access LDC1614 registers from PC.
    Please read the post from FAQ, for LDC1000 was defined protocol how to it.
    My question is where can I found protocol definitions for LDC1614 EVM ?

    Thanks,
    John
  • Hello John,
    I'm afraid protocol definitions for the LDC1614 EVM are currently not available.
  • Hi Ben,

    Do you have any expectation date, when it will be released to public ?

    Thanks,
    John
  • Hello John,

    Unfortunately we currently dont have a plan to release it in near feauture.

    Best Regards,

    Natallia Holubeva

  • John,

    Is your primary interest in the protocol definition for the MSP interface, or the actual firmware? If we provided the protocol definition, can you work with that?

    Jim

  • Hi Jim,

    Yes, protocol only will be more then enough.

    Thanks,
    John
  • John,

    What specifically are you trying to do through the protocol? Read and write registers, or anything else?

    Best Regards,
    Natallia Holubeva
  • Hi Natallia,

    Yes, read and write registers.

    Thanks,

    John

  • Hello John,

    Could you please wait for a week? We are working on it now.

    Best Regards,
    Natallia Holubeva
  • Hi Natallia,

    No, problem. I will wait.

    Thanks,

    John

  • John,

    Thank you very much. We will be able to share the protocol in the next couple days.

    Best Regards,
    Natallia Holubeva
  • Hello John,

    Please see below:

    LDC13xx/16xx communication is accomplished via driver-simulated COM protocols. Settings are:

                Baud rate 115200

                No termination CHAR

                Data bits 8

                Parity None

                Stop bit 1

    Flow control: None

    Write register command

    Write register command is used to set desired register settings. It is formed as follow:

    4C 15 01 00 04 2A XX YY YY ZZ

    Where

                4C 15 01 00 04 2A = Write register command header.

                XX is the register address to be written, expressed as HEX. For example, if register 12 is x0C, so XX = 0C

                YY YY is the 2 bytes of data to be written, in HEX, MSB 1st.

                ZZ is CRC-8 check for the command string, which is explained below.

    Each HEX value represents corresponding ASCII character, which is written to COM port.

    For example, if we need to write to register 11 (x1B) a value of x820D, the command is

    4C 15 01 00 04 2A 1B 82 0D A3. In ASCII it appears as                            

    After writing a register it is required to read back 32 bytes – MCU response to a command. Convert ASCII string into array of 8-bit numbers. It consists of the command sent + 21 bytes of 00 + CRC value. In the above example, correct response is 4C 15 01 00 04 2A 1B 82 0D A3 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00A3.

    4th byte (indicated in red above) is an error field. If this byte is 00, there is no error.

    Read register command

    Read register command is used to check LDC register settings. Read process consists of 2 steps:

    1)      Set register command, which is required to indicate which register is to be read. The command format is: 4C 15 01 00 02 2A XX ZZ, where XX is the register address to be read, and ZZ is CRC-8 check for the command string. For example, to read back register 1B the command is 4C 15 01 00 02 2A 1B 10. After sending this command it is required to read 32 bytes. The 4th byte will indicate an error, if any.

    2)      Read register command, in the format 4C 14 01 00 02 2A 02 ZZ, where ZZ is CRC-8 check. After sending this command it is required to read 32 bytes, as noted above. The 4th byte will indicate an error, if any. 7th and 8th bytes are MSB and LSB bytes of the register value. For example, if we read register x1B value, the response is 4C 14 01 00 03 2A 82 0D C6 A3 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 C6

     

    Start streaming command

    To optimize data throughput a special command is implemented, which will continuously output data from LDC devices to COM port.

    To start streaming, send 4C 05 01 00 06 01 29 04 04 30 2A C1. After sending this command it is required to read 32 bytes. 4th byte will indicate an error, if any.

    After the stream is initialized, read 32 bytes at a time. An example read:

    4C30 0100 092A 0151 42CB 0150 5FFF 1C00 0000 0000 0000 0000 0000 0000 0000 001C

    Bytes 7-10 are the Ch0 data (marked in green), MSB 1st, bytes 11-14 are Ch1 data (marked in blue), MSB 1st. In this example, Ch0 data is x015142CB (22,102,731 in decimal), Ch1 is 01505FFF (22,044,671). Further conversion of the raw data to the frequency of oscillation is described in the LDC161x/131x datasheet

    Stop streaming command

    To stop the streaming, send the command 4C 06 01 00 01 01 D2. After sending this command it is required to read 32 bytes. 4th byte will indicate an error, if any.

     

    CRC-8 check

    CRC check is well described in http://en.wikipedia.org/wiki/Computation_of_cyclic_redundancy_checks

    Please refer to the link for more detailed information.

    The LDC 13xx/16xx EVMs use CRC-8 with polynomial coefficient indices of 8, 2, 1, and 0.

    Outlined below is one of the possible implementations:

    Convert each byte in the command to an array of Booleans (T = 1, F = 0), MSB being index 1. For example, xA7 becomes an array (T,F,T,F,F,T,T,T).

    Concatenate the array of bytes, 1st byte being indices 1-8, 2nd – bytes 9-16 etc. For example, xA70F becomes (T,F,T,F,F,T,T,T,F,F,F,F,T,T,T,T). Record the array size N.

    Form C = (T,F,F,F,F,F,T,T,T) – CRC array. Note that the indices of the non-zero coefficients are 8, 2, 1, 0.

    Append to the Boolean command array an array of 8 False (F,F,F,F,F,F,F,F) at the end. Denote this array A.

    For loop for i=1 to N

    IF A[i] = True then

                Get B = array A subset starting at index i, length 9

                B’ = B XOR C

                Replace B in A with B’

    End IF

    End loop

    Take the last 8 Booleans of the updated A, convert it to byte (MSB 1st). For example, if last 8 elements in A are (T,F,T,T,F,F,T,T), it converts to xB3

    This is desired CRC-8 check value (ZZ value in the document)

    Best Regards,

    Natallia Holubeva

  • Hi Natallia,

    Thanks for so quick response. I have started to work on my Python script.

    As soon as it will be ready I will release it to public.

    Thanks,

    Jogn 

  • Hello John,

    I am glad it helped. Thank you very much.

    Best Regards,
    Natallia Holubeva
  • Hi Natallia,

    I just wrote a few lines in python just to verify that I have response to write reg command.

    But the result is absolutely unexpected. Please see below the python code:

    import sys
    import collections
    import serial
    import time
    import struct
    import msvcrt
    
    serial_port = serial.Serial(port='COM13', baudrate=115200, bytesize=8, stopbits=1, parity=serial.PARITY_NONE)
    print("aaaa")
    serial_port.write('4C150100042A1B820DA3')
    s = serial_port.read(11)
    print("bbbb")
    print("Read:", s )
    

    The output of this screen just 11 bytes of text "no stream\r\n"

    Can you please advise ?

    Thanks,

    John

  • I just found solution by myself: I need hex string instead of ASCII:
    serial_port.write('\x4C\x15\x01\x00\x04\x2A\x1B\x82\x0D\xA3')
  • Hi All,

    Please see below short Pyhon script to read write LDC1614 registers.

    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    
    import sys
    import collections
    import serial
    import time
    import struct
    import msvcrt
    from array import *
    import binascii
    
    
    #############################################################################################
    # LDC1000 addressing space
    LDC1614_DATA_MSB_CH0		= '00'
    LDC1614_DATA_LSB_CH0		= '01'
    LDC1614_DATA_MSB_CH1		= '02'
    LDC1614_DATA_LSB_CH1		= '03'
    LDC1614_DATA_MSB_CH2		= '04'
    LDC1614_DATA_LSB_CH2		= '05'
    LDC1614_DATA_MSB_CH3		= '06'
    LDC1614_DATA_LSB_CH3		= '07'
    LDC1614_RCOUNT_CH0			= '08'
    LDC1614_RCOUNT_CH1			= '09'
    LDC1614_RCOUNT_CH2			= '0A'
    LDC1614_RCOUNT_CH3			= '0B'
    LDC1614_OFFSET_CH0			= '0C'
    LDC1614_OFFSET_CH1			= '0D'
    LDC1614_OFFSET_CH2			= '0E'
    LDC1614_OFFSET_CH3			= '0F'
    LDC1614_SETTLECOUNT_CH0		= '10'
    LDC1614_SETTLECOUNT_CH1		= '11'
    LDC1614_SETTLECOUNT_CH2		= '12'
    LDC1614_SETTLECOUNT_CH3		= '13'
    LDC1614_CLOCK_DIVIDERS_CH0	= '14'
    LDC1614_CLOCK_DIVIDERS_CH1	= '15'
    LDC1614_CLOCK_DIVIDERS_CH2	= '16'
    LDC1614_CLOCK_DIVIDERS_CH3	= '17'
    LDC1614_STATUS				= '18'
    LDC1614_ERROR_CONFIG		= '19'
    LDC1614_CONFIG				= '1A'
    LDC1614_MUX_CONFIG			= '1B'
    LDC1614_RESET_DEV			= '1C'
    LDC1614_DRIVE_CURRENT_CH0	= '1E'
    LDC1614_DRIVE_CURRENT_CH1	= '1F'
    LDC1614_DRIVE_CURRENT_CH2	= '20'
    LDC1614_DRIVE_CURRENT_CH3	= '21'
    LDC1614_MANUFACTURER_ID		= '7E'
    LDC1614_DEVICE_ID			= '7F'
    
    
    DEBUG_PRINT_TX_DATA = 0
    DEBUG_PRINT_RX_DATA = 0
    DEBUG_PRINT_READ_DATA = 0
    
    class crc8:
    	def __init__(self):
    		self.crcTable = (0x00, 0x07, 0x0e, 0x09, 0x1c, 0x1b, 0x12, 0x15, 0x38,
    			0x3f, 0x36, 0x31, 0x24, 0x23, 0x2a, 0x2d, 0x70, 0x77,
    			0x7e, 0x79, 0x6c, 0x6b, 0x62, 0x65, 0x48, 0x4f, 0x46,
    			0x41, 0x54, 0x53, 0x5a, 0x5d, 0xe0, 0xe7, 0xee, 0xe9,
    			0xfc, 0xfb, 0xf2, 0xf5, 0xd8, 0xdf, 0xd6, 0xd1, 0xc4,
    			0xc3, 0xca, 0xcd, 0x90, 0x97, 0x9e, 0x99, 0x8c, 0x8b,
    			0x82, 0x85, 0xa8, 0xaf, 0xa6, 0xa1, 0xb4, 0xb3, 0xba,
    			0xbd, 0xc7, 0xc0, 0xc9, 0xce, 0xdb, 0xdc, 0xd5, 0xd2,
    			0xff, 0xf8, 0xf1, 0xf6, 0xe3, 0xe4, 0xed, 0xea, 0xb7,
    			0xb0, 0xb9, 0xbe, 0xab, 0xac, 0xa5, 0xa2, 0x8f, 0x88,
    			0x81, 0x86, 0x93, 0x94, 0x9d, 0x9a, 0x27, 0x20, 0x29,
    			0x2e, 0x3b, 0x3c, 0x35, 0x32, 0x1f, 0x18, 0x11, 0x16,
    			0x03, 0x04, 0x0d, 0x0a, 0x57, 0x50, 0x59, 0x5e, 0x4b,
    			0x4c, 0x45, 0x42, 0x6f, 0x68, 0x61, 0x66, 0x73, 0x74,
    			0x7d, 0x7a, 0x89, 0x8e, 0x87, 0x80, 0x95, 0x92, 0x9b,
    			0x9c, 0xb1, 0xb6, 0xbf, 0xb8, 0xad, 0xaa, 0xa3, 0xa4,
    			0xf9, 0xfe, 0xf7, 0xf0, 0xe5, 0xe2, 0xeb, 0xec, 0xc1,
    			0xc6, 0xcf, 0xc8, 0xdd, 0xda, 0xd3, 0xd4, 0x69, 0x6e,
    			0x67, 0x60, 0x75, 0x72, 0x7b, 0x7c, 0x51, 0x56, 0x5f,
    			0x58, 0x4d, 0x4a, 0x43, 0x44, 0x19, 0x1e, 0x17, 0x10,
    			0x05, 0x02, 0x0b, 0x0c, 0x21, 0x26, 0x2f, 0x28, 0x3d,
    			0x3a, 0x33, 0x34, 0x4e, 0x49, 0x40, 0x47, 0x52, 0x55,
    			0x5c, 0x5b, 0x76, 0x71, 0x78, 0x7f, 0x6a, 0x6d, 0x64,
    			0x63, 0x3e, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2c, 0x2b,
    			0x06, 0x01, 0x08, 0x0f, 0x1a, 0x1d, 0x14, 0x13, 0xae,
    			0xa9, 0xa0, 0xa7, 0xb2, 0xb5, 0xbc, 0xbb, 0x96, 0x91,
    			0x98, 0x9f, 0x8a, 0x8d, 0x84, 0x83, 0xde, 0xd9, 0xd0,
    			0xd7, 0xc2, 0xc5, 0xcc, 0xcb, 0xe6, 0xe1, 0xe8, 0xef,
    			0xfa, 0xfd, 0xf4, 0xf3)
    	def crc(self, msg):
    		runningCRC = 0
    		for c in msg:
    			c = ord(str(c))
    			runningCRC = self.crcByte(runningCRC, c)
    		return runningCRC
     
    	def crcByte(self, oldCrc, byte):
    		res = self.crcTable[oldCrc & 0xFF ^ byte & 0xFF];
    		return res 
    
    def write_reg(serial_port, addr, data):
    	crc = crc8()
    	serial_string = '4C150100042A'+ addr + data
    	serial_string = serial_string.decode('hex')
    	crc_byte = chr(crc.crc(serial_string))
    	serial_port.write(serial_string+crc_byte)
    	s = serial_port.read(32)
    	if DEBUG_PRINT_RX_DATA:
    		print("Read:%s" % (binascii.hexlify(s)))
    	if (s[3] != '\x00'):
    		print("Error in write register")
    		exit()
    
    def read_reg(serial_port, addr):
    
    	crc = crc8()
    	serial_string = '4C150100022A'+ addr
    	serial_string = serial_string.decode('hex')
    	crc_byte = chr(crc.crc(serial_string))
    	serial_port.write(serial_string+crc_byte)
    	s = serial_port.read(32)
    	if DEBUG_PRINT_RX_DATA:
    		print("Read:%s" % (binascii.hexlify(s)))
    	if (s[3] != '\x00'):
    		print("Error in set register")
    		exit()
    	serial_string = '4C140100022A02'
    	serial_string = serial_string.decode('hex')
    	crc_byte = chr(crc.crc(serial_string))
    	serial_port.write(serial_string+crc_byte)
    	s = serial_port.read(32)
    	if DEBUG_PRINT_RX_DATA:
    		print("Read:%s" % (binascii.hexlify(s)))
    	if (s[3] != '\x00'):
    		print("Error in read register")
    		exit()
    	data_read = s[6] + s[7]
    	if DEBUG_PRINT_READ_DATA:
    		print("Addr:", addr,"Data:", binascii.hexlify(data_read) )
    	return binascii.hexlify(data_read)
    
    def ldc_config(serial_port):
    	write_reg(serial_port, LDC1614_MUX_CONFIG,       'C20F')
    	
    	
    def main():
    	serial_port = serial.Serial(port='COM13', baudrate=115200)
    	device_id 	= read_reg  (serial_port, LDC1614_DEVICE_ID)
    	print("device_id=%s" % (device_id))
    
    	write_reg (serial_port, LDC1614_CONFIG, '0200')
    	ldc_config (serial_port)
    	write_reg (serial_port, LDC1614_CONFIG, '0000')
    
    	try:
    	  while 1:
    		# do loop stuff
    		data_lsb 	= read_reg  (serial_port, LDC1614_DATA_LSB_CH0)
    		data_msb 	= read_reg  (serial_port, LDC1614_DATA_MSB_CH0)
    		status 		= read_reg  (serial_port, LDC1614_STATUS)
    		
    		print("Frequency Counter=%s%s  Status=%s  " % (data_msb, data_lsb, status))
    		time.sleep(.5)
    
    	except KeyboardInterrupt:
    		exit()
    
    if __name__ == "__main__":
    	main()

    Natalia,

    May be you can add this post to FAQ ?

    Regards,

    John

  • Hi John,

    I was about to chime in with explanation of HEX representation of the commands, but you have already got it.

    Thanks a lot for posting the script, we'll include it as an example.
  • Hello John,

    thank you very much for posting your Python code. I added your example to the inductive sensing FAQ

  • Hi All,
    I found in the inductive sensing FAQ (e2e.ti.com/.../295036) that the code above refers to LDC1612/14 and LDC1312/14 case. Is theoretically possible to extend its use (with some modifications) to LDC1000 case or is it impossible?

    Best regards
    Alberto
  • You don't need to...

    Take a look here:

    e2e.ti.com/.../295036

    Search for "phyton"

  • Hi John,
    first of all thank you for the script you shared above. In the link that you suggest (inductive sensing FAQ) if I search "python" I see your code for LDC1614. Now I wonder if I could extend it to the LDC1000 changing some rows of code.
    Best regards
    Alberto
  • The protocol for the LDC1000 can be found in the thread e2e.ti.com/.../1426287.

    Regards,

    ChrisO
  • Hi Chris,
    I can't find the protocol for the LDC1000 in the link you cite (e2e.ti.com/.../1426287). For protocol I mean something like the sequence of char that it's necessary to read or write on LDC1000 such as the instructions for the LDC1614 protocol that I found in this thread:

    ...
    Write register command

    Write register command is used to set desired register settings. It is formed as follow:

    4C 15 01 00 04 2A XX YY YY ZZ
    ....

    Best regards,
    Alberto
  • Sorry, somehow the link did not come through. The text I was referring to is below. The LDC1000 uses the same protocol:

    LDC13xx/16xx communication is accomplished via driver-simulated COM protocols. Settings are:

    Baud rate 115200

    No termination CHAR

    Data bits 8

    Parity None

    Stop bit 1

    Flow control: None

    Write register command

    Write register command is used to set desired register settings. It is formed as follow:

    4C 15 01 00 04 2A XX YY YY ZZ

    Where

    4C 15 01 00 04 2A = Write register command header.

    XX is the register address to be written, expressed as HEX. For example, if register 12 is x0C, so XX = 0C

    YY YY is the 2 bytes of data to be written, in HEX, MSB 1st.

    ZZ is CRC-8 check for the command string, which is explained below.

    Each HEX value represents corresponding ASCII character, which is written to COM port.

    For example, if we need to write to register 11 (x1B) a value of x820D, the command is

    4C 15 01 00 04 2A 1B 82 0D A3. In ASCII it appears as

    After writing a register it is required to read back 32 bytes – MCU response to a command. Convert ASCII string into array of 8-bit numbers. It consists of the command sent + 21 bytes of 00 + CRC value. In the above example, correct response is 4C 15 01 00 04 2A 1B 82 0D A3 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00A3.

    4th byte (indicated in red above) is an error field. If this byte is 00, there is no error.

    Read register command

    Read register command is used to check LDC register settings. Read process consists of 2 steps:

    1) Set register command, which is required to indicate which register is to be read. The command format is: 4C 15 01 00 02 2A XX ZZ, where XX is the register address to be read, and ZZ is CRC-8 check for the command string. For example, to read back register 1B the command is 4C 15 01 00 02 2A 1B 10. After sending this command it is required to read 32 bytes. The 4th byte will indicate an error, if any.

    2) Read register command, in the format 4C 14 01 00 02 2A 02 ZZ, where ZZ is CRC-8 check. After sending this command it is required to read 32 bytes, as noted above. The 4th byte will indicate an error, if any. 7th and 8th bytes are MSB and LSB bytes of the register value. For example, if we read register x1B value, the response is 4C 14 01 00 03 2A 82 0D C6 A3 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 C6



    Start streaming command

    To optimize data throughput a special command is implemented, which will continuously output data from LDC devices to COM port.

    To start streaming, send 4C 05 01 00 06 01 29 04 04 30 2A C1. After sending this command it is required to read 32 bytes. 4th byte will indicate an error, if any.

    After the stream is initialized, read 32 bytes at a time. An example read:

    4C30 0100 092A 0151 42CB 0150 5FFF 1C00 0000 0000 0000 0000 0000 0000 0000 001C

    Bytes 7-10 are the Ch0 data (marked in green), MSB 1st, bytes 11-14 are Ch1 data (marked in blue), MSB 1st. In this example, Ch0 data is x015142CB (22,102,731 in decimal), Ch1 is 01505FFF (22,044,671). Further conversion of the raw data to the frequency of oscillation is described in the LDC161x/131x datasheet

    Stop streaming command

    To stop the streaming, send the command 4C 06 01 00 01 01 D2. After sending this command it is required to read 32 bytes. 4th byte will indicate an error, if any.



    CRC-8 check

    CRC check is well described in en.wikipedia.org/.../Computation_of_cyclic_redundancy_checks

    Please refer to the link for more detailed information.

    The LDC 13xx/16xx EVMs use CRC-8 with polynomial coefficient indices of 8, 2, 1, and 0.

    Outlined below is one of the possible implementations:

    Convert each byte in the command to an array of Booleans (T = 1, F = 0), MSB being index 1. For example, xA7 becomes an array (T,F,T,F,F,T,T,T).

    Concatenate the array of bytes, 1st byte being indices 1-8, 2nd – bytes 9-16 etc. For example, xA70F becomes (T,F,T,F,F,T,T,T,F,F,F,F,T,T,T,T). Record the array size N.

    Form C = (T,F,F,F,F,F,T,T,T) – CRC array. Note that the indices of the non-zero coefficients are 8, 2, 1, 0.

    Append to the Boolean command array an array of 8 False (F,F,F,F,F,F,F,F) at the end. Denote this array A.

    For loop for i=1 to N

    IF A[i] = True then

    Get B = array A subset starting at index i, length 9

    B’ = B XOR C

    Replace B in A with B’

    End IF

    End loop

    Take the last 8 Booleans of the updated A, convert it to byte (MSB 1st). For example, if last 8 elements in A are (T,F,T,T,F,F,T,T), it converts to xB3

    This is desired CRC-8 check value (ZZ value in the document)
  • Hi Chris,

    I have some doubts about your reply. I notice that in LDC1000EVM the COM has a 9600 baud rate instead of 115200. My problem is that if I use the protocol above and the Python code writte by John (which is based on the indications and protocol rules above) I have wrong results from serial. I would like to have something like in Putty (see picture below) where I can read directly the L and Rp values without GUI. My target is to read L and Rp measurement with Python with LDC1000 as John did with LDC1614.

    Best regards

    Alberto

  • Hello Alberto,
    Please make sure that all the register address values are modified for LDC1000 in the code instead of LDC1614. Make sure that you are reading the correct registers for L and RP values.
    Also, can you please post a picture of the wrong results you got during serial communication.
    -Best Regards, Suhas R C
  • Hi Suhas,
    I'm using the same code written by John. I modified register address values for LDC1000 in this way:

    LDC1000_REVID ='00'
    LDC1000_RPMAX ='01'
    LDC1000_RPMIN ='02'
    LDC1000_SENSORFREQ ='03'
    LDC1000_LDCCONFIG ='04'
    LDC1000_CLKCONFIG ='05'
    LDC1000_THRESHILSB ='06'
    LDC1000_THRESHIMSB ='07'
    LDC1000_THRESLOLSB ='08'
    LDC1000_THRESLOMSB ='09'
    LDC1000_INTCONFIG ='0A'
    LDC1000_PWRCONFIG ='0B'
    LDC1000_STATUS ='20'
    LDC1000_PROXLSB ='21'
    LDC1000_PROXMSB ='22'
    LDC1000_FREQCTRLSB ='23'
    LDC1000_FREQCTRMID ='24'
    LDC1000_FREQCTRMSB ='25'

    # LDC BITMASKS
    LDC1000_BIT_AMPLITUDE ='18'
    LDC1000_BIT_RESPTIME ='07'
    LDC1000_BIT_CLKSEL ='02'
    LDC1000_BIT_CLKPD ='01'
    LDC1000_BIT_INTMODE ='07'
    LDC1000_BIT_PWRMODE ='01'
    LDC1000_BIT_STATUSOSC ='80'
    LDC1000_BIT_STATUSDRDYB ='40'
    LDC1000_BIT_STATUSWAKEUP ='20'
    LDC1000_BIT_STATUSCOMP ='10'

    When I run the code I see from the debug (in this case when I read the '25' register):

    ('Addr:', '25', 'Data:', '4c1401ea00cb02760000000000000000000000000000000000000000000000cb') which is very different from the correct type of reply like 4C 14 01 00 03 2A 82 0D C6 A3 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 C6 as indicated above in the previous answers.

    Best regards
    Alberto
  • PS: Compared to John's code I use " data_read = s" because I want to see the entire serial message. Moreover there is another difference in the code formed by the line "serial_port = serial.Serial(port='COM6', timeout=0.5, baudrate=9600, parity=serial.PARITY_NONE, bytesize=serial.EIGHTBITS,stopbits=serial.STOPBITS_ONE)"
    Everything else is equal to John's code.
  • Hi Alberto,

    The baud rate and parity do not matter, as they only exist for a physical COM port, and are not truly configured for a virtual COM port running over USB.

    Regards,

    ChrisO
  • Hi Chris,
    thank you for your clarification. However I still have read error. When I started to adapt John's code for LDC1000 my first idea is to use indication in e2e.ti.com/.../292002 together with the Matlab code of LDC1000 that I found in the LDC1000EVM online firmware repository. The final result is (for example for write a register):

    def write_reg(serial_port, reg, data):
    crc = crc8()
    serial_string = '02'+ reg + data +'00'
    serial_string = serial_string.decode('hex')
    crc_byte = chr(crc.crc(serial_string))
    serial_port.write(serial_string+crc_byte)

    Is it a bad approach?
    Best regards
    Alberto
  • Hi Alberto,

    The response you received wouldn't work because the commands you're attempting are for I2C devices, but the LDC1000 uses a SPI interface. You'll need to adjust the read and write register commands to the following format:

    • Write Register
      • 4C 11 01 00 02 AA DD ZZ
        • AA is the register address to write to
        • DD are the data bytes to write 
        • ZZ is the CRC of the packet (use the instructions about to calculate)
      • Response should be an echo of the packet sent
    • Read Register
      • 4C 10 01 00 02 RR CC ZZ
        • RR is the register to write to
        • CC is the number of bytes to read 
        • ZZ is the CRC of the packet (use the instructions about to calculate)

      • Response should be as follows:
        • 4C 10 01 00 NN RR DD ZZ
          • NN - Subtract 1 from this bytes the number of data bytes read from the register
          • RR is the register address read
          • DD are the data bytes read
          • ZZ is the CRC of the received packet (use the instructions about to calculate)

    Hope this helps!

    Best regards,

    Blair

  • Hi Alberto,

    Please see below a working code example for LDC1000.

    It was originally posted somewhere on TI forums, but I can't find the original thread.

    To forum administrators: please add it to FAQ.

    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    
    import sys
    import collections
    import serial
    import time
    import struct
    import msvcrt
    from array import *
    
    
    #############################################################################################
    # USB CDC commands
    LDC_READ = '03'
    LDC_WRITE = '02'
    LDC_FIRMWARE ='09'
    LDC_STREAM_ON = '06'
    LDC_STREAM_OFF = '07'
    #############################################################################################
    
    #############################################################################################
    # LDC1000 addressing space
    LDC1000_CMD_REVID 		= '00'
    LDC1000_CMD_RPMAX 		= '01'
    LDC1000_CMD_RPMIN 		= '02'
    LDC1000_CMD_SENSORFREQ 	= '03'
    LDC1000_CMD_LDCCONFIG 	= '04'
    LDC1000_CMD_CLKCONFIG 	= '05'
    LDC1000_CMD_THRESHILSB 	= '06'
    LDC1000_CMD_THRESHIMSB 	= '07'
    LDC1000_CMD_THRESLOLSB 	= '08'
    LDC1000_CMD_THRESLOMSB 	= '09'
    LDC1000_CMD_INTCONFIG 	= '0A'
    LDC1000_CMD_PWRCONFIG 	= '0B'
    LDC1000_CMD_STATUS	 	= '20'
    LDC1000_CMD_PROXLSB 	= '21'
    LDC1000_CMD_PROXMSB 	= '22'
    LDC1000_CMD_FREQCTRLSB	= '23'
    LDC1000_CMD_FREQCTRMID	= '24'
    LDC1000_CMD_FREQCTRMSB	= '25'
    
    
    DEBUG_PRINT_TX_DATA = 0
    DEBUG_PRINT_RX_DATA = 0
    DEBUG_PRINT_READ_DATA = 0
    
    
    def write_reg(serial_port, addr, data):
    	serial_port.write('02'+addr+data)
    	s = serial_port.read(32)
    	if DEBUG_PRINT_RX_DATA :
    		print("Read:", s )
    
    def read_reg(serial_port, addr):
    	serial_port.write('03'+addr+'00')
    	s = serial_port.read(32)
    	if DEBUG_PRINT_RX_DATA :
    		print("Read:", s )
    	data_read = s[8]
    	if DEBUG_PRINT_READ_DATA:
    		print("Addr:", addr,"Data:", data_read )
    	return data_read.encode('hex')
    
    def ldc_config(serial_port):
    	write_reg(serial_port, LDC1000_CMD_RPMAX,       '0E')
    	write_reg(serial_port, LDC1000_CMD_RPMIN,       '3B')
    	write_reg(serial_port, LDC1000_CMD_SENSORFREQ,  '94')
    	write_reg(serial_port, LDC1000_CMD_LDCCONFIG,   '17')
    	write_reg(serial_port, LDC1000_CMD_CLKCONFIG,   '02')
    	write_reg(serial_port, LDC1000_CMD_INTCONFIG,   '04')
    
    	write_reg(serial_port, LDC1000_CMD_THRESHILSB,  '50')
    	write_reg(serial_port, LDC1000_CMD_THRESHIMSB,  '14')
    	write_reg(serial_port, LDC1000_CMD_THRESLOLSB,  'C0')
    	write_reg(serial_port, LDC1000_CMD_THRESLOMSB,  '12')
    	
    	
    def main():
    	serial_port = serial.Serial(port='COM12', baudrate=115200)
    
    	write_reg (serial_port, LDC1000_CMD_PWRCONFIG, '00')
    	ldc_config (serial_port)
    	write_reg (serial_port, LDC1000_CMD_PWRCONFIG, '01')
    	# Read Proximity Data LSB to update data
    	try:
    	  while 1:
    		# do loop stuff
    		read_reg  (serial_port, LDC1000_CMD_PROXLSB)
    		data_lsb 	= read_reg  (serial_port, LDC1000_CMD_FREQCTRLSB)
    		data_msb 	= read_reg  (serial_port, LDC1000_CMD_FREQCTRMID)
    		status 		= read_reg  (serial_port, LDC1000_CMD_STATUS)
    
    		rp_min 		= read_reg  (serial_port, LDC1000_CMD_RPMAX)
    		rp_max 		= read_reg  (serial_port, LDC1000_CMD_RPMIN)
    		freq 		= read_reg  (serial_port, LDC1000_CMD_SENSORFREQ)
    		conf 		= read_reg  (serial_port, LDC1000_CMD_LDCCONFIG)
    		clk 		= read_reg  (serial_port, LDC1000_CMD_CLKCONFIG)
    		int 		= read_reg  (serial_port, LDC1000_CMD_INTCONFIG)
    		
    		th_hi_lsb		= read_reg  (serial_port, LDC1000_CMD_THRESHILSB)
    		th_hi_msb 		= read_reg  (serial_port, LDC1000_CMD_THRESHIMSB)
    		th_lo_lsb 		= read_reg  (serial_port, LDC1000_CMD_THRESLOLSB)
    		th_lo_msb 		= read_reg  (serial_port, LDC1000_CMD_THRESLOMSB)
    
    		
    		print("Frequency Counter=%s%s  Status=%s  rp_min=%s rp_max=%s freq=%s conf=%s clk=%s int=%s th_hi_lsb=%s th_hi_msb=%s th_lo_lsb=%s th_lo_msb=%s" % (data_msb, data_lsb, status, rp_min, rp_max, freq, conf, clk, int, th_hi_lsb, th_hi_msb, th_lo_lsb, th_lo_msb))
    		time.sleep(.5)
    
    	except KeyboardInterrupt:
    		exit()
    
    if __name__ == "__main__":
    	main()

  • Hi John,
    thank you very much! Really amazing! This is exactly what I was looking for. I see that the code uses the approach on which I wondered in my previous post but probably I made some mistakes when I tried to add CRC. Now I can see the same hex numbers that I saw with Putty! I think this code is very useful so I quote you about add this code to FAQ.
    Best regards
    Alberto
  • Hi Blair,
    thank you for your clarification. I knew that LDC1000 uses SPI instead of I2C but I didn't know how to adapt the protocol that I see for LDC1614 from previous posts to LDC1000 case. Now with your suggestions I will try to modify the code. For now I only have tested John's suggestion for LDC1000 which I confirm that works really well.
    Best regards
    Alberto
  • Hi John,
    thank you very much for sharing your code. I added it to the FAQ.