# Issues Subscribing to SPI Bus with GPIO as Chip Select

**URL:** <https://forum.sierrawireless.com/t/issues-subscribing-to-spi-bus-with-gpio-as-chip-select/7975>\
**Category:** Open AT\
**Created:** [May 29, 2015, 9:37pm UTC](https://forum.sierrawireless.com/t/issues-subscribing-to-spi-bus-with-gpio-as-chip-select/7975 "2015-05-29T21:37:07Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![mattmc318](https://avatars.discourse-cdn.com/v4/letter/m/f4b2a3/32.png) [@mattmc318](https://forum.sierrawireless.com/u/mattmc318)\
**Post date:** [May 29, 2015, 9:37pm UTC](https://forum.sierrawireless.com/t/issues-subscribing-to-spi-bus-with-gpio-as-chip-select/7975/1 "2015-05-29T21:37:07Z")

</div>

Hello,

I’m having issues trying to subscribe to an SPI bus in Open AT. However, I followed the ADL documentation very closely and am still having trouble.

```auto
#include "adl_global.h"
#include "adl_gpio.h"
#include "adl_bus.h"
#include "generated.h"

// globals
adl_tmr_t *mainTicker;
adl_busSPISettings_t SpiSettings =
{
		0,
		ADL_BUS_SPI_CLK_MODE_0,
		ADL_BUS_SPI_ADDR_CS_GPIO,
		ADL_BUS_SPI_CS_POL_HIGH,
		ADL_BUS_SPI_MSB_FIRST,
		ADL_IO_GPIO | 20,
		ADL_BUS_SPI_LOAD_UNUSED,
		ADL_BUS_SPI_DATA_BIDIR,
		ADL_BUS_SPI_MASTER_MODE,
		ADL_BUS_SPI_BUSY_UNUSED
};
s32 SpiHandle;

void initSPI(void)
{
	SpiHandle = adl_busSubscribe(ADL_BUS_ID_SPI,1,&SpiSettings);

	switch( SpiHandle ) {
	case ADL_RET_ERR_PARAM:
		adl_atSendResponse(ADL_AT_UNS, "ADL_RET_ERR_PARAM\n");
		break;
	case ADL_RET_ERR_ALREADY_SUBSCRIBED:
		adl_atSendResponse(ADL_AT_UNS, "ADL_RET_ERR_ALREADY_SUBSCRIBED\n");
		break;
	case ADL_RET_ERR_BAD_HDL:
		adl_atSendResponse(ADL_AT_UNS, "ADL_RET_ERR_BAD_HDL\n");
		break;
	case ADL_RET_ERR_NOT_SUPPORTED:
		adl_atSendResponse(ADL_AT_UNS, "ADL_RET_ERR_NOT_SUPPORTED\n");
		break;
	case ADL_RET_ERR_SERVICE_LOCKED:
		adl_atSendResponse(ADL_AT_UNS, "ADL_RET_ERR_SERVICE_LOCKED\n");
		break;
	default:
		adl_atSendResponse(ADL_AT_UNS, "default\n");
		break;
	}
}

void SPI_task(void)
{
	adl_busAccess_t AccessConfig = {0,0};
	u8 test = 0xAA;
	adl_busWrite(SpiHandle, &AccessConfig, 1, &test);
}

void main_task(void)
{
	initSPI();
	mainTicker = (adl_tmr_t*) adl_tmrSubscribe (TRUE, 10,
			ADL_TMR_TYPE_100MS, (adl_tmrHandler_t) SPI_task);
}
```

The output: ADL\_RET\_ERR\_BAD\_HDL. According to the documentation, this value is returned “if a GPIO required by the provided bus configuration is currently  
subscribed by an application.” How could this be? I’m only using one port! What am I doing wrong here?

---

<div class="post-metadata">

**Author:** ![mattmc318](https://avatars.discourse-cdn.com/v4/letter/m/f4b2a3/32.png) [@mattmc318](https://forum.sierrawireless.com/u/mattmc318)\
**Post date:** [May 29, 2015, 9:38pm UTC](https://forum.sierrawireless.com/t/issues-subscribing-to-spi-bus-with-gpio-as-chip-select/7975/2 "2015-05-29T21:38:20Z")

</div>

Similar (unresolved) issue here:

[https://forum.sierrawireless.com/t/cant-subscribe-spi-bus-after-use-as-gpio/3537/1](https://forum.sierrawireless.com/t/cant-subscribe-spi-bus-after-use-as-gpio/3537/1)

---

<div class="post-metadata">

**Author:** ![davidc](https://avatars.discourse-cdn.com/v4/letter/d/a183cd/32.png) [@davidc](https://forum.sierrawireless.com/u/davidc)\
**Post date:** [May 29, 2015, 11:26pm UTC](https://forum.sierrawireless.com/t/issues-subscribing-to-spi-bus-with-gpio-as-chip-select/7975/3 "2015-05-29T23:26:52Z")

</div>

Hiya,

What module are you using? The thoughts below are with regards to the Q2686 and Q2698 modules.

Make sure that the GPIO is

1. not used by another module - eg not a GPIO used by the UART as (in the case of the UART) ALL 9 GPIO are used by the UART module even if you’re only using UART 5 wire or 2 wire mode. You can how the UARTs are assigned by using AT+WMFM. If the uart is ‘open’ that means it is under control of the firmware, and all the GPIO are assigned to the UART hardware.
2. If the module is Q2686/Q2687 make sure that the GPIO keyboard functionality is not enabled - see AT+WHCNF
3. If the GPIO is otherwise used by the Firmware - see AT+WIOM

All that said, from your code you are trying to use GPIO20 (hardware pin 48) as your CS - and my reading of the Q2686 and Q2698 PTS documents indicate that this GPIO is not shared between modules.

I’m also not sure if your Clock speed of 0 is correct - although the ADL guide says that it is. I use the following:

```auto
#define PCLK 13000 // Max Clock Freq in kHz)
#define SPICLK 6000 // desired clock freq (in kHz)

// SPI bus subscription data
// SPI2
const adl_busSPISettings_t SpiLcdConfig =
{
        (PCLK/(1 + SPICLK)), // SPI bus speed (should be 6000kHz)
        ADL_BUS_SPI_CLK_MODE_3, // SPI Bus mode (CLK idle HI, Data read on Rising Edge)
        ADL_BUS_SPI_ADDR_CS_GPIO, // Set up chip select pin (use GPIO pin)
        ADL_BUS_SPI_CS_POL_LOW, // chip select Active state (LOW)
        ADL_BUS_SPI_MSB_FIRST, // data are sent MSB first
        ADL_IO_GPIO | 35, // GPIO to use for CS - not applicable for CS_HARD
        ADL_BUS_SPI_LOAD_UNUSED, // LOAD Signal
        ADL_BUS_SPI_DATA_BIDIR, // DataLinesConf
        ADL_BUS_SPI_MASTER_MODE, // Master Node
        ADL_BUS_SPI_BUSY_UNUSED // Busy Signal
};

// BUS Handle
s32 SpiLcdHandle = ERROR;

s32 spiOpen( void )
{
	u32 maxClock;
    // subscribe to SPI bus (SPI2 for LCD)

	adl_regGetHWInteger("spi_02_Master_MaxFreqClock", (s32 *)&maxClock);
    TRACE (( 1, "spiInit: max SPI Clock [%d] ", maxClock ));

    SpiLcdHandle = adl_busSubscribe( ADL_BUS_ID_SPI, 2, (adl_busSettings_u *) &SpiLcdConfig);

    TRACE (( 1, "spiInit: SpiLcdHandle [%d] ", SpiLcdHandle ));

	return SpiLcdHandle;
}
```

to set up to talk to a SPI LCD on a Q2686 module.

Just out of interest, can you use GPIO31 (pin 22) as your CS line?

Let us all know how you get on.

ciao, Dave
