mirror of https://github.com/ARMmbed/mbed-os.git
SPI: Add explicit pinmap support
parent
ca80cd22f7
commit
beec0f1e84
|
|
@ -131,6 +131,33 @@ public:
|
|||
*/
|
||||
SPI(PinName mosi, PinName miso, PinName sclk, PinName ssel, use_gpio_ssel_t);
|
||||
|
||||
/** Create a SPI master connected to the specified pins.
|
||||
*
|
||||
* @note This constructor passes the SSEL pin selection to the target HAL.
|
||||
* Not all targets support SSEL, so this cannot be relied on in portable code.
|
||||
* Portable code should use the alternative constructor that uses GPIO
|
||||
* for SSEL.
|
||||
*
|
||||
* @note You can specify mosi or miso as NC if not used.
|
||||
*
|
||||
* @param explicit_pinmap reference to strucure which holds static pinmap.
|
||||
*/
|
||||
SPI(const spi_pinmap_t &explicit_pinmap);
|
||||
|
||||
/** Create a SPI master connected to the specified pins.
|
||||
*
|
||||
* @note This constructor manipulates the SSEL pin as a GPIO output
|
||||
* using a DigitalOut object. This should work on any target, and permits
|
||||
* the use of select() and deselect() methods to keep the pin asserted
|
||||
* between transfers.
|
||||
*
|
||||
* @note You can specify mosi or miso as NC if not used.
|
||||
*
|
||||
* @param explicit_pinmap reference to strucure which holds static pinmap.
|
||||
* @param ssel SPI Chip Select pin.
|
||||
*/
|
||||
SPI(const spi_pinmap_t &explicit_pinmap, PinName ssel);
|
||||
|
||||
virtual ~SPI();
|
||||
|
||||
/** Configure the data transmission format.
|
||||
|
|
@ -408,6 +435,12 @@ protected:
|
|||
char _write_fill;
|
||||
/* Select count to handle re-entrant selection */
|
||||
int8_t _select_count;
|
||||
/* Static pinmap data */
|
||||
const spi_pinmap_t *_explicit_pinmap;
|
||||
/* SPI peripheral name */
|
||||
SPIName _peripheral_name;
|
||||
/* Pointer to spi init function */
|
||||
void (*_init_func)(SPI*);
|
||||
|
||||
private:
|
||||
void _do_construct();
|
||||
|
|
@ -425,6 +458,10 @@ private:
|
|||
*/
|
||||
static spi_peripheral_s *_alloc();
|
||||
|
||||
static void _do_init(SPI *obj);
|
||||
static void _do_init_direct(SPI *obj);
|
||||
|
||||
|
||||
#endif //!defined(DOXYGEN_ONLY)
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -36,8 +36,17 @@ SPI::SPI(PinName mosi, PinName miso, PinName sclk, PinName ssel) :
|
|||
_miso(miso),
|
||||
_sclk(sclk),
|
||||
_hw_ssel(ssel),
|
||||
_sw_ssel(NC)
|
||||
_sw_ssel(NC),
|
||||
_explicit_pinmap(NULL),
|
||||
_init_func(_do_init)
|
||||
{
|
||||
// Need backwards compatibility with HALs not providing API
|
||||
#ifdef DEVICE_SPI_COUNT
|
||||
_peripheral_name = spi_get_peripheral_name(_mosi, _miso, _sclk);
|
||||
#else
|
||||
_peripheral_name = GlobalSPI;
|
||||
#endif
|
||||
|
||||
_do_construct();
|
||||
}
|
||||
|
||||
|
|
@ -49,11 +58,62 @@ SPI::SPI(PinName mosi, PinName miso, PinName sclk, PinName ssel, use_gpio_ssel_t
|
|||
_miso(miso),
|
||||
_sclk(sclk),
|
||||
_hw_ssel(NC),
|
||||
_sw_ssel(ssel, 1)
|
||||
_sw_ssel(ssel, 1),
|
||||
_explicit_pinmap(NULL),
|
||||
_init_func(_do_init)
|
||||
{
|
||||
// Need backwards compatibility with HALs not providing API
|
||||
#ifdef DEVICE_SPI_COUNT
|
||||
_peripheral_name = spi_get_peripheral_name(_mosi, _miso, _sclk);
|
||||
#else
|
||||
_peripheral_name = GlobalSPI;
|
||||
#endif
|
||||
_do_construct();
|
||||
}
|
||||
|
||||
SPI::SPI(const spi_pinmap_t &pinmap) :
|
||||
#if DEVICE_SPI_ASYNCH
|
||||
_irq(this),
|
||||
#endif
|
||||
_mosi(pinmap.mosi_pin),
|
||||
_miso(pinmap.miso_pin),
|
||||
_sclk(pinmap.sclk_pin),
|
||||
_hw_ssel(pinmap.ssel_pin),
|
||||
_sw_ssel(NC),
|
||||
_explicit_pinmap(&pinmap),
|
||||
_peripheral_name((SPIName)pinmap.peripheral),
|
||||
_init_func(_do_init_direct)
|
||||
|
||||
{
|
||||
_do_construct();
|
||||
}
|
||||
|
||||
SPI::SPI(const spi_pinmap_t &pinmap, PinName ssel) :
|
||||
#if DEVICE_SPI_ASYNCH
|
||||
_irq(this),
|
||||
#endif
|
||||
_mosi(pinmap.mosi_pin),
|
||||
_miso(pinmap.miso_pin),
|
||||
_sclk(pinmap.sclk_pin),
|
||||
_hw_ssel(NC),
|
||||
_sw_ssel(ssel, 1),
|
||||
_explicit_pinmap(&pinmap),
|
||||
_peripheral_name((SPIName)pinmap.peripheral),
|
||||
_init_func(_do_init_direct)
|
||||
{
|
||||
_do_construct();
|
||||
}
|
||||
|
||||
void SPI::_do_init(SPI *obj)
|
||||
{
|
||||
spi_init(&obj->_peripheral->spi, obj->_mosi, obj->_miso, obj->_sclk, obj->_hw_ssel);
|
||||
}
|
||||
|
||||
void SPI::_do_init_direct(SPI *obj)
|
||||
{
|
||||
spi_init_direct(&obj->_peripheral->spi, obj->_explicit_pinmap);
|
||||
}
|
||||
|
||||
void SPI::_do_construct()
|
||||
{
|
||||
// No lock needed in the constructor
|
||||
|
|
@ -67,20 +127,13 @@ void SPI::_do_construct()
|
|||
_hz = 1000000;
|
||||
_write_fill = SPI_FILL_CHAR;
|
||||
|
||||
// Need backwards compatibility with HALs not providing API
|
||||
#ifdef DEVICE_SPI_COUNT
|
||||
SPIName name = spi_get_peripheral_name(_mosi, _miso, _sclk);
|
||||
#else
|
||||
SPIName name = GlobalSPI;
|
||||
#endif
|
||||
|
||||
core_util_critical_section_enter();
|
||||
// lookup in a critical section if we already have it else initialize it
|
||||
|
||||
_peripheral = SPI::_lookup(name);
|
||||
_peripheral = SPI::_lookup(_peripheral_name);
|
||||
if (!_peripheral) {
|
||||
_peripheral = SPI::_alloc();
|
||||
_peripheral->name = name;
|
||||
_peripheral->name = _peripheral_name;
|
||||
}
|
||||
core_util_critical_section_exit();
|
||||
|
||||
|
|
@ -158,7 +211,7 @@ void SPI::frequency(int hz)
|
|||
void SPI::_acquire()
|
||||
{
|
||||
if (_peripheral->owner != this) {
|
||||
spi_init(&_peripheral->spi, _mosi, _miso, _sclk, _hw_ssel);
|
||||
_init_func(this);
|
||||
spi_format(&_peripheral->spi, _bits, _mode, 0);
|
||||
spi_frequency(&_peripheral->spi, _hz);
|
||||
_peripheral->owner = this;
|
||||
|
|
|
|||
Loading…
Reference in New Issue