Skip to content

Commit ece9c36

Browse files
author
rogerclarkmelbourne
committed
Added code to 'get' the gpio mode of a pin, and have used it in SPIClass::begin() to store and reinstate the pin mode of the SPI NSS pin. This is a work around for 'features' in the STM32 silicon, which seem to change the GPIO mode of the SPI NSS (hardware - 'Software Select' pin)
1 parent ef03bcd commit ece9c36

3 files changed

Lines changed: 44 additions & 1 deletion

File tree

STM32F1/cores/maple/libmaple/gpio_f1.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,23 @@ void gpio_set_mode(gpio_dev *dev, uint8 pin, gpio_pin_mode mode) {
138138
}
139139
}
140140

141+
gpio_pin_mode gpio_get_mode(gpio_dev *dev, uint8 pin) {
142+
gpio_reg_map *regs = dev->regs;
143+
__io uint32 *cr = &regs->CRL + (pin >> 3);
144+
uint32 shift = (pin & 0x7) * 4;
145+
uint32 tmp = *cr;
146+
147+
uint32 crMode = (*cr>>shift) & 0x0F;
148+
149+
// could be pull up or pull down. Nee to check the ODR
150+
if (crMode==GPIO_INPUT_PD && ((regs->ODR >> pin) & 0x01) !=0 )
151+
{
152+
crMode = GPIO_INPUT_PU;
153+
}
154+
155+
return(crMode);
156+
}
157+
141158
/*
142159
* AFIO
143160
*/

STM32F1/libraries/SPI/src/SPI.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,17 +119,43 @@ SPIClass::SPIClass(uint32 spi_num) {
119119
*/
120120

121121
void SPIClass::begin(void) {
122+
gpio_pin_mode nssPinMode;
123+
int nssPin;
122124
if (dataMode >= 4) {
123125
ASSERT(0);
124126
return;
125127
}
128+
129+
#if BOARD_NR_SPI >= 1
130+
if (this->spi_d == SPI1)
131+
{
132+
nssPin=BOARD_SPI1_NSS_PIN;
133+
}
134+
#endif
135+
#if BOARD_NR_SPI >= 2
136+
if (this->spi_d == SPI2)
137+
{
138+
nssPin=BOARD_SPI2_NSS_PIN;
139+
}
140+
#endif
141+
#if BOARD_NR_SPI >= 3
142+
if (this->spi_d == SPI3)
143+
{
144+
nssPin=BOARD_SPI3_NSS_PIN;
145+
}
146+
#endif
147+
148+
149+
nssPinMode = gpio_get_mode(PIN_MAP[nssPin].gpio_device, PIN_MAP[nssPin].gpio_bit);// get and save NSS pin mode
150+
126151
uint32 flags = ((bitOrder == MSBFIRST ? SPI_FRAME_MSB : SPI_FRAME_LSB) | SPI_DFF_8_BIT | SPI_SW_SLAVE | SPI_SOFT_SS);
127152
spi_init(spi_d);
128153
configure_gpios(spi_d, 1);
129154
#ifdef SPI_DEBUG
130155
Serial.print("spi_master_enable("); Serial.print(clockDivider); Serial.print(","); Serial.print(dataMode); Serial.print(","); Serial.print(flags); Serial.println(")");
131156
#endif
132157
spi_master_enable(spi_d, (spi_baud_rate)clockDivider, (spi_mode)dataMode, flags);
158+
gpio_set_mode(PIN_MAP[nssPin].gpio_device, PIN_MAP[nssPin].gpio_bit, nssPinMode);// restore pin mode of nss pin (work around for bug in the STM32)
133159
}
134160

135161
void SPIClass::beginSlave(void) {

STM32F1/system/libmaple/include/libmaple/gpio.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ void gpio_init(gpio_dev *dev);
7171
void gpio_init_all(void);
7272
/* TODO flags argument version? */
7373
void gpio_set_mode(gpio_dev *dev, uint8 pin, gpio_pin_mode mode);
74-
74+
gpio_pin_mode gpio_get_mode(gpio_dev *dev, uint8 pin);
7575
/**
7676
* @brief Get a GPIO port's corresponding EXTI port configuration.
7777
* @param dev GPIO port whose exti_cfg to return.

0 commit comments

Comments
 (0)