Seeing recent response to my original question on multiple chip selects, I've opted to share a modification to spi_master that I've implemented in part to make handling some serial LCDs, which use an added command pin, easier. By using a mask instead of pin number, it allows both pins to be changed in one call and ensures the two pins are synchronized. It also allows a single function call to configure all the chip selects associated with an SPI channel which I think makes for cleaner code. I've attached the entire file, but included a few snippets to illustrate changes.
I've left the code with #define to use it in either mask or pin# mode, but honestly don't think I will ever use it in any mode other than the mask mode.
The pin_slave_select declaratuin in spi_master_instance_t was changed to
#ifdef SPI_MASK_CS
uint32_t mask_slave_select; /**< Current chip select. */
uint32_t mask_chip_selects; /**< All chip selects */
#else
uint8_t pin_slave_select; /**< A pin for Slave Select. */
#endif**
and the spi_master_change_cs function's use of the pin_slave select was modified to:
#ifdef SPI_MASK_CS
p_spi_instance->mask_slave_select = cs_pin;
NRF_GPIO->OUTSET = p_spi_instance->mask_slave_select;
NRF_GPIO->DIRSET = p_spi_instance->mask_slave_select;
NRF_GPIO->OUTSET = p_spi_instance->mask_slave_select;
#else
p_spi_instance->pin_slave_select = cs_pin;
//A Slave select must be set as high before setting it as output,
//because during connect it to the pin it causes glitches.
nrf_gpio_pin_set(p_spi_instance->pin_slave_select);
nrf_gpio_cfg_output(p_spi_instance->pin_slave_select);
nrf_gpio_pin_set(p_spi_instance->pin_slave_select);
#endif
And spi_send_recv updated to
#ifdef SPI_MASK_CS
NRF_GPIO->OUTCLR = p_spi_instance->mask_slave_select;
#else
nrf_gpio_pin_clear(p_spi_instance->pin_slave_select);
#endif
My LCD initialization code looks like this:
#define SPI_MASK_CS
#define LCD_CS_MASK 0x00040000 /**< The value of bit 18 */
#define LCD_A0_MASK 0x00080000 /**< The value of bit 19 */
#define LCD_D0_MASK 0x00000000
#define LCD_CMND_MASK (LCD_A0_MASK | LCD_CS_MASK)
#define LCD_DATA_MASK (LCD_D0_MASK | LCD_CS_MASK)
spi_master_change_cs(LCD_SPI, LCD_CMND_MASK);
init_buf(m_tx_data_spi, m_rx_data_spi, TX_RX_MSG_LENGTH, 0);
m_tx_data_spi[0] = 0xA2; //LCD bias set
m_tx_data_spi[1] = 0xA0; //SEQ correspondance normal
m_tx_data_spi[2] = 0xC8; //COM dir reverse
...
m_tx_data_spi[9] = 0x81; //set Vs (CONTRAST)
m_tx_data_spi[10] = LCDcontrast;//value
m_tx_data_spi[11] = 0xA6;//display normal
m_tx_data_spi[12] = 0xAF;//display on
len = 13;
lcd_spi_send_recv(LCD_SPI, m_tx_data_spi, m_rx_data_spi, len);
The entire modified SDK8 version of spi_master spi_master.c