SPI communication can't send data (WP8548 on MangOH)


#1

Hello,

I am trying to communicate with an external hardware which is connected with the mangOH through the IOT Breakout Board (IOT 0) using SPI. I am able to initialize the SPI but I am not able to send anything using the SPI. I used an oscilloscope (meassured on the CLK) to see if anything is sent, but only the le_spi_Configure displayed something on the oscilloscope, but I wasn’t able to see something when I send something.

I did the same with a second WP8548 which is based on an older Firmware without the spiService (and with the spi_sierra). On the older implementation, I had no problem to see the clock meassured with an oscilloscope (If required, I can post it too).

I think the problem is the spiService?! I hope somebody has an idea how I could fix this problem. Thanks!

(There is also a SPITest on the mangOH Github page which looks similar to the following code: https://github.com/mangOH/SpiTest)

On my WP8548 is FW14 installed and kernelmodules are loaded and the /dev/spidev0.0 is available:

root@swi-mdm9x15:~# lsmod | grep "spi*"
spisvc 694 0 - Live 0xbf07b000 (O)
spidev 6076 2 - Live 0xbf076000

Furthermore the spiService is running.

My programm looks like this:

#include "legato.h"
#include "interfaces.h"
/**
 * Handle for passing to related functions to access the SPI device
 */
static le_spi_DeviceHandleRef_t spiHandle = NULL;
void spi_open()
{
	le_result_t res_open; //Stores the error of le_spi_Open()
	int32_t mode = 3; //Set SPI mode 3
	uint8_t bits = 8; //Set 8 bits per word
	uint32_t speed = 96000; //Set max speed to 96khz
	int32_t msb = 0; //Set as 0 for MSB as first bit
	LE_DEBUG("Open SPI device");
	res_open = le_spi_Open("spidev0.0", &spiHandle);
	if (res_open == LE_OK)
	{
		LE_DEBUG("SPI opened on device %s", device_name);
	}
	else
	{
		LE_ERROR("le_spi_Open failed to open %s with result=%s", device_name, LE_RESULT_TXT(res_open));
	}
	le_spi_Configure(spiHandle, mode, bits, speed, msb);
}
/**
 * Initialize the SPI
 */
void spi_init()
{
	le_result_t res_write; //Stores the error of le_spi_WriteHD()
	const uint8_t activate_spi[4] = {0x00, 0xEB, 0xFF, 0x00}; //Write 0x00 to address 0xEBFF to activate ADE7878
	//activate_spi has to be sent 3 times to activate ADE7878
	for(int i = 0; i < 3; i++)
	{
		res_write = le_spi_WriteHD(spiHandle, activate_spi, NUM_ARRAY_MEMBERS(activate_spi));
		if (res_write != LE_OK)
		{
			LE_ERROR("le_spi_WriteHD failed on iteration %d with result=%s", i + 1, LE_RESULT_TXT(res_write));
		}
	}
	//Read Checksum Register the check whether connection has been opened successful
	le_result_t res_read;
	const uint8_t read_checksum[] = {0x01, 0xE5, 0x1f};
	uint8_t read_result[4];
	size_t read_result_size = NUM_ARRAY_MEMBERS(read_result);
	LE_INFO("Started to read...");
	res_read = le_spi_WriteReadHD(spiHandle, read_checksum, NUM_ARRAY_MEMBERS(read_checksum),
	read_result, &read_result_size);
	if (res_read == LE_OK)
	{
		if (read_checksum[3] == 0x33 && read_checksum[4] == 0x66 && read_checksum[5] == 0x67 && read_checksum[6] == 0x87)
		{
			LE_DEBUG("ADE7878 checksum read - Checksum: %d %d %d %d \n", read_result[0], read_result[1], read_result[2], read_result[3]);
		}
		else
		{
			LE_DEBUG("Error opening SPI connection - Checksum: %d %d %d %d \n", read_result[0], read_result[1], read_result[2], read_result[3]);
		}
	}
	else
	{
		LE_ERROR("le_spi_ReadHD failed with result=%s", LE_RESULT_TXT(res_read));
	}
}
COMPONENT_INIT
{
	spi_open();
	spi_init();
}

My Component.cdef looks like this:

sources:
{
SPITestComponent.c
}
requires:
{
api:
{
le_spi = ${LEGATO_ROOT}/interfaces/le_spi.api
}
}

And my SPITest.adef like this:

version: 1.0.0
sandboxed: false
start: manual
bindings:
{
spitest.SPITestComponent.le_spi -> spiService.le_spi
}
maxFileSystemBytes: 512K
executables:
{
spitest = ( SPITestComponent )
}
processes:
{
envVars:
{
LE_LOG_LEVEL = DEBUG
}
run:
{
( spitest )
}
maxCoreDumpFileBytes: 512K
maxFileBytes: 512K
}

I get the following output:

Jun 8 12:18:12 | supervisor[500]/supervisor T=main | resourceLimits.c SetRLimitValue() 282 | Setting resource limit maxCoreDumpFileBytes to value 524288.
Jun 8 12:18:12 | supervisor[500]/supervisor T=main | resourceLimits.c SetRLimitValue() 282 | Setting resource limit maxFileBytes to value 524288.
Jun 8 12:18:12 | supervisor[500]/supervisor T=main | resourceLimits.c SetRLimitValue() 282 | Setting resource limit maxLockedMemoryBytes to value 8192.
Jun 8 12:18:12 | supervisor[500]/supervisor T=main | resourceLimits.c SetRLimitValue() 282 | Setting resource limit maxFileDescriptors to value 256.
Jun 8 12:18:12 | supervisor[500]/supervisor T=main | resourceLimits.c SetRLimitValue() 282 | Setting resource limit maxMQueueBytes to value 512.
Jun 8 12:18:12 | supervisor[500]/supervisor T=main | resourceLimits.c SetRLimitValue() 282 | Setting resource limit maxThreads to value 20.
Jun 8 12:18:12 | supervisor[500]/supervisor T=main | resourceLimits.c SetRLimitValue() 282 | Setting resource limit maxQueuedSignals to value 100.
Jun 8 12:18:12 | supervisor[500]/supervisor T=main | proc.c proc_Start() 1190 | Starting process ‘spitest’ with pid 3665
Jun 8 12:18:12 | supervisor[3665]/supervisor T=main | proc.c proc_Start() 1155 | Execing 'spitest’
Jun 8 12:18:12 | UNKNOWN[3665]/framework T=unknown | LE_FILENAME InitPool() 303 | Memory pool name ‘framework.hashMap_refPathIteratorMap’ is truncated to 'framework.hashMap_refPathIterat’
Jun 8 12:18:12 | UNKNOWN[3665]/framework T=main | LE_FILENAME InitPool() 303 | Memory pool name ‘framework.hashMap_refEventHandlers’ is truncated to 'framework.hashMap_refEventHandl’
Jun 8 12:18:12 | UNKNOWN[3665]/framework T=main | LE_FILENAME InitPool() 303 | Memory pool name ‘framework.hashMap_refDefault Timer SafeRe’ is truncated to 'framework.hashMap_refDefault Ti’
Jun 8 12:18:12 | UNKNOWN[3665]/framework T=main | LE_FILENAME InitPool() 303 | Memory pool name ‘framework.MessagingClientInterfaces’ is truncated to 'framework.MessagingClientInterf’
Jun 8 12:18:12 | UNKNOWN[3665]/framework T=main | LE_FILENAME InitPool() 303 | Memory pool name ‘framework.hashMap_refHandlersRef’ is truncated to 'framework.hashMap_refHandlersRe’
Jun 8 12:18:12 | UNKNOWN[3665]/framework T=main | LE_FILENAME InitPool() 303 | Memory pool name ‘framework.hashMap_MessagingServices’ is truncated to 'framework.hashMap_MessagingServ’
Jun 8 12:18:12 | UNKNOWN[3665]/framework T=main | LE_FILENAME InitPool() 303 | Memory pool name ‘framework.hashMap_MessagingClients’ is truncated to 'framework.hashMap_MessagingClie’
Jun 8 12:18:12 | UNKNOWN[3665]/framework T=main | LE_FILENAME InitPool() 303 | Memory pool name ‘framework.PipelineSIGCHLD-reports’ is truncated to 'framework.PipelineSIGCHLD-repor’
Jun 8 12:18:12 | UNKNOWN[3665]/framework T=main | LE_FILENAME le_mem_ForceAlloc() 841 | Memory pool ‘framework.DestructorObjs’ overflowed. Expanded to 1 blocks.
Jun 8 12:18:12 | UNKNOWN[3665]/ T=main | _componentMain.c _SPITestComponent_Init() 29 | Initializing SPITestComponent component library.
Jun 8 12:18:12 | UNKNOWN[3665]/framework T=main | LE_FILENAME InitPool() 303 | Memory pool name ‘framework.hashMap_refle_spi_ClientHandler’ is truncated to 'framework.hashMap_refle_spi_Cli’
Jun 8 12:18:12 | UNKNOWN[3665]/framework T=main | LE_FILENAME msgMessage_CreatePool() 112 | Pool name truncated to ‘msgs-87787d2f610390791c34d1db20’ for protocol ‘87787d2f610390791c34d1db20b78ef7’.
Jun 8 12:18:12 | UNKNOWN[3665]/framework T=main | LE_FILENAME InitPool() 303 | Memory pool name ‘framework.msgs-87787d2f610390791c34d1db20’ is truncated to 'framework.msgs-87787d2f61039079’
Jun 8 12:18:12 | UNKNOWN[3665]/framework T=main | LE_FILENAME le_mem_ForceAlloc() 841 | Memory pool ‘.le_spi_ClientThreadData’ overflowed. Expanded to 1 blocks.
Jun 8 12:18:12 | UNKNOWN[3665]/framework T=main | le_spi_client.c DoConnectService() 391 | ======= Starting client for ‘spitest.SPITestComponent.le_spi’ service ========
Jun 8 12:18:12 | spitest[3665]/framework T=main | LE_FILENAME InitPool() 303 | Memory pool name ‘framework.msgs-LogControlProtocol’ is truncated to 'framework.msgs-LogControlProtoc’
Jun 8 12:18:12 | spitest[3665]/spitest_exe T=main | _main.c main() 56 | == Starting Event Processing Loop ==
Jun 8 12:18:12 | spitest[3665]/SPITestComponent T=main | SPITestComponent.c spi_open() 31 | Open SPI device
Jun 8 12:18:12 | spitest[3665]/framework T=main | le_spi_client.c le_spi_Open() 560 | Sending message to server and waiting for response : 13 bytes sent
Jun 8 12:18:12 | spitest[3665]/SPITestComponent T=main | SPITestComponent.c spi_open() 35 | SPI opened on device spidev0.0
Jun 8 12:18:12 | spitest[3665]/framework T=main | le_spi_client.c le_spi_Configure() 705 | Sending message to server and waiting for response : 17 bytes sent
Jun 8 12:18:12 | spitest[3665]/framework T=main | le_spi_client.c le_spi_WriteHD() 848 | Sending message to server and waiting for response : 12 bytes sent
Jun 8 12:18:12 | spitest[3665]/framework T=main | le_spi_client.c le_spi_WriteHD() 848 | Sending message to server and waiting for response : 12 bytes sent
Jun 8 12:18:12 | spitest[3665]/framework T=main | le_spi_client.c le_spi_WriteHD() 848 | Sending message to server and waiting for response : 12 bytes sent
Jun 8 12:18:12 | spitest[3665]/SPITestComponent T=main | SPITestComponent.c spi_init() 74 | Started to read…
Jun 8 12:18:12 | spitest[3665]/framework T=main | le_spi_client.c le_spi_WriteReadHD() 777 | Sending message to server and waiting for response : 15 bytes sent
Jun 8 12:18:12 | spitest[3665]/SPITestComponent T=main | SPITestComponent.c spi_init() 88 | Error opening SPI connection - Checksum: 0 0 0 0


#2

Hi,

It seems that you are writing 3 bytes stored in the array read_checksum [0x01, 0xE5, 0x1F] and then you are reading 4 bytes into the array read_result. Then you have a line that does:
if (read_checksum[3] == 0x33 && read_checksum[4] == 0x66 && read_checksum[5] == 0x67 && read_checksum[6] == 0x87)

However, since read_checksum is only of size 3, accessing array indexes 3 through 6 is illegal. Shouldn’t you be checking read_result[0] through read_result[3]?

Clearly you weren’t expecting to read all zeros back. If you have access to a logic analyzer, I suggest that you monitor your SPI communication and check what the signals on the wires look like.


#3

Thanks, that was definitely a mistake. The final problem was the breakout board, which was connected to the wrong pins… Now it is working.