mirror of https://github.com/ARMmbed/mbed-os.git
Fixes for SPI slave implementation (#336)
* Start on SPI slave comms test * Free pins in SPI and SPISlave destructor * Improve LPC1768 readable()pull/15530/head
parent
e6043218fd
commit
d1dbb405c8
|
@ -33,7 +33,7 @@ namespace mbed {
|
|||
|
||||
/** A SPI slave, used for communicating with a SPI master device.
|
||||
*
|
||||
* The default format is set to 8 bits, mode 0 and a clock frequency of 1MHz.
|
||||
* The default format is set to 8 bits, mode 0.
|
||||
*
|
||||
* @note Synchronization level: Not protected
|
||||
*
|
||||
|
@ -80,6 +80,11 @@ public:
|
|||
SPISlave(const spi_pinmap_t &pinmap);
|
||||
SPISlave(const spi_pinmap_t &&) = delete; // prevent passing of temporary objects
|
||||
|
||||
/**
|
||||
* @brief Destructor. Frees the SPI peripheral so it can be used elsewhere.
|
||||
*/
|
||||
~SPISlave();
|
||||
|
||||
/** Configure the data transmission format.
|
||||
*
|
||||
* @param bits Number of bits per SPI frame (4 - 16).
|
||||
|
@ -96,12 +101,6 @@ public:
|
|||
*/
|
||||
void format(int bits, int mode = 0);
|
||||
|
||||
/** Set the SPI bus clock frequency.
|
||||
*
|
||||
* @param hz Clock frequency in hz (default = 1MHz).
|
||||
*/
|
||||
void frequency(int hz = 1000000);
|
||||
|
||||
/** Polls the SPI to see if data has been received.
|
||||
*
|
||||
* @return Presence of received data.
|
||||
|
@ -133,8 +132,6 @@ protected:
|
|||
int _bits;
|
||||
/* Clock phase and polarity */
|
||||
int _mode;
|
||||
/* Clock frequency */
|
||||
int _hz;
|
||||
|
||||
#endif //!defined(DOXYGEN_ONLY)
|
||||
};
|
||||
|
|
|
@ -24,23 +24,34 @@ namespace mbed {
|
|||
SPISlave::SPISlave(PinName mosi, PinName miso, PinName sclk, PinName ssel) :
|
||||
_spi(),
|
||||
_bits(8),
|
||||
_mode(0),
|
||||
_hz(1000000)
|
||||
_mode(0)
|
||||
{
|
||||
spi_init(&_spi, mosi, miso, sclk, ssel);
|
||||
spi_format(&_spi, _bits, _mode, 1);
|
||||
spi_frequency(&_spi, _hz);
|
||||
|
||||
// For legacy compatibility, tell the HAL to set the frequency to 1MHz.
|
||||
// This is done even though it does not make sense to set the frequency of a slave device;
|
||||
// it has to run at whatever SCLK frequency the master supplies.
|
||||
spi_frequency(&_spi, 1000000);
|
||||
}
|
||||
|
||||
SPISlave::SPISlave(const spi_pinmap_t &pinmap) :
|
||||
_spi(),
|
||||
_bits(8),
|
||||
_mode(0),
|
||||
_hz(1000000)
|
||||
_mode(0)
|
||||
{
|
||||
spi_init_direct(&_spi, &pinmap);
|
||||
spi_format(&_spi, _bits, _mode, 1);
|
||||
spi_frequency(&_spi, _hz);
|
||||
|
||||
// For legacy compatibility, tell the HAL to set the frequency to 1MHz.
|
||||
// This is done even though it does not make sense to set the frequency of a slave device;
|
||||
// it has to run at whatever SCLK frequency the master supplies.
|
||||
spi_frequency(&_spi, 1000000);
|
||||
}
|
||||
|
||||
SPISlave::~SPISlave()
|
||||
{
|
||||
spi_free(&_spi);
|
||||
}
|
||||
|
||||
void SPISlave::format(int bits, int mode)
|
||||
|
@ -50,12 +61,6 @@ void SPISlave::format(int bits, int mode)
|
|||
spi_format(&_spi, _bits, _mode, 1);
|
||||
}
|
||||
|
||||
void SPISlave::frequency(int hz)
|
||||
{
|
||||
_hz = hz;
|
||||
spi_frequency(&_spi, _hz);
|
||||
}
|
||||
|
||||
int SPISlave::receive(void)
|
||||
{
|
||||
return (spi_slave_receive(&_spi));
|
||||
|
|
|
@ -71,6 +71,12 @@ struct i2c_s {
|
|||
struct spi_s {
|
||||
LPC_SSP_TypeDef *spi;
|
||||
uint8_t bits_per_word;
|
||||
|
||||
// Pin names, so that we can unmap them when the SPI is freed
|
||||
PinName mosi_pin;
|
||||
PinName miso_pin;
|
||||
PinName sclk_pin;
|
||||
PinName ssel_pin;
|
||||
};
|
||||
|
||||
struct flash_s {
|
||||
|
|
|
@ -34,18 +34,30 @@ void spi_init_direct(spi_t *obj, const spi_pinmap_t *pinmap) {
|
|||
case SPI_1: LPC_SC->PCONP |= 1 << 10; break;
|
||||
}
|
||||
|
||||
// pin out the spi pins
|
||||
pin_function(pinmap->mosi_pin, pinmap->mosi_function);
|
||||
pin_mode(pinmap->mosi_pin, PullNone);
|
||||
pin_function(pinmap->miso_pin, pinmap->miso_function);
|
||||
pin_mode(pinmap->miso_pin, PullNone);
|
||||
// Pin out the spi pins.
|
||||
// Note: SCLK is the only pin that is always required.
|
||||
if(pinmap->mosi_pin != NC)
|
||||
{
|
||||
pin_function(pinmap->mosi_pin, pinmap->mosi_function);
|
||||
pin_mode(pinmap->mosi_pin, PullNone);
|
||||
}
|
||||
if(pinmap->miso_pin != NC)
|
||||
{
|
||||
pin_function(pinmap->miso_pin, pinmap->miso_function);
|
||||
pin_mode(pinmap->miso_pin, PullNone);
|
||||
}
|
||||
pin_function(pinmap->sclk_pin, pinmap->sclk_function);
|
||||
pin_mode(pinmap->sclk_pin, PullNone);
|
||||
|
||||
if (pinmap->ssel_pin != NC) {
|
||||
pin_function(pinmap->ssel_pin, pinmap->ssel_function);
|
||||
pin_mode(pinmap->ssel_pin, PullNone);
|
||||
}
|
||||
|
||||
// Save pins
|
||||
obj->mosi_pin = pinmap->mosi_pin;
|
||||
obj->miso_pin = pinmap->miso_pin;
|
||||
obj->sclk_pin = pinmap->sclk_pin;
|
||||
obj->ssel_pin = pinmap->ssel_pin;
|
||||
}
|
||||
|
||||
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
|
|||
spi_init_direct(obj, &pinmap);
|
||||
}
|
||||
|
||||
void spi_free(spi_t *obj) {}
|
||||
void spi_free(spi_t *obj)
|
||||
{
|
||||
// Reset all pins to GPIO function
|
||||
if(obj->mosi_pin != NC) pin_function(obj->mosi_pin, 0);
|
||||
if(obj->miso_pin != NC) pin_function(obj->miso_pin, 0);
|
||||
pin_function(obj->sclk_pin, 0);
|
||||
if(obj->ssel_pin != NC) pin_function(obj->ssel_pin, 0);
|
||||
}
|
||||
|
||||
void spi_format(spi_t *obj, int bits, int mode, int slave) {
|
||||
ssp_disable(obj);
|
||||
|
@ -233,7 +252,7 @@ int spi_master_block_write(spi_t *obj, const char *tx_buffer, int tx_length,
|
|||
}
|
||||
|
||||
int spi_slave_receive(spi_t *obj) {
|
||||
return (ssp_readable(obj) && !ssp_busy(obj)) ? (1) : (0);
|
||||
return ssp_readable(obj);
|
||||
}
|
||||
|
||||
int spi_slave_read(spi_t *obj) {
|
||||
|
|
Loading…
Reference in New Issue