SPI configuration
응답
17. 3. 7 오전 10:46

Hello,

I am trying to interface to a peripheral using SPI. My peripheral detects correctly the SPI Chip Select change of state but when I write data from XDK it doesn't seem to be correctly handled on the other side. There is one SPI parameter that I wasn't able to check on the XDK: my peripheral requires MSB first in the payload but I haven't seen any bitorder init function. 

Someone could confirm if XDK uses MSB first or LSB first by default? And can it be changed through an existing function?

 

Thanks,

Aurelien

0 (0 투표)
RE: SPI configuration
응답
17. 3. 7 오후 11:50 as a reply to Aurelien Lequertier.

Hello Aurelien,

there is indeed an configuration in the SPI interface which sends the MSB first as default. 

You can take a look at this specific part in SPI_cc.c at line 462. Unfortunately the interface SPI_ih.h contains no function which sets the MSB or LSB first.

Please tell me if this is helpful and do not hesitate to ask if you have further questions.

Kind regards,
Franjo

0 (0 투표)
RE: SPI configuration
응답
17. 4. 10 오후 1:21 as a reply to Franjo Stjepandic.

Hi Franjo,

Thanks for your reply, I was out of office for some time and started again on this project last week.

As I was still having problems with the SPI I tried my SPI module with an Arduino and was able to make it work. Now I've switched back to the XDK but still having issues.

My SPI init params should be ok:

	/* Init PTD driver */
	PTD_portInit();
	// Enable XDK Gateway Power pins
	PTD_pinModeSet(PTD_GET_PORT_PIN_MODE_DOUT(WIFI_SD_VDD_PORT));
	/* Enable SPI pins */
	PTD_pinModeSet(PTD_GET_PORT_PIN_MODE_DOUT(EXTENSION_US2_MOSI)); // PB4
	PTD_pinModeSet(PTD_GET_PORT_PIN_MODE_DOUT(EXTENSION_US2_MISO)); // PB3
	PTD_pinModeSet(PTD_GET_PORT_PIN_MODE_DOUT(EXTENSION_US2_SCK)); // PB5
	PTD_pinModeSet(PTD_GET_PORT_PIN_MODE_DOUT(EXTENSION_US2_CS)); // PD8

	/* Enable GPIO for Ack input*/
	PTD_pinModeSet(PTD_PORT_EXTENSION_GPIO_IN_OUT_0, PTD_PIN_EXTENSION_GPIO_IN_OUT_0,
			gpioModeInput, PTD_GPIO_PULLUP); //PA1

	/* Selecting the SPI Port number, Clock mode, Route location and Baudrate */
	initParams.portNumber = SPI2; /* SPI port number */
	initParams.clockMode = SPI_CLOCK_MODE_CPOL0_CPHA1; /* SPI mode configuration */
	initParams.routeLocation = SPI_ROUTE_LOCATION1; /* SPI Route location fixed */
	initParams.txBuf_p = txBuf; /* Pointer to the buffer that is to be used as the serial device's holds bytes that are to be transmitted.*/
	initParams.rxBuf_p = rxBuf; /* Pointer to the circular buffer that holds the bytes received by the driver */
	initParams.txBufSize = 50; /* Capacity in bytes of the transmit buffer */
	initParams.rxBufSize = 50; /* Capacity in bytes of the Receive buffer */
	initParams.baudrate = 125000; //here setting the baudrate to 125 kbaud (max is 1 Mbaud)

 

Then I manage the SPI send and receive data inside a task (so I can use vTaskDelay() to add pauses in the flow). The Chip Select clear is correctly detected by my SPI module (there is an additional Input PIN that is driven low to detect it).  Then I use SPI_write() to send 2 bytes. I don't need to read the corresponding MISO but if I put the writeOnly flag to 1, the first SPI_write() call always returns "SPI_SERIAL_READ_FAILED".  Next byte returns SPI_SUCCESS.

 

I have tried the following functions but with no success, as well as different baudrate values:

- SPI_write(&spiHandle, &writeBuf[0], 1, 1) in a loop for each byte

- SPI_write(&spiHandle, &writeBuf, bufLength, 1);

- SPI_writeReadInOut(&spiHandle, &writeBuf[0], &readBuf[0]) in a loop for each byte

 

My module drives high a GPIO pin if SPI reception is successful.

 

Is there a way to enable more SPI debugging?

Do you know if dealing with SPI in a task could be a problem?

 

Thanks,

Aurelien

0 (0 투표)
RE: SPI configuration
응답
17. 4. 11 오후 3:37 as a reply to Aurelien Lequertier.

Hello Aurelien,

I won't make any detailed suggestions about your code before I perform an own test, but on the first glance it should work as intended. I will do some tests tomorrow.

I assume it could be an issue with the receiving SPI functionality and the operating task. Did you try if it worked without the operating task?

In addition, you can use a J-LINK debugger to debug every piece of your SPI XDK implementation to find the cause of the issue.

Meanwhile, please do not hesitate to ask if you have further questions.

Kind regards,
Franjo

0 (0 투표)
RE: SPI configuration
응답
17. 4. 11 오전 10:16 as a reply to Franjo Stjepandic.

Hi Franjo,

I haven't tried without the operating tasks. After clearing out the SPI CS pin, I need to wait for my module to set an input pin high (Ack pin) before writing the data. Apparently I cannot use the C "sleep()" function so I am not sure how to implement without the task. Maybe with interrupts but I haven't looked into this yet.

Thanks for your help,

Aurelien

0 (0 투표)
RE: SPI configuration
응답
17. 4. 12 오전 11:37 as a reply to Aurelien Lequertier.

Hello Aurelien,

Unfortunately I was not able to complete the promised test, because it is more complex than I first expected. But I will do it the next couple of days.

Nevertheless I think I can help you without the test. You are not bound to an operating task to use vTaskDelay(). You can use it in appInitSystem(), too, to delay your application.

Besides, if you are waiting for an input high state from your external device, wouldn't it make sense to delay your application with a loop until you receive the high state on your particular input pin?

Please tell me if this are possible solutions for your purpose. In the meantime, do not hesitate to ask if you have further questions.

Kind regards,
Franjo

0 (0 투표)
RE: SPI configuration
응답
17. 4. 13 오전 8:17 as a reply to Franjo Stjepandic.

Hi Franjo,

Thanks for the info on the vTaskDelay().

FYI here's my complete code with my while loop:

        // Enabling the SPI Chip select
		PTD_pinOutClear(PTD_PORT_EXTENSION_US2_CS, PTD_PIN_EXTENSION_US2_CS);
		printf("SEND: Set CS Select\n");

		// Wait for Ack pin low
		while (PTD_pinInGet(PTD_PORT_EXTENSION_GPIO_IN_OUT_0, PTD_PIN_EXTENSION_GPIO_IN_OUT_0) == GPIO_STATE_ON) {
			vTaskDelay(MILLISECONDS(1));
		}
		printf("SEND: Ack is low\n");

		// Send data
		printf("SENDING: %02x %02x\n", writeBuf[0], writeBuf[1]);
		spiRet = SPI_write(&spiHandle, &writeBuf[0], 1, 1); /* Transmitting the data */
		printf("return: %d\n", spiRet);
		spiRet = SPI_write(&spiHandle, &writeBuf[1], 1, 1); /* Transmitting the data */
		printf("return: %d\n", spiRet);
		printf("SEND: SPI write done\n");

		// Wait Ack pin high
		while (PTD_pinInGet(PTD_PORT_EXTENSION_GPIO_IN_OUT_0, PTD_PIN_EXTENSION_GPIO_IN_OUT_0) == GPIO_STATE_OFF) {
			vTaskDelay(MILLISECONDS(1));
		}
		printf("SEND: Ack is high\n");

		/* Disabling the SPI Chip select */
		PTD_pinOutSet(PTD_PORT_EXTENSION_US2_CS, PTD_PIN_EXTENSION_US2_CS);

 

I will make a test with vTaskDelay in the appInitSystem().

Also quick question: if I power my module using the 3V3 pin on the XDK gateway, will the other GPIOs output 3V3? Same for inputs, are GPIOS expect 3V3 or there is a wider range?

 

Thanks,

Aurelien

0 (0 투표)
RE: SPI configuration
응답
17. 4. 13 오후 12:28 as a reply to Aurelien Lequertier.

I have good news!

MOSI and MISO pins were reversed, I am now able to send and receive data.
Looks like the XDK extension bus guide is incorrect:

http://xdk.bosch-connectivity.com/xdk_docs/html/_x_d_k__e_x_t_e_n_s_i_o_n__b_u_s__g_u_i_d_e.html

B5 PB4 US2 MOSI operations EXTENSION_US2_MOSI
B6 PB3 US2 MISO operations EXTENSION_US2_MISO

 

MOSI should be PB3 and MISO PB4.

 

Thanks for your help,

Aurelien

0 (0 투표)
RE: SPI configuration
응답
17. 4. 18 오전 11:02 as a reply to Aurelien Lequertier.

Hello Aurelien,

I am glad to hear that you made it work. It is currently no mistake within the extension bus guide, only the pins are wrong labeled on the extension bus. This fact is mentioned in the technical overview guide.

Regarding your question, the GPIO pins on the extension bus are generally limited to output voltages of 2.5V. The supply pin you are using to power your external module is the only one providing an output voltage of 3.3V. Please note that all pins of the extension bus are additionally
restricted to currents of 6 mA.

For more information, please refer to section 4 in the general information guide.

Please tell me if this is helpful and do not hesitate to ask if you have further questions.

Kind regards,
Franjo

0 (0 투표)
RE: SPI configuration
응답
17. 4. 20 오후 2:16 as a reply to Franjo Stjepandic.

Hi Franjo,

Thanks for the explanation, I guess I didn't read the whole guide ;-)

Everything works perfectly now! Just one last question regarding the current: the power pin (3V3 or 2V5) can provide up to 100 mA right? Any idea of max peak current that can be provided by it? For instance could 200-250mA for a 2 sec period every 10 minutes would work?

 

Thanks,

Aurelien

0 (0 투표)
RE: SPI configuration
응답
17. 4. 20 오후 3:44 as a reply to Aurelien Lequertier.

Hello Aurelien,

I am glad to hear that your implementation is working fine.
Regarding your question, I assume the 3.3 V power pin supply current is limited in the same range as the other GPIO pins. Thus I think it can only provide supply currents in the range of 0,5 ,2,6 and 20 mA. The extension bus itself is also limited to 50 mA. Due to this limitation of the complete extension bus, I don't think that the 3.3 V is able to provide 100 mA or 200 to 250 mA peaks.  

May I ask what exactly you are trying to build to need such a current peak?

Kind regards,
Franjo

0 (0 투표)
RE: SPI configuration
응답
17. 4. 21 오후 12:33 as a reply to Franjo Stjepandic.

Hi Franjo,

The following guide mentions 100 mA max continuous/peak current on 3V3 and 2V5 pins:

https://xdk.bosch-connectivity.com/documents/37728/87798/XDK_Getting_Started.pdf/9fca7e8c-a2d9-4416-8925-289dd07cd3b6

We are connecting a wireless module (sigfox technology) to the XDK gateway. In Europe our module is around 30 mA max current but in US it can reach 200 mA for up to 400ms.

Best,

Aurelien

0 (0 투표)
RE: SPI configuration
응답
17. 4. 24 오후 6:32 as a reply to Aurelien Lequertier.

Hello Aurelien,


You are right, the 3.3 V can provide 100 mA, according to the information from the general information and technical overview guide. Thus the value is set for both continuous current and peak current.

In addition, I took a look at the reference manual for the EFM32 micro controller of the XDK and the block diagram in the general information guide on page 9. According to those, the EFM32 and the peripherals are supplied by a 3.3V voltage regulator. I assume this is the internal voltage regulator of the
EFM32 micro controller, which can only provide an continuous output current of 50 mA. Thus I assume the mentioned 100 mA are the maximum peak value, too.

Furthermore, I will request additional information about the peak current of the 3.3V pin.

For now, I recommend to stay below the mentioned 100 mA, because both the 3.3V power pin and the EFM32 are powered by the same instance. A current gain of 200 mA over 400 ms would cause unknown behavior for all other consumer of that instance (especially the EFM32 micro controller).


Please tell me if this is helpful and do not hesitate to ask if you have further questions.

Kind regards,
Franjo

0 (0 투표)