Skip to content

Commit d1dbb40

Browse files
author
Jamie Smith
authored
Fixes for SPI slave implementation (#336)
* Start on SPI slave comms test * Free pins in SPI and SPISlave destructor * Improve LPC1768 readable()
1 parent e604321 commit d1dbb40

File tree

4 files changed

+56
-29
lines changed

4 files changed

+56
-29
lines changed

drivers/include/drivers/SPISlave.h

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ namespace mbed {
3333

3434
/** A SPI slave, used for communicating with a SPI master device.
3535
*
36-
* The default format is set to 8 bits, mode 0 and a clock frequency of 1MHz.
36+
* The default format is set to 8 bits, mode 0.
3737
*
3838
* @note Synchronization level: Not protected
3939
*
@@ -80,6 +80,11 @@ class SPISlave : private NonCopyable<SPISlave> {
8080
SPISlave(const spi_pinmap_t &pinmap);
8181
SPISlave(const spi_pinmap_t &&) = delete; // prevent passing of temporary objects
8282

83+
/**
84+
* @brief Destructor. Frees the SPI peripheral so it can be used elsewhere.
85+
*/
86+
~SPISlave();
87+
8388
/** Configure the data transmission format.
8489
*
8590
* @param bits Number of bits per SPI frame (4 - 16).
@@ -96,12 +101,6 @@ class SPISlave : private NonCopyable<SPISlave> {
96101
*/
97102
void format(int bits, int mode = 0);
98103

99-
/** Set the SPI bus clock frequency.
100-
*
101-
* @param hz Clock frequency in hz (default = 1MHz).
102-
*/
103-
void frequency(int hz = 1000000);
104-
105104
/** Polls the SPI to see if data has been received.
106105
*
107106
* @return Presence of received data.
@@ -133,8 +132,6 @@ class SPISlave : private NonCopyable<SPISlave> {
133132
int _bits;
134133
/* Clock phase and polarity */
135134
int _mode;
136-
/* Clock frequency */
137-
int _hz;
138135

139136
#endif //!defined(DOXYGEN_ONLY)
140137
};

drivers/source/SPISlave.cpp

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -24,23 +24,34 @@ namespace mbed {
2424
SPISlave::SPISlave(PinName mosi, PinName miso, PinName sclk, PinName ssel) :
2525
_spi(),
2626
_bits(8),
27-
_mode(0),
28-
_hz(1000000)
27+
_mode(0)
2928
{
3029
spi_init(&_spi, mosi, miso, sclk, ssel);
3130
spi_format(&_spi, _bits, _mode, 1);
32-
spi_frequency(&_spi, _hz);
31+
32+
// For legacy compatibility, tell the HAL to set the frequency to 1MHz.
33+
// This is done even though it does not make sense to set the frequency of a slave device;
34+
// it has to run at whatever SCLK frequency the master supplies.
35+
spi_frequency(&_spi, 1000000);
3336
}
3437

3538
SPISlave::SPISlave(const spi_pinmap_t &pinmap) :
3639
_spi(),
3740
_bits(8),
38-
_mode(0),
39-
_hz(1000000)
41+
_mode(0)
4042
{
4143
spi_init_direct(&_spi, &pinmap);
4244
spi_format(&_spi, _bits, _mode, 1);
43-
spi_frequency(&_spi, _hz);
45+
46+
// For legacy compatibility, tell the HAL to set the frequency to 1MHz.
47+
// This is done even though it does not make sense to set the frequency of a slave device;
48+
// it has to run at whatever SCLK frequency the master supplies.
49+
spi_frequency(&_spi, 1000000);
50+
}
51+
52+
SPISlave::~SPISlave()
53+
{
54+
spi_free(&_spi);
4455
}
4556

4657
void SPISlave::format(int bits, int mode)
@@ -50,12 +61,6 @@ void SPISlave::format(int bits, int mode)
5061
spi_format(&_spi, _bits, _mode, 1);
5162
}
5263

53-
void SPISlave::frequency(int hz)
54-
{
55-
_hz = hz;
56-
spi_frequency(&_spi, _hz);
57-
}
58-
5964
int SPISlave::receive(void)
6065
{
6166
return (spi_slave_receive(&_spi));

targets/TARGET_NXP/TARGET_LPC176X/objects.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,12 @@ struct i2c_s {
7171
struct spi_s {
7272
LPC_SSP_TypeDef *spi;
7373
uint8_t bits_per_word;
74+
75+
// Pin names, so that we can unmap them when the SPI is freed
76+
PinName mosi_pin;
77+
PinName miso_pin;
78+
PinName sclk_pin;
79+
PinName ssel_pin;
7480
};
7581

7682
struct flash_s {

targets/TARGET_NXP/TARGET_LPC176X/spi_api.c

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,18 +34,30 @@ void spi_init_direct(spi_t *obj, const spi_pinmap_t *pinmap) {
3434
case SPI_1: LPC_SC->PCONP |= 1 << 10; break;
3535
}
3636

37-
// pin out the spi pins
38-
pin_function(pinmap->mosi_pin, pinmap->mosi_function);
39-
pin_mode(pinmap->mosi_pin, PullNone);
40-
pin_function(pinmap->miso_pin, pinmap->miso_function);
41-
pin_mode(pinmap->miso_pin, PullNone);
37+
// Pin out the spi pins.
38+
// Note: SCLK is the only pin that is always required.
39+
if(pinmap->mosi_pin != NC)
40+
{
41+
pin_function(pinmap->mosi_pin, pinmap->mosi_function);
42+
pin_mode(pinmap->mosi_pin, PullNone);
43+
}
44+
if(pinmap->miso_pin != NC)
45+
{
46+
pin_function(pinmap->miso_pin, pinmap->miso_function);
47+
pin_mode(pinmap->miso_pin, PullNone);
48+
}
4249
pin_function(pinmap->sclk_pin, pinmap->sclk_function);
4350
pin_mode(pinmap->sclk_pin, PullNone);
44-
4551
if (pinmap->ssel_pin != NC) {
4652
pin_function(pinmap->ssel_pin, pinmap->ssel_function);
4753
pin_mode(pinmap->ssel_pin, PullNone);
4854
}
55+
56+
// Save pins
57+
obj->mosi_pin = pinmap->mosi_pin;
58+
obj->miso_pin = pinmap->miso_pin;
59+
obj->sclk_pin = pinmap->sclk_pin;
60+
obj->ssel_pin = pinmap->ssel_pin;
4961
}
5062

5163
SPIName spi_get_peripheral_name(PinName mosi, PinName miso, PinName sclk)
@@ -80,7 +92,14 @@ void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel
8092
spi_init_direct(obj, &pinmap);
8193
}
8294

83-
void spi_free(spi_t *obj) {}
95+
void spi_free(spi_t *obj)
96+
{
97+
// Reset all pins to GPIO function
98+
if(obj->mosi_pin != NC) pin_function(obj->mosi_pin, 0);
99+
if(obj->miso_pin != NC) pin_function(obj->miso_pin, 0);
100+
pin_function(obj->sclk_pin, 0);
101+
if(obj->ssel_pin != NC) pin_function(obj->ssel_pin, 0);
102+
}
84103

85104
void spi_format(spi_t *obj, int bits, int mode, int slave) {
86105
ssp_disable(obj);
@@ -233,7 +252,7 @@ int spi_master_block_write(spi_t *obj, const char *tx_buffer, int tx_length,
233252
}
234253

235254
int spi_slave_receive(spi_t *obj) {
236-
return (ssp_readable(obj) && !ssp_busy(obj)) ? (1) : (0);
255+
return ssp_readable(obj);
237256
}
238257

239258
int spi_slave_read(spi_t *obj) {

0 commit comments

Comments
 (0)