Merge branch 'stevstrong-master'
This commit is contained in:
commit
754bc29699
|
@ -68,6 +68,7 @@ void spi_master_enable(spi_dev *dev,
|
|||
spi_reconfigure(dev, baud | flags | SPI_CR1_MSTR | mode);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Configure and enable a SPI device as a bus slave.
|
||||
*
|
||||
|
@ -157,8 +158,9 @@ void spi_rx_dma_disable(spi_dev *dev) {
|
|||
*/
|
||||
|
||||
static void spi_reconfigure(spi_dev *dev, uint32 cr1_config) {
|
||||
#define MASK (SPI_CR1_CRCEN|SPI_CR1_DFF)
|
||||
spi_irq_disable(dev, SPI_INTERRUPTS_ALL);
|
||||
spi_peripheral_disable(dev);
|
||||
if ( (dev->regs->CR1&MASK)!=(cr1_config&MASK) ) spi_peripheral_disable(dev);
|
||||
dev->regs->CR1 = cr1_config;
|
||||
spi_peripheral_enable(dev);
|
||||
}
|
||||
|
|
|
@ -393,15 +393,13 @@ void usb_cdcacm_putc(char ch) {
|
|||
;
|
||||
}
|
||||
|
||||
/* This function is non-blocking.
|
||||
/* This function is blocking.
|
||||
*
|
||||
* It copies data from a usercode buffer into the USB peripheral TX
|
||||
* buffer, and returns the number of bytes copied. */
|
||||
uint32 usb_cdcacm_tx(const uint8* buf, uint32 len) {
|
||||
/* Last transmission hasn't finished, so abort. */
|
||||
if (usb_cdcacm_is_transmitting()) {
|
||||
return 0;
|
||||
}
|
||||
while ( usb_cdcacm_is_transmitting()>0 ) ; // wait for end of transmission
|
||||
|
||||
/* We can only put USB_CDCACM_TX_EPSIZE bytes in the buffer. */
|
||||
if (len > USB_CDCACM_TX_EPSIZE) {
|
||||
|
|
|
@ -142,7 +142,7 @@ SPIClass::SPIClass(uint32 spi_num) {
|
|||
* Set up/tear down
|
||||
*/
|
||||
void SPIClass::updateSettings(void) {
|
||||
uint32 flags = ((_currentSetting->bitOrder == MSBFIRST ? SPI_FRAME_MSB : SPI_FRAME_LSB) | SPI_DFF_8_BIT | SPI_SW_SLAVE | SPI_SOFT_SS);
|
||||
uint32 flags = ((_currentSetting->bitOrder == MSBFIRST ? SPI_FRAME_MSB : SPI_FRAME_LSB) | _currentSetting->dataSize | SPI_SW_SLAVE | SPI_SOFT_SS);
|
||||
#ifdef SPI_DEBUG
|
||||
Serial.print("spi_master_enable("); Serial.print(_currentSetting->clockDivider); Serial.print(","); Serial.print(_currentSetting->dataMode); Serial.print(","); Serial.print(flags); Serial.println(")");
|
||||
#endif
|
||||
|
@ -150,20 +150,15 @@ void SPIClass::updateSettings(void) {
|
|||
}
|
||||
|
||||
void SPIClass::begin(void) {
|
||||
|
||||
spi_init(_currentSetting->spi_d);
|
||||
configure_gpios(_currentSetting->spi_d, 1);
|
||||
updateSettings();
|
||||
}
|
||||
|
||||
void SPIClass::beginSlave(void) {
|
||||
if (_currentSetting->dataMode >= 4) {
|
||||
ASSERT(0);
|
||||
return;
|
||||
}
|
||||
uint32 flags = ((_currentSetting->bitOrder == MSBFIRST ? SPI_FRAME_MSB : SPI_FRAME_LSB) | SPI_DFF_8_BIT | SPI_SW_SLAVE);
|
||||
spi_init(_currentSetting->spi_d);
|
||||
configure_gpios(_currentSetting->spi_d, 0);
|
||||
uint32 flags = ((_currentSetting->bitOrder == MSBFIRST ? SPI_FRAME_MSB : SPI_FRAME_LSB) | _currentSetting->dataSize | SPI_SW_SLAVE);
|
||||
#ifdef SPI_DEBUG
|
||||
Serial.print("spi_slave_enable("); Serial.print(_currentSetting->dataMode); Serial.print(","); Serial.print(flags); Serial.println(")");
|
||||
#endif
|
||||
|
@ -195,7 +190,8 @@ void SPIClass::setClockDivider(uint32_t clockDivider)
|
|||
Serial.print("Clock divider set to "); Serial.println(clockDivider);
|
||||
#endif
|
||||
_currentSetting->clockDivider = clockDivider;
|
||||
updateSettings();
|
||||
uint32 cr1 = _currentSetting->spi_d->regs->CR1 & ~(SPI_CR1_BR);
|
||||
_currentSetting->spi_d->regs->CR1 = cr1 | (clockDivider & SPI_CR1_BR);
|
||||
}
|
||||
|
||||
void SPIClass::setBitOrder(BitOrder bitOrder)
|
||||
|
@ -204,7 +200,9 @@ void SPIClass::setBitOrder(BitOrder bitOrder)
|
|||
Serial.print("Bit order set to "); Serial.println(bitOrder);
|
||||
#endif
|
||||
_currentSetting->bitOrder = bitOrder;
|
||||
updateSettings();
|
||||
uint32 cr1 = _currentSetting->spi_d->regs->CR1 & ~(SPI_CR1_LSBFIRST);
|
||||
if ( bitOrder==LSBFIRST ) cr1 |= SPI_CR1_LSBFIRST;
|
||||
_currentSetting->spi_d->regs->CR1 = cr1;
|
||||
}
|
||||
|
||||
/* Victor Perez. Added to test changing datasize from 8 to 16 bit modes on the fly.
|
||||
|
@ -213,11 +211,9 @@ void SPIClass::setBitOrder(BitOrder bitOrder)
|
|||
*/
|
||||
void SPIClass::setDataSize(uint32 datasize)
|
||||
{
|
||||
uint32 cr1 = _currentSetting->spi_d->regs->CR1;
|
||||
datasize &= SPI_CR1_DFF;
|
||||
cr1 &= ~(SPI_CR1_DFF);
|
||||
cr1 |= datasize;
|
||||
_currentSetting->spi_d->regs->CR1 = cr1;
|
||||
_currentSetting->dataSize = datasize;
|
||||
uint32 cr1 = _currentSetting->spi_d->regs->CR1 & ~(SPI_CR1_DFF);
|
||||
_currentSetting->spi_d->regs->CR1 = cr1 | (datasize & SPI_CR1_DFF);
|
||||
}
|
||||
|
||||
void SPIClass::setDataMode(uint8_t dataMode)
|
||||
|
@ -236,13 +232,11 @@ SPI Mode CPOL CPHA Shift SCK-edge Capture SCK-edge
|
|||
On the STM32 it appears to be
|
||||
|
||||
bit 1 - CPOL : Clock polarity
|
||||
|
||||
(This bit should not be changed when communication is ongoing)
|
||||
0 : CLK to 0 when idle
|
||||
1 : CLK to 1 when idle
|
||||
|
||||
bit 0 - CPHA : Clock phase
|
||||
|
||||
(This bit should not be changed when communication is ongoing)
|
||||
0 : The first clock transition is the first data capture edge
|
||||
1 : The second clock transition is the first data capture edge
|
||||
|
@ -253,10 +247,10 @@ If someone finds this is not the case or sees a logic error with this let me kno
|
|||
Serial.print("Data mode set to "); Serial.println(dataMode);
|
||||
#endif
|
||||
_currentSetting->dataMode = dataMode;
|
||||
updateSettings();
|
||||
uint32 cr1 = _currentSetting->spi_d->regs->CR1 & ~(SPI_CR1_CPOL|SPI_CR1_CPHA);
|
||||
_currentSetting->spi_d->regs->CR1 = cr1 | (dataMode & (SPI_CR1_CPOL|SPI_CR1_CPHA));
|
||||
}
|
||||
|
||||
|
||||
void SPIClass::beginTransaction(uint8_t pin, SPISettings settings)
|
||||
{
|
||||
#ifdef SPI_DEBUG
|
||||
|
@ -267,10 +261,22 @@ void SPIClass::beginTransaction(uint8_t pin, SPISettings settings)
|
|||
//digitalWrite(_SSPin,LOW);
|
||||
setBitOrder(settings.bitOrder);
|
||||
setDataMode(settings.dataMode);
|
||||
setDataSize(settings.dataSize);
|
||||
setClockDivider(determine_baud_rate(_currentSetting->spi_d, settings.clock));
|
||||
begin();
|
||||
}
|
||||
|
||||
void SPIClass::beginTransactionSlave(SPISettings settings)
|
||||
{
|
||||
#ifdef SPI_DEBUG
|
||||
Serial.println(F("SPIClass::beginTransactionSlave"));
|
||||
#endif
|
||||
setBitOrder(settings.bitOrder);
|
||||
setDataMode(settings.dataMode);
|
||||
setDataSize(settings.dataSize);
|
||||
beginSlave();
|
||||
}
|
||||
|
||||
void SPIClass::endTransaction(void)
|
||||
{
|
||||
#ifdef SPI_DEBUG
|
||||
|
@ -354,6 +360,15 @@ void SPIClass::write(const uint8 *data, uint32 length) {
|
|||
}
|
||||
}
|
||||
|
||||
uint16_t SPIClass::transfer16(uint16_t wr_data) const {
|
||||
spi_tx_reg(_currentSetting->spi_d, wr_data); // "2. Write the first data item to be transmitted into the SPI_DR register (this clears the TXE flag)."
|
||||
while (spi_is_rx_nonempty(_currentSetting->spi_d) == 0); // "4. Wait until RXNE=1 ..."
|
||||
uint16_t rd_data = spi_rx_reg(_currentSetting->spi_d); // "... and read the last received data."
|
||||
// while (spi_is_tx_empty(_currentSetting->spi_d) == 0); // "5. Wait until TXE=1 ..."
|
||||
// while (spi_is_busy(_currentSetting->spi_d) != 0); // "... and then wait until BSY=0 before disabling the SPI."
|
||||
return rd_data;
|
||||
}
|
||||
|
||||
uint8 SPIClass::transfer(uint8 byte) const {
|
||||
spi_tx_reg(_currentSetting->spi_d, byte); // "2. Write the first data item to be transmitted into the SPI_DR register (this clears the TXE flag)."
|
||||
while (spi_is_rx_nonempty(_currentSetting->spi_d) == 0); // "4. Wait until RXNE=1 ..."
|
||||
|
|
|
@ -96,28 +96,40 @@
|
|||
#define SPI_MODE2 SPI_MODE_2
|
||||
#define SPI_MODE3 SPI_MODE_3
|
||||
|
||||
#define DATA_SIZE_8BIT SPI_CR1_DFF_8_BIT
|
||||
#define DATA_SIZE_16BIT SPI_CR1_DFF_16_BIT
|
||||
|
||||
class SPISettings {
|
||||
public:
|
||||
SPISettings(uint32_t clock, BitOrder bitOrder, uint8_t dataMode) {
|
||||
if (__builtin_constant_p(clock)) {
|
||||
init_AlwaysInline(clock, bitOrder, dataMode);
|
||||
init_AlwaysInline(clock, bitOrder, dataMode, DATA_SIZE_8BIT);
|
||||
} else {
|
||||
init_MightInline(clock, bitOrder, dataMode);
|
||||
init_MightInline(clock, bitOrder, dataMode, DATA_SIZE_8BIT);
|
||||
}
|
||||
}
|
||||
SPISettings() { init_AlwaysInline(4000000, MSBFIRST, SPI_MODE0); }
|
||||
SPISettings(uint32_t clock, BitOrder bitOrder, uint8_t dataMode, uint32_t dataSize) {
|
||||
if (__builtin_constant_p(clock)) {
|
||||
init_AlwaysInline(clock, bitOrder, dataMode, dataSize);
|
||||
} else {
|
||||
init_MightInline(clock, bitOrder, dataMode, dataSize);
|
||||
}
|
||||
}
|
||||
SPISettings() { init_AlwaysInline(4000000, MSBFIRST, SPI_MODE0, DATA_SIZE_8BIT); }
|
||||
private:
|
||||
void init_MightInline(uint32_t clock, BitOrder bitOrder, uint8_t dataMode) {
|
||||
init_AlwaysInline(clock, bitOrder, dataMode);
|
||||
void init_MightInline(uint32_t clock, BitOrder bitOrder, uint8_t dataMode, uint32_t dataSize) {
|
||||
init_AlwaysInline(clock, bitOrder, dataMode, dataSize);
|
||||
}
|
||||
void init_AlwaysInline(uint32_t clock, BitOrder bitOrder, uint8_t dataMode) __attribute__((__always_inline__)) {
|
||||
void init_AlwaysInline(uint32_t clock, BitOrder bitOrder, uint8_t dataMode, uint32_t dataSize) __attribute__((__always_inline__)) {
|
||||
this->clock = clock;
|
||||
this->bitOrder = bitOrder;
|
||||
this->dataMode = dataMode;
|
||||
this->dataSize = dataSize;
|
||||
}
|
||||
uint32_t clock;
|
||||
BitOrder bitOrder;
|
||||
uint8_t dataMode;
|
||||
uint32_t dataSize;
|
||||
|
||||
spi_dev *spi_d;
|
||||
uint8_t _SSPin;
|
||||
|
@ -182,6 +194,8 @@ public:
|
|||
void beginTransaction(uint8_t pin, SPISettings settings);
|
||||
void endTransaction(void);
|
||||
|
||||
void beginTransactionSlave(SPISettings settings);
|
||||
|
||||
void setClockDivider(uint32_t clockDivider);
|
||||
void setBitOrder(BitOrder bitOrder);
|
||||
void setDataMode(uint8_t dataMode);
|
||||
|
@ -246,6 +260,7 @@ public:
|
|||
* @return Next unread byte.
|
||||
*/
|
||||
uint8 transfer(uint8 data) const;
|
||||
uint16_t transfer16(uint16_t data) const;
|
||||
|
||||
/**
|
||||
* @brief Sets up a DMA Transfer for "length" bytes.
|
||||
|
|
|
@ -78,7 +78,7 @@ extern struct adc_dev *ADC3;
|
|||
#define ADC_CR2_EXTTRIG_BIT 20
|
||||
#define ADC_CR2_JSWSTART_BIT 21
|
||||
#define ADC_CR2_SWSTART_BIT 22
|
||||
#define ADC_CR2_TSEREFE_BIT 23
|
||||
#define ADC_CR2_TSVREFE_BIT 23
|
||||
|
||||
#define ADC_CR2_ADON (1U << ADC_CR2_ADON_BIT)
|
||||
#define ADC_CR2_CONT (1U << ADC_CR2_CONT_BIT)
|
||||
|
@ -108,7 +108,7 @@ extern struct adc_dev *ADC3;
|
|||
#define ADC_CR2_EXTTRIG (1U << ADC_CR2_EXTTRIG_BIT)
|
||||
#define ADC_CR2_JSWSTART (1U << ADC_CR2_JSWSTART_BIT)
|
||||
#define ADC_CR2_SWSTART (1U << ADC_CR2_SWSTART_BIT)
|
||||
#define ADC_CR2_TSEREFE (1U << ADC_CR2_TSEREFE_BIT)
|
||||
#define ADC_CR2_TSVREFE (1U << ADC_CR2_TSVREFE_BIT)
|
||||
|
||||
/*
|
||||
* Other types
|
||||
|
|
Loading…
Reference in New Issue