Merge branch 'master' into patch-4

This commit is contained in:
Testato 2017-07-16 09:16:02 +03:00 committed by GitHub
commit e518b74fb0
62 changed files with 768 additions and 407 deletions

1
.gitignore vendored
View File

@ -6,6 +6,5 @@ other/maple-bootloader/cscope.out
other/maple-bootloader/build
other/maple-bootloader/*~
*.o
tools/src/stm32flash_serial/src/parsers/parsers.a
*.bak
*.1

View File

@ -142,6 +142,11 @@ void HardwareTimer::refresh(void) {
timer_generate_update(this->dev);
}
void HardwareTimer::setMasterModeTrGo(uint32_t mode) {
this->dev->regs.bas->CR2 &= ~TIMER_CR2_MMS;
this->dev->regs.bas->CR2 |= mode;
}
/* CARLOS Changes to add encoder mode.*/
//direction of movement. (to be better described).

View File

@ -209,6 +209,23 @@ public:
*/
void refresh(void);
// SYFRE
/**
* @brief Set the Master mode TRGO signal
* These bits allow to select the information to be sent in master mode to slave timers for
* synchronization (TRGO).
* mode:
* TIMER_CR2_MMS_RESET
* TIMER_CR2_MMS_ENABLE
* TIMER_CR2_MMS_UPDATE
* TIMER_CR2_MMS_COMPARE_PULSE
* TIMER_CR2_MMS_COMPARE_OC1REF
* TIMER_CR2_MMS_COMPARE_OC2REF
* TIMER_CR2_MMS_COMPARE_OC3REF
* TIMER_CR2_MMS_COMPARE_OC4REF
*/
void setMasterModeTrGo(uint32_t mode);
//CARLOS.
/*
added these functions to make sense for the encoder mode.

View File

@ -59,6 +59,7 @@ void adc_set_extsel(adc_dev *dev, adc_extsel_event event) {
uint32 cr2 = dev->regs->CR2;
cr2 &= ~ADC_CR2_EXTSEL;
cr2 |= event;
cr2 |= ADC_CR2_EXTTRIG;
dev->regs->CR2 = cr2;
}

View File

@ -62,8 +62,8 @@
#if !(defined(BOARD_maple) || defined(BOARD_maple_RET6) || \
defined(BOARD_maple_mini) || defined(BOARD_maple_native))
#warning USB CDC ACM relies on LeafLabs board-specific configuration.\
You may have problems on non-LeafLabs boards.
//#warning USB CDC ACM relies on LeafLabs board-specific configuration.\
// You may have problems on non-LeafLabs boards.
#endif
static void vcomDataTxCb(void);

View File

@ -71,7 +71,7 @@ void USBSerial::begin(void) {
return;
_hasBegun = true;
usb_cdcacm_enable(BOARD_USB_DISC_DEV, BOARD_USB_DISC_BIT);
usb_cdcacm_enable(BOARD_USB_DISC_DEV, (uint8_t)BOARD_USB_DISC_BIT);
usb_cdcacm_set_hooks(USB_CDCACM_HOOK_RX, rxHook);
usb_cdcacm_set_hooks(USB_CDCACM_HOOK_IFACE_SETUP, ifaceSetupHook);
#endif
@ -97,7 +97,7 @@ volatile uint8_t removeCompilerWarningsIgnore=ignore;
void USBSerial::end(void) {
#if BOARD_HAVE_SERIALUSB
usb_cdcacm_disable(BOARD_USB_DISC_DEV, BOARD_USB_DISC_BIT);
usb_cdcacm_disable(BOARD_USB_DISC_DEV, (uint8_t)BOARD_USB_DISC_BIT);
usb_cdcacm_remove_hooks(USB_CDCACM_HOOK_RX | USB_CDCACM_HOOK_IFACE_SETUP);
_hasBegun = false;
#endif
@ -119,7 +119,7 @@ size_t n = 0;
size_t USBSerial::write(const uint8 *buf, uint32 len)
{
size_t n = 0;
if (!this->isConnected() || !buf) {
if (!(bool) *this || !buf) {
return 0;
}
@ -168,6 +168,19 @@ uint32 USBSerial::read(uint8 * buf, uint32 len) {
return rxed;
}
size_t USBSerial::readBytes(char *buf, const size_t& len)
{
size_t rxed=0;
unsigned long startMillis;
startMillis = millis();
if (len <= 0) return 0;
do {
rxed += usb_cdcacm_rx((uint8 *)buf + rxed, len - rxed);
if (rxed == len) return rxed;
} while(millis() - startMillis < _timeout);
return rxed;
}
/* Blocks forever until 1 byte is received */
int USBSerial::read(void) {
uint8 b;
@ -190,10 +203,6 @@ uint8 USBSerial::pending(void) {
return usb_cdcacm_get_pending();
}
uint8 USBSerial::isConnected(void) {
return usb_is_connected(USBLIB) && usb_is_configured(USBLIB) && usb_cdcacm_get_dtr();
}
uint8 USBSerial::getDTR(void) {
return usb_cdcacm_get_dtr();
}
@ -202,6 +211,10 @@ uint8 USBSerial::getRTS(void) {
return usb_cdcacm_get_rts();
}
USBSerial::operator bool() {
return usb_is_connected(USBLIB) && usb_is_configured(USBLIB) && usb_cdcacm_get_dtr();
}
#if BOARD_HAVE_SERIALUSB
#ifdef SERIAL_USB
USBSerial Serial;

View File

@ -44,41 +44,51 @@ public:
void begin(void);
// Roger Clark. Added dummy function so that existing Arduino sketches which specify baud rate will compile.
void begin(unsigned long);
void begin(unsigned long, uint8_t);
// Roger Clark. Added dummy function so that existing Arduino sketches which specify baud rate will compile.
void begin(unsigned long);
void begin(unsigned long, uint8_t);
void end(void);
operator bool() { return true; } // Roger Clark. This is needed because in cardinfo.ino it does if (!Serial) . It seems to be a work around for the Leonardo that we needed to implement just to be compliant with the API
virtual int available(void);// Changed to virtual
size_t readBytes(char *buf, const size_t& len);
uint32 read(uint8 * buf, uint32 len);
// uint8 read(void);
// uint8 read(void);
// Roger Clark. added functions to support Arduino 1.0 API
// Roger Clark. added functions to support Arduino 1.0 API
virtual int peek(void);
virtual int read(void);
int availableForWrite(void);
virtual void flush(void);
size_t write(uint8);
size_t write(const char *str);
size_t write(const uint8*, uint32);
uint8 getRTS();
uint8 getDTR();
uint8 isConnected();
uint8 pending();
/* SukkoPera: This is the Arduino way to check if an USB CDC serial
* connection is open.
* Used for instance in cardinfo.ino.
*/
operator bool();
/* Old libmaple way to check for serial connection.
*
* Deprecated, use the above.
*/
uint8 isConnected() __attribute__((deprecated("Use !Serial instead"))) { return (bool) *this; }
protected:
static bool _hasBegun;
};
#ifdef SERIAL_USB
extern USBSerial Serial;
#ifdef SERIAL_USB
extern USBSerial Serial;
#endif
#endif

View File

@ -15,7 +15,7 @@ void setup() {
// Initialize virtual COM over USB on Maple Mini
Serial.begin(9600); // BAUD has no effect on USB serial: placeholder for physical UART
// wait for serial monitor to be connected.
while (!(Serial.isConnected() && (Serial.getDTR() || Serial.getRTS())))
while (!Serial)
{
digitalWrite(33,!digitalRead(33));// Turn the LED from off to on, or on to off
delay(100); // fast blink

View File

@ -18,7 +18,7 @@ void setup()
Serial.begin(BAUD); // BAUD has no effect on USB serial: placeholder for physical UART
Serial.setTimeout(timeoutPeriod); // default is 1 second
// wait for serial monitor to be connected.
while (!(Serial.isConnected() && (Serial.getDTR() || Serial.getRTS())))
while (!Serial)
{
digitalWrite(33,!digitalRead(33));// Turn the LED from off to on, or on to off
delay(100); // fast blink

View File

@ -19,7 +19,7 @@ void setup()
Serial.begin(BAUD); // BAUD has no effect on USB serial: placeholder for physical UART
Serial.setTimeout(timeoutPeriod); // default is 1 second
// wait for serial monitor to be connected.
while (!(Serial.isConnected() && (Serial.getDTR() || Serial.getRTS())))
while (!Serial)
{
digitalWrite(33,!digitalRead(33));// Turn the LED from off to on, or on to off
delay(100); // fast blink

View File

@ -38,7 +38,7 @@ void setup(void)
pinMode(A_RANDOM_ANALOG_PIN, INPUT_ANALOG);
// wait for serial monitor to be connected.
while (!(Serial.isConnected() && (Serial.getDTR() || Serial.getRTS())))
while (!Serial)
{
digitalWrite(33,!digitalRead(33));// Turn the LED from off to on, or on to off
delay(100); // fast blink
@ -48,7 +48,7 @@ void setup(void)
setup_temperature_sensor();
// announce start up
if(Serial.isConnected() && (Serial.getDTR() || Serial.getRTS()))
if(Serial)
Serial.println("Temp mon startup");
}
@ -69,7 +69,7 @@ void loop(void)
t2 = micros();
vsense = adc_read(ADC1, 16);
t3 = micros();
if(Serial.isConnected() && (Serial.getDTR() || Serial.getRTS())) {
if(Serial) {
sprintf(buf,"%04x %08x %04x %08x" , vsense, t3-t2, alogpin, t2-t1);
Serial.println(buf);
}

View File

@ -29,7 +29,7 @@ void setup()
pinMode(33, OUTPUT);
Serial.begin(BAUD); // BAUD has no effect on USB serial: placeholder for physical UART
// wait for serial monitor to be connected.
while (!(Serial.isConnected() && (Serial.getDTR() || Serial.getRTS())))
while (!Serial)
{
digitalWrite(33,!digitalRead(33));// Turn the LED from off to on, or on to off
delay(100); // fast blink

View File

@ -18,7 +18,7 @@ void setup() {
pinMode(33, OUTPUT);
Serial.begin(BAUD); // BAUD has no effect on USB serial: placeholder for physical UART
// wait for serial monitor to be connected.
while (!(Serial.isConnected() && (Serial.getDTR() || Serial.getRTS())))
while (!Serial)
{
digitalWrite(33,!digitalRead(33));// Turn the LED from off to on, or on to off
delay(100); // fast blink

View File

@ -18,7 +18,7 @@ void setup() {
pinMode(33, OUTPUT);
Serial.begin(BAUD); // BAUD has no effect on USB serial: placeholder for physical UART
// wait for serial monitor to be connected.
while (!(Serial.isConnected() && (Serial.getDTR() || Serial.getRTS())))
while (!Serial)
{
digitalWrite(33,!digitalRead(33));// Turn the LED from off to on, or on to off
delay(100); // fast blink

View File

@ -15,7 +15,7 @@ void setup()
pinMode(33, OUTPUT);
Serial.begin(BAUD); // BAUD has no effect on USB serial: placeholder for physical UART
// wait for serial monitor to be connected.
while (!(Serial.isConnected() && (Serial.getDTR() || Serial.getRTS())))
while (!Serial)
{
digitalWrite(33,!digitalRead(33));// Turn the LED from off to on, or on to off
delay(100); // fast blink

View File

@ -17,7 +17,7 @@ void setup() // run once, when the sketch starts
pinMode(33, OUTPUT);
Serial.begin(BAUD); // BAUD has no effect on USB serial: placeholder for physical UART
// wait for serial monitor to be connected.
while (!(Serial.isConnected() && (Serial.getDTR() || Serial.getRTS())))
while (!Serial)
{
digitalWrite(33,!digitalRead(33));// Turn the LED from off to on, or on to off
delay(100); // fast blink

View File

@ -16,7 +16,7 @@ void setup() // run once, when the sketch starts
pinMode(33, OUTPUT);
Serial.begin(BAUD); // BAUD has no effect on USB serial: placeholder for physical UART
// wait for serial monitor to be connected.
while (!(Serial.isConnected() && (Serial.getDTR() || Serial.getRTS())))
while (!Serial)
{
digitalWrite(33,!digitalRead(33));// Turn the LED from off to on, or on to off
delay(100); // fast blink

View File

@ -13,7 +13,7 @@ void setup() {
pinMode(33, OUTPUT);
Serial.begin(BAUD); // BAUD has no effect on USB serial: placeholder for physical UAR
// wait for serial monitor to be connected.
while (!(Serial.isConnected() && (Serial.getDTR() || Serial.getRTS())))
while (!Serial)
{
digitalWrite(33,!digitalRead(33));// Turn the LED from off to on, or on to off
delay(100); // fast blink

View File

@ -34,7 +34,7 @@ void setup() {
pinMode(33, OUTPUT);
Serial.begin(); // USB does not require BAUD
// wait for serial monitor to be connected.
while (!(Serial.isConnected() && (Serial.getDTR() || Serial.getRTS())))
while (!Serial)
{
digitalWrite(33,!digitalRead(33));// Turn the LED from off to on, or on to off
delay(100); // fast blink

View File

@ -19,7 +19,7 @@ void setup() {
pinMode(33, OUTPUT);
Serial.begin(9600);
// wait for serial monitor to be connected.
while (!(Serial.isConnected() && (Serial.getDTR() || Serial.getRTS())))
while (!Serial)
{
digitalWrite(33,!digitalRead(33));// Turn the LED from off to on, or on to off
delay(100); // fast blink

View File

@ -94,76 +94,85 @@ static const spi_pins board_spi_pins[] __FLASH__ = {
SPIClass::SPIClass(uint32 spi_num) {
_currentSetting=&_settings[spi_num-1];// SPI channels are called 1 2 and 3 but the array is zero indexed
_currentSetting=&_settings[spi_num-1];// SPI channels are called 1 2 and 3 but the array is zero indexed
switch (spi_num) {
#if BOARD_NR_SPI >= 1
case 1:
_currentSetting->spi_d = SPI1;
_spi1_this = (void*) this;
break;
#endif
#if BOARD_NR_SPI >= 2
case 2:
_currentSetting->spi_d = SPI2;
_spi2_this = (void*) this;
break;
#endif
#if BOARD_NR_SPI >= 3
case 3:
_currentSetting->spi_d = SPI3;
_spi3_this = (void*) this;
break;
#endif
default:
ASSERT(0);
}
// Init things specific to each SPI device
// clock divider setup is a bit of hack, and needs to be improved at a later date.
_settings[0].spi_d = SPI1;
_settings[0].clockDivider = determine_baud_rate(_settings[0].spi_d, _settings[0].clock);
_settings[0].spiDmaDev = DMA1;
_settings[0].spiTxDmaChannel = DMA_CH3;
_settings[0].spiRxDmaChannel = DMA_CH2;
_settings[1].spi_d = SPI2;
_settings[1].clockDivider = determine_baud_rate(_settings[1].spi_d, _settings[1].clock);
_settings[1].spiDmaDev = DMA1;
_settings[1].spiTxDmaChannel = DMA_CH5;
_settings[1].spiRxDmaChannel = DMA_CH4;
// Init things specific to each SPI device
// clock divider setup is a bit of hack, and needs to be improved at a later date.
_settings[0].spi_d = SPI1;
_settings[0].clockDivider = determine_baud_rate(_settings[0].spi_d, _settings[0].clock);
_settings[0].spiDmaDev = DMA1;
_settings[0].spiTxDmaChannel = DMA_CH3;
_settings[0].spiRxDmaChannel = DMA_CH2;
_settings[1].spi_d = SPI2;
_settings[1].clockDivider = determine_baud_rate(_settings[1].spi_d, _settings[1].clock);
_settings[1].spiDmaDev = DMA1;
_settings[1].spiTxDmaChannel = DMA_CH5;
_settings[1].spiRxDmaChannel = DMA_CH4;
#if BOARD_NR_SPI >= 3
_settings[2].spi_d = SPI3;
_settings[2].clockDivider = determine_baud_rate(_settings[2].spi_d, _settings[2].clock);
_settings[2].spiDmaDev = DMA2;
_settings[2].spiTxDmaChannel = DMA_CH2;
_settings[2].spiRxDmaChannel = DMA_CH1;
_settings[2].spi_d = SPI3;
_settings[2].clockDivider = determine_baud_rate(_settings[2].spi_d, _settings[2].clock);
_settings[2].spiDmaDev = DMA2;
_settings[2].spiTxDmaChannel = DMA_CH2;
_settings[2].spiRxDmaChannel = DMA_CH1;
#endif
// added for DMA callbacks.
_currentSetting->state = SPI_STATE_IDLE;
}
/*
* Set up/tear down
*/
void SPIClass::updateSettings(void) {
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
spi_master_enable(_currentSetting->spi_d, (spi_baud_rate)_currentSetting->clockDivider, (spi_mode)_currentSetting->dataMode, flags);
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
spi_master_enable(_currentSetting->spi_d, (spi_baud_rate)_currentSetting->clockDivider, (spi_mode)_currentSetting->dataMode, flags);
}
void SPIClass::begin(void) {
spi_init(_currentSetting->spi_d);
configure_gpios(_currentSetting->spi_d, 1);
updateSettings();
// added for DMA callbacks.
_currentSetting->state = SPI_STATE_READY;
}
void SPIClass::beginSlave(void) {
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_RX_ONLY);
#ifdef SPI_DEBUG
Serial.print("spi_slave_enable("); Serial.print(_currentSetting->dataMode); Serial.print(","); Serial.print(flags); Serial.println(")");
#endif
#ifdef SPI_DEBUG
Serial.print("spi_slave_enable("); Serial.print(_currentSetting->dataMode); Serial.print(","); Serial.print(flags); Serial.println(")");
#endif
spi_slave_enable(_currentSetting->spi_d, (spi_mode)_currentSetting->dataMode, flags);
// added for DMA callbacks.
_currentSetting->state = SPI_STATE_READY;
}
void SPIClass::end(void) {
@ -182,28 +191,31 @@ void SPIClass::end(void) {
while (spi_is_busy(_currentSetting->spi_d))
;
spi_peripheral_disable(_currentSetting->spi_d);
// added for DMA callbacks.
// Need to add unsetting the callbacks for the DMA channels.
_currentSetting->state = SPI_STATE_IDLE;
}
/* Roger Clark added 3 functions */
void SPIClass::setClockDivider(uint32_t clockDivider)
{
#ifdef SPI_DEBUG
Serial.print("Clock divider set to "); Serial.println(clockDivider);
#endif
_currentSetting->clockDivider = clockDivider;
uint32 cr1 = _currentSetting->spi_d->regs->CR1 & ~(SPI_CR1_BR);
_currentSetting->spi_d->regs->CR1 = cr1 | (clockDivider & SPI_CR1_BR);
#ifdef SPI_DEBUG
Serial.print("Clock divider set to "); Serial.println(clockDivider);
#endif
_currentSetting->clockDivider = clockDivider;
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)
{
#ifdef SPI_DEBUG
Serial.print("Bit order set to "); Serial.println(bitOrder);
#endif
_currentSetting->bitOrder = bitOrder;
uint32 cr1 = _currentSetting->spi_d->regs->CR1 & ~(SPI_CR1_LSBFIRST);
if ( bitOrder==LSBFIRST ) cr1 |= SPI_CR1_LSBFIRST;
_currentSetting->spi_d->regs->CR1 = cr1;
#ifdef SPI_DEBUG
Serial.print("Bit order set to "); Serial.println(bitOrder);
#endif
_currentSetting->bitOrder = bitOrder;
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.
@ -212,11 +224,11 @@ void SPIClass::setBitOrder(BitOrder bitOrder)
*/
void SPIClass::setDataSize(uint32 datasize)
{
_currentSetting->dataSize = datasize;
uint32 cr1 = _currentSetting->spi_d->regs->CR1 & ~(SPI_CR1_DFF);
uint8 en = spi_is_enabled(_currentSetting->spi_d);
spi_peripheral_disable(_currentSetting->spi_d);
_currentSetting->spi_d->regs->CR1 = cr1 | (datasize & SPI_CR1_DFF) | en;
_currentSetting->dataSize = datasize;
uint32 cr1 = _currentSetting->spi_d->regs->CR1 & ~(SPI_CR1_DFF);
uint8 en = spi_is_enabled(_currentSetting->spi_d);
spi_peripheral_disable(_currentSetting->spi_d);
_currentSetting->spi_d->regs->CR1 = cr1 | (datasize & SPI_CR1_DFF) | en;
}
void SPIClass::setDataMode(uint8_t dataMode)
@ -246,56 +258,56 @@ bit 0 - CPHA : Clock phase
If someone finds this is not the case or sees a logic error with this let me know ;-)
*/
#ifdef SPI_DEBUG
Serial.print("Data mode set to "); Serial.println(dataMode);
#endif
_currentSetting->dataMode = dataMode;
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));
#ifdef SPI_DEBUG
Serial.print("Data mode set to "); Serial.println(dataMode);
#endif
_currentSetting->dataMode = dataMode;
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
Serial.println("SPIClass::beginTransaction");
#endif
setBitOrder(settings.bitOrder);
setDataMode(settings.dataMode);
setDataSize(settings.dataSize);
setClockDivider(determine_baud_rate(_currentSetting->spi_d, settings.clock));
begin();
#ifdef SPI_DEBUG
Serial.println("SPIClass::beginTransaction");
#endif
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();
#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
Serial.println("SPIClass::endTransaction");
#endif
//digitalWrite(_SSPin,HIGH);
#ifdef SPI_DEBUG
Serial.println("SPIClass::endTransaction");
#endif
//digitalWrite(_SSPin,HIGH);
#if false
// code from SAM core
uint8_t mode = interruptMode;
if (mode > 0) {
if (mode < 16) {
if (mode & 1) PIOA->PIO_IER = interruptMask[0];
if (mode & 2) PIOB->PIO_IER = interruptMask[1];
if (mode & 4) PIOC->PIO_IER = interruptMask[2];
if (mode & 8) PIOD->PIO_IER = interruptMask[3];
} else {
if (interruptSave) interrupts();
}
}
uint8_t mode = interruptMode;
if (mode > 0) {
if (mode < 16) {
if (mode & 1) PIOA->PIO_IER = interruptMask[0];
if (mode & 2) PIOB->PIO_IER = interruptMask[1];
if (mode & 4) PIOC->PIO_IER = interruptMask[2];
if (mode & 8) PIOD->PIO_IER = interruptMask[3];
} else {
if (interruptSave) interrupts();
}
}
#endif
}
@ -306,80 +318,139 @@ void SPIClass::endTransaction(void)
uint16 SPIClass::read(void)
{
while ( spi_is_rx_nonempty(_currentSetting->spi_d)==0 ) ;
return (uint16)spi_rx_reg(_currentSetting->spi_d);
while ( spi_is_rx_nonempty(_currentSetting->spi_d)==0 ) ;
return (uint16)spi_rx_reg(_currentSetting->spi_d);
}
void SPIClass::read(uint8 *buf, uint32 len)
{
if ( len == 0 ) return;
spi_rx_reg(_currentSetting->spi_d); // clear the RX buffer in case a byte is waiting on it.
spi_reg_map * regs = _currentSetting->spi_d->regs;
// start sequence: write byte 0
regs->DR = 0x00FF; // write the first byte
// main loop
while ( (--len) ) {
while( !(regs->SR & SPI_SR_TXE) ); // wait for TXE flag
noInterrupts(); // go atomic level - avoid interrupts to surely get the previously received data
regs->DR = 0x00FF; // write the next data item to be transmitted into the SPI_DR register. This clears the TXE flag.
while ( !(regs->SR & SPI_SR_RXNE) ); // wait till data is available in the DR register
*buf++ = (uint8)(regs->DR); // read and store the received byte. This clears the RXNE flag.
interrupts(); // let systick do its job
}
// read remaining last byte
while ( !(regs->SR & SPI_SR_RXNE) ); // wait till data is available in the Rx register
*buf++ = (uint8)(regs->DR); // read and store the received byte
if ( len == 0 ) return;
spi_rx_reg(_currentSetting->spi_d); // clear the RX buffer in case a byte is waiting on it.
spi_reg_map * regs = _currentSetting->spi_d->regs;
// start sequence: write byte 0
regs->DR = 0x00FF; // write the first byte
// main loop
while ( (--len) ) {
while( !(regs->SR & SPI_SR_TXE) ); // wait for TXE flag
noInterrupts(); // go atomic level - avoid interrupts to surely get the previously received data
regs->DR = 0x00FF; // write the next data item to be transmitted into the SPI_DR register. This clears the TXE flag.
while ( !(regs->SR & SPI_SR_RXNE) ); // wait till data is available in the DR register
*buf++ = (uint8)(regs->DR); // read and store the received byte. This clears the RXNE flag.
interrupts(); // let systick do its job
}
// read remaining last byte
while ( !(regs->SR & SPI_SR_RXNE) ); // wait till data is available in the Rx register
*buf++ = (uint8)(regs->DR); // read and store the received byte
}
void SPIClass::write(uint16 data)
{
/* Added for 16bit data Victor Perez. Roger Clark
* Improved speed by just directly writing the single byte to the SPI data reg and wait for completion,
* by taking the Tx code from transfer(byte)
* This almost doubles the speed of this function.
*/
spi_tx_reg(_currentSetting->spi_d, data); // write the data to be transmitted into the SPI_DR register (this clears the TXE flag)
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."
/* Added for 16bit data Victor Perez. Roger Clark
* Improved speed by just directly writing the single byte to the SPI data reg and wait for completion,
* by taking the Tx code from transfer(byte)
* This almost doubles the speed of this function.
*/
spi_tx_reg(_currentSetting->spi_d, data); // write the data to be transmitted into the SPI_DR register (this clears the TXE flag)
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."
}
void SPIClass::write(uint16 data, uint32 n)
{
// Added by stevstrong: Repeatedly send same data by the specified number of times
spi_reg_map * regs = _currentSetting->spi_d->regs;
while ( (n--)>0 ) {
regs->DR = data; // write the data to be transmitted into the SPI_DR register (this clears the TXE flag)
while ( (regs->SR & SPI_SR_TXE)==0 ) ; // wait till Tx empty
}
while ( (regs->SR & SPI_SR_BSY) != 0); // wait until BSY=0 before returning
// Added by stevstrong: Repeatedly send same data by the specified number of times
spi_reg_map * regs = _currentSetting->spi_d->regs;
while ( (n--)>0 ) {
regs->DR = data; // write the data to be transmitted into the SPI_DR register (this clears the TXE flag)
while ( (regs->SR & SPI_SR_TXE)==0 ) ; // wait till Tx empty
}
while ( (regs->SR & SPI_SR_BSY) != 0); // wait until BSY=0 before returning
}
void SPIClass::write(void *data, uint32 length)
{
spi_dev * spi_d = _currentSetting->spi_d;
spi_tx(spi_d, (void*)data, length); // data can be array of bytes or words
while (spi_is_tx_empty(spi_d) == 0); // "5. Wait until TXE=1 ..."
while (spi_is_busy(spi_d) != 0); // "... and then wait until BSY=0 before disabling the SPI."
spi_dev * spi_d = _currentSetting->spi_d;
spi_tx(spi_d, (void*)data, length); // data can be array of bytes or words
while (spi_is_tx_empty(spi_d) == 0); // "5. Wait until TXE=1 ..."
while (spi_is_busy(spi_d) != 0); // "... and then wait until BSY=0 before disabling the SPI."
}
uint8 SPIClass::transfer(uint8 byte) const
{
spi_dev * spi_d = _currentSetting->spi_d;
spi_rx_reg(spi_d); // read any previous data
spi_tx_reg(spi_d, byte); // Write the data item to be transmitted into the SPI_DR register
while (spi_is_tx_empty(spi_d) == 0); // "5. Wait until TXE=1 ..."
while (spi_is_busy(spi_d) != 0); // "... and then wait until BSY=0 before disabling the SPI."
return (uint8)spi_rx_reg(spi_d); // "... and read the last received data."
spi_dev * spi_d = _currentSetting->spi_d;
spi_rx_reg(spi_d); // read any previous data
spi_tx_reg(spi_d, byte); // Write the data item to be transmitted into the SPI_DR register
while (spi_is_tx_empty(spi_d) == 0); // "5. Wait until TXE=1 ..."
while (spi_is_busy(spi_d) != 0); // "... and then wait until BSY=0 before disabling the SPI."
return (uint8)spi_rx_reg(spi_d); // "... and read the last received data."
}
uint16_t SPIClass::transfer16(uint16_t wr_data) const
{
spi_dev * spi_d = _currentSetting->spi_d;
spi_rx_reg(spi_d); // read any previous data
spi_tx_reg(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_tx_empty(spi_d) == 0); // "5. Wait until TXE=1 ..."
while (spi_is_busy(spi_d) != 0); // "... and then wait until BSY=0 before disabling the SPI."
return (uint16)spi_rx_reg(spi_d); // "... and read the last received data."
spi_dev * spi_d = _currentSetting->spi_d;
spi_rx_reg(spi_d); // read any previous data
spi_tx_reg(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_tx_empty(spi_d) == 0); // "5. Wait until TXE=1 ..."
while (spi_is_busy(spi_d) != 0); // "... and then wait until BSY=0 before disabling the SPI."
return (uint16)spi_rx_reg(spi_d); // "... and read the last received data."
}
/* Roger Clark and Victor Perez, 2015
* Performs a DMA SPI transfer with at least a receive buffer.
* If a TX buffer is not provided, FF is sent over and over for the lenght of the transfer.
* On exit TX buffer is not modified, and RX buffer cotains the received data.
* Still in progress.
*/
void SPIClass::dmaTransferSet(void *transmitBuf, void *receiveBuf) {
dma_init(_currentSetting->spiDmaDev);
//spi_rx_dma_enable(_currentSetting->spi_d);
//spi_tx_dma_enable(_currentSetting->spi_d);
dma_xfer_size dma_bit_size = (_currentSetting->dataSize==DATA_SIZE_16BIT) ? DMA_SIZE_16BITS : DMA_SIZE_8BITS;
dma_setup_transfer(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaChannel, &_currentSetting->spi_d->regs->DR, dma_bit_size,
receiveBuf, dma_bit_size, (DMA_MINC_MODE | DMA_TRNS_CMPLT ));// receive buffer DMA
if (!transmitBuf) {
transmitBuf = &ff;
dma_setup_transfer(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, &_currentSetting->spi_d->regs->DR, dma_bit_size,
transmitBuf, dma_bit_size, (DMA_FROM_MEM));// Transmit FF repeatedly
}
else {
dma_setup_transfer(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, &_currentSetting->spi_d->regs->DR, dma_bit_size,
transmitBuf, dma_bit_size, (DMA_MINC_MODE | DMA_FROM_MEM ));// Transmit buffer DMA
}
dma_set_priority(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, DMA_PRIORITY_LOW);
dma_set_priority(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaChannel, DMA_PRIORITY_VERY_HIGH);
}
uint8 SPIClass::dmaTransferRepeat(uint16 length) {
if (length == 0) return 0;
if (spi_is_rx_nonempty(_currentSetting->spi_d) == 1) spi_rx_reg(_currentSetting->spi_d);
_currentSetting->state = SPI_STATE_TRANSFER;
dma_set_num_transfers(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaChannel, length);
dma_set_num_transfers(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, length);
dma_enable(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaChannel);// enable receive
dma_enable(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel);// enable transmit
spi_rx_dma_enable(_currentSetting->spi_d);
spi_tx_dma_enable(_currentSetting->spi_d);
if (_currentSetting->receiveCallback){
return 0;
}
//uint32_t m = millis();
uint8 b = 0;
uint32_t m = millis();
while ((dma_get_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel) & DMA_ISR_TCIF1)==0) {
//Avoid interrupts and just loop waiting for the flag to be set.
if ((millis() - m) > DMA_TIMEOUT) { b = 2; break; }
}
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."
spi_tx_dma_disable(_currentSetting->spi_d);
spi_rx_dma_disable(_currentSetting->spi_d);
dma_disable(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel);
dma_disable(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaChannel);
dma_clear_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaChannel);
dma_clear_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel);
_currentSetting->state = SPI_STATE_READY;
return b;
}
/* Roger Clark and Victor Perez, 2015
@ -388,51 +459,10 @@ uint16_t SPIClass::transfer16(uint16_t wr_data) const
* On exit TX buffer is not modified, and RX buffer contains the received data.
* Still in progress.
*/
uint8 SPIClass::dmaTransfer(void * transmitBuf, void * receiveBuf, uint16 length)
{
if (length == 0) return 0;
uint8 b = 0;
// dma1_ch3_Active=true;
dma_init(_currentSetting->spiDmaDev);
// dma_attach_interrupt(DMA1, DMA_CH3, &SPIClass::DMA1_CH3_Event);
// RX
dma_xfer_size dma_bit_size = (_currentSetting->dataSize==DATA_SIZE_16BIT) ? DMA_SIZE_16BITS : DMA_SIZE_8BITS;
dma_setup_transfer(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaChannel, &_currentSetting->spi_d->regs->DR, dma_bit_size,
receiveBuf, dma_bit_size, (DMA_MINC_MODE));// receive buffer DMA
dma_set_num_transfers(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaChannel, length);
dma_enable(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaChannel);// enable receive
// TX
uint32 flags = (DMA_MINC_MODE | DMA_FROM_MEM);
if ( transmitBuf==0 ) {
static uint8_t ff = 0XFF;
transmitBuf = &ff;
flags ^= DMA_MINC_MODE; // remove increment mode
}
dma_setup_transfer(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, &_currentSetting->spi_d->regs->DR, dma_bit_size,
transmitBuf, dma_bit_size, flags);// Transmit buffer DMA
dma_set_num_transfers(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, length);
dma_clear_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel);
dma_enable(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel);// enable transmit
spi_rx_reg(_currentSetting->spi_d); //Clear the RX buffer in case a byte is waiting on it.
spi_rx_dma_enable(_currentSetting->spi_d);
spi_tx_dma_enable(_currentSetting->spi_d); // must be the last enable to avoid DMA error flag
uint32_t m = millis();
while ((dma_get_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel) & DMA_ISR_TCIF1)==0) {//Avoid interrupts and just loop waiting for the flag to be set.
//delayMicroseconds(10);
if ((millis() - m) > DMA_TIMEOUT) { b = 2; break; }
}
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."
spi_tx_dma_disable(_currentSetting->spi_d);
spi_rx_dma_disable(_currentSetting->spi_d); // And disable generation of DMA request from the SPI port so other peripherals can use the channels
dma_disable(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel);
dma_disable(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaChannel);
return b;
uint8 SPIClass::dmaTransfer(void *transmitBuf, void *receiveBuf, uint16 length) {
dmaTransferSet(transmitBuf, receiveBuf);
return dmaTransferRepeat(length);
}
/* Roger Clark and Victor Perez, 2015
@ -441,82 +471,184 @@ uint8 SPIClass::dmaTransfer(void * transmitBuf, void * receiveBuf, uint16 length
* Still in progress.
* 2016 - stevstrong - reworked to automatically detect bit size from SPI setting
*/
uint8 SPIClass::dmaSend(void * transmitBuf, uint16 length, bool minc)
{
if (length == 0) return 0;
uint32 flags = ( (DMA_MINC_MODE*minc) | DMA_FROM_MEM | DMA_TRNS_CMPLT);
uint8 b = 0;
dma_init(_currentSetting->spiDmaDev);
// TX
dma_xfer_size dma_bit_size = (_currentSetting->dataSize==DATA_SIZE_16BIT) ? DMA_SIZE_16BITS : DMA_SIZE_8BITS;
dma_setup_transfer(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, &_currentSetting->spi_d->regs->DR, dma_bit_size,
transmitBuf, dma_bit_size, flags);// Transmit buffer DMA
dma_set_num_transfers(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, length);
dma_clear_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel);
dma_enable(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel);// enable transmit
spi_tx_dma_enable(_currentSetting->spi_d);
void SPIClass::dmaSendSet(void * transmitBuf, bool minc) {
uint32 flags = ( (DMA_MINC_MODE*minc) | DMA_FROM_MEM | DMA_TRNS_CMPLT);
dma_init(_currentSetting->spiDmaDev);
dma_xfer_size dma_bit_size = (_currentSetting->dataSize==DATA_SIZE_16BIT) ? DMA_SIZE_16BITS : DMA_SIZE_8BITS;
dma_setup_transfer(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, &_currentSetting->spi_d->regs->DR, dma_bit_size,
transmitBuf, dma_bit_size, flags);// Transmit buffer DMA
dma_set_priority(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, DMA_PRIORITY_LOW);
}
uint8 SPIClass::dmaSendRepeat(uint16 length) {
if (length == 0) return 0;
dma_clear_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel);
dma_set_num_transfers(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, length);
_currentSetting->state = SPI_STATE_TRANSMIT;
dma_enable(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel);// enable transmit
spi_tx_dma_enable(_currentSetting->spi_d);
if (_currentSetting->transmitCallback)
{
return 0;
}
uint32_t m = millis();
while ((dma_get_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel) & DMA_ISR_TCIF1)==0) {//Avoid interrupts and just loop waiting for the flag to be set.
//delayMicroseconds(10);
if ((millis() - m) > DMA_TIMEOUT) { b = 2; break; }
uint8 b = 0;
while ((dma_get_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel) & DMA_ISR_TCIF1)==0) {
//Avoid interrupts and just loop waiting for the flag to be set.
if ((millis() - m) > DMA_TIMEOUT) { b = 2; break; }
}
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."
spi_tx_dma_disable(_currentSetting->spi_d);
dma_disable(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel);
dma_clear_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel);
_currentSetting->state = SPI_STATE_READY;
return b;
}
uint8 SPIClass::dmaSend(void * transmitBuf, uint16 length, bool minc) {
dmaSendSet(transmitBuf, minc);
return dmaSendRepeat(length);
}
uint8 SPIClass::dmaSendAsync(void * transmitBuf, uint16 length, bool minc) {
uint8 b = 0;
if (_currentSetting->state != SPI_STATE_READY)
{
uint32_t m = millis();
while ((dma_get_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel) & DMA_ISR_TCIF1)==0) {//Avoid interrupts and just loop waiting for the flag to be set.
//delayMicroseconds(10);
if ((millis() - m) > DMA_TIMEOUT) { b = 2; break; }
}
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."
spi_tx_dma_disable(_currentSetting->spi_d);
dma_disable(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel);
_currentSetting->state = SPI_STATE_READY;
}
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."
spi_tx_dma_disable(_currentSetting->spi_d);
dma_disable(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel);
return b;
}
uint8 SPIClass::dmaSendAsync(void * transmitBuf, uint16 length, bool minc)
{
static bool isRunning=false;
uint8 b = 0;
if (isRunning)
{
uint32_t m = millis();
while ((dma_get_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel) & DMA_ISR_TCIF1)==0) {//Avoid interrupts and just loop waiting for the flag to be set.
//delayMicroseconds(10);
if ((millis() - m) > DMA_TIMEOUT) { b = 2; break; }
}
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."
spi_tx_dma_disable(_currentSetting->spi_d);
dma_disable(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel);
isRunning=false;
}
if (length == 0) return 0;
uint32 flags = ( (DMA_MINC_MODE*minc) | DMA_FROM_MEM | DMA_TRNS_CMPLT);
if (length == 0) return 0;
uint32 flags = ( (DMA_MINC_MODE*minc) | DMA_FROM_MEM | DMA_TRNS_CMPLT);
dma_init(_currentSetting->spiDmaDev);
// TX
dma_xfer_size dma_bit_size = (_currentSetting->dataSize==DATA_SIZE_16BIT) ? DMA_SIZE_16BITS : DMA_SIZE_8BITS;
// TX
dma_xfer_size dma_bit_size = (_currentSetting->dataSize==DATA_SIZE_16BIT) ? DMA_SIZE_16BITS : DMA_SIZE_8BITS;
dma_setup_transfer(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, &_currentSetting->spi_d->regs->DR, dma_bit_size,
transmitBuf, dma_bit_size, flags);// Transmit buffer DMA
dma_set_num_transfers(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, length);
dma_clear_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel);
dma_enable(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel);// enable transmit
spi_tx_dma_enable(_currentSetting->spi_d);
transmitBuf, dma_bit_size, flags);// Transmit buffer DMA
dma_set_num_transfers(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, length);
dma_clear_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel);
dma_enable(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel);// enable transmit
spi_tx_dma_enable(_currentSetting->spi_d);
isRunning=true;
_currentSetting->state = SPI_STATE_TRANSMIT;
return b;
return b;
}
/*
New functions added to manage callbacks.
Victor Perez 2017
*/
void SPIClass::onReceive(void(*callback)(void)) {
_currentSetting->receiveCallback = callback;
if (callback){
switch (_currentSetting->spi_d->clk_id) {
case RCC_SPI1:
dma_attach_interrupt(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaChannel, &SPIClass::_spi1EventCallback);
break;
case RCC_SPI2:
dma_attach_interrupt(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaChannel, &SPIClass::_spi2EventCallback);
break;
#if BOARD_NR_SPI >= 3
case RCC_SPI3:
dma_attach_interrupt(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaChannel, &SPIClass::_spi3EventCallback);
break;
#endif
default:
ASSERT(0);
}
}
else {
dma_detach_interrupt(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaChannel);
}
}
void SPIClass::onTransmit(void(*callback)(void)) {
_currentSetting->transmitCallback = callback;
if (callback){
switch (_currentSetting->spi_d->clk_id) {
case RCC_SPI1:
dma_attach_interrupt(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, &SPIClass::_spi1EventCallback);
break;
case RCC_SPI2:
dma_attach_interrupt(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, &SPIClass::_spi2EventCallback);
break;
#if BOARD_NR_SPI >= 3
case RCC_SPI3:
dma_attach_interrupt(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, &SPIClass::_spi3EventCallback);
break;
#endif
default:
ASSERT(0);
}
}
else {
dma_detach_interrupt(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel);
}
}
/*
TODO: check if better to first call the customer code, next disable the DMA requests.
Also see if we need to check whether callbacks are set or not, may be better to be checked during the initial setup and only set the callback to EventCallback if they are set.
*/
void SPIClass::EventCallback() {
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"
switch (_currentSetting->state) {
case SPI_STATE_TRANSFER:
while (spi_is_rx_nonempty(_currentSetting->spi_d));
_currentSetting->state = SPI_STATE_READY;
spi_tx_dma_disable(_currentSetting->spi_d);
spi_rx_dma_disable(_currentSetting->spi_d);
//dma_disable(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel);
//dma_disable(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaChannel);
if (_currentSetting->receiveCallback)
{
_currentSetting->receiveCallback();
}
break;
case SPI_STATE_TRANSMIT:
_currentSetting->state = SPI_STATE_READY;
spi_tx_dma_disable(_currentSetting->spi_d);
//dma_disable(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel);
if (_currentSetting->transmitCallback)
{
_currentSetting->transmitCallback();
}
break;
default:
// we shouldn't get here, so better to add an assert and fail.
return;
}
}
void SPIClass::attachInterrupt(void) {
// Should be enableInterrupt()
// Should be enableInterrupt()
}
void SPIClass::detachInterrupt(void) {
// Should be disableInterrupt()
// Should be disableInterrupt()
}
/*
@ -557,10 +689,26 @@ uint8 SPIClass::recv(void) {
return this->read();
}
/*
* Auxiliary functions
*/
DMA call back functions, one per port.
*/
void SPIClass::_spi1EventCallback()
{
reinterpret_cast<class SPIClass*>(_spi1_this)->EventCallback();
}
void SPIClass::_spi2EventCallback() {
reinterpret_cast<class SPIClass*>(_spi2_this)->EventCallback();
}
#if BOARD_NR_SPI >= 3
void SPIClass::_spi3EventCallback() {
reinterpret_cast<class SPIClass*>(_spi3_this)->EventCallback();
}
#endif
/*
* Auxiliary functions
*/
static const spi_pins* dev_to_spi_pins(spi_dev *dev) {
switch (dev->clk_id) {
@ -601,8 +749,8 @@ static void configure_gpios(spi_dev *dev, bool as_master) {
disable_pwm(mosii);
spi_config_gpios(dev, as_master, nssi->gpio_device, nssi->gpio_bit,
scki->gpio_device, scki->gpio_bit, misoi->gpio_bit,
mosii->gpio_bit);
scki->gpio_device, scki->gpio_bit, misoi->gpio_bit,
mosii->gpio_bit);
}
static const spi_baud_rate baud_rates[8] __FLASH__ = {
@ -617,26 +765,26 @@ static const spi_baud_rate baud_rates[8] __FLASH__ = {
};
/*
* Note: This assumes you're on a LeafLabs-style board
* (CYCLES_PER_MICROSECOND == 72, APB2 at 72MHz, APB1 at 36MHz).
*/
* Note: This assumes you're on a LeafLabs-style board
* (CYCLES_PER_MICROSECOND == 72, APB2 at 72MHz, APB1 at 36MHz).
*/
static spi_baud_rate determine_baud_rate(spi_dev *dev, uint32_t freq) {
uint32_t clock = 0, i;
#ifdef SPI_DEBUG
Serial.print("determine_baud_rate("); Serial.print(freq); Serial.println(")");
#endif
uint32_t clock = 0, i;
#ifdef SPI_DEBUG
Serial.print("determine_baud_rate("); Serial.print(freq); Serial.println(")");
#endif
switch (rcc_dev_clk(dev->clk_id))
{
case RCC_APB2: clock = STM32_PCLK2; break; // 72 Mhz
case RCC_APB1: clock = STM32_PCLK1; break; // 36 Mhz
case RCC_APB2: clock = STM32_PCLK2; break; // 72 Mhz
case RCC_APB1: clock = STM32_PCLK1; break; // 36 Mhz
}
clock /= 2;
i = 0;
while (i < 7 && freq < clock) {
clock /= 2;
i++;
clock /= 2;
i++;
}
return baud_rates[i];
return baud_rates[i];
}
SPIClass SPI(1);

View File

@ -99,6 +99,13 @@
#define DATA_SIZE_8BIT SPI_CR1_DFF_8_BIT
#define DATA_SIZE_16BIT SPI_CR1_DFF_16_BIT
typedef enum {
SPI_STATE_IDLE,
SPI_STATE_READY,
SPI_STATE_RECEIVE,
SPI_STATE_TRANSMIT,
SPI_STATE_TRANSFER
} spi_mode_t;
class SPISettings {
public:
SPISettings(uint32_t clock, BitOrder bitOrder, uint8_t dataMode) {
@ -134,21 +141,31 @@ private:
this->dataSize = dataSize;
}
uint32_t clock;
uint32_t dataSize;
uint32_t clockDivider;
BitOrder bitOrder;
uint8_t dataMode;
uint32_t dataSize;
uint8_t _SSPin;
volatile spi_mode_t state;
spi_dev *spi_d;
uint8_t _SSPin;
uint32_t clockDivider;
dma_channel spiRxDmaChannel, spiTxDmaChannel;
dma_dev* spiDmaDev;
void (*receiveCallback)(void) = NULL;
void (*transmitCallback)(void) = NULL;
friend class SPIClass;
};
volatile static bool dma1_ch3_Active;
/*
Should move this to within the class once tested out, just for tidyness
*/
static uint8_t ff = 0XFF;
static void (*_spi1_this);
static void (*_spi2_this);
#if BOARD_NR_SPI >= 3
static void (*_spi3_this);
#endif
/**
* @brief Wirish SPI interface.
@ -217,7 +234,15 @@ public:
*/
void setDataSize(uint32 ds);
/* Victor Perez 2017. Added to set and clear callback functions for callback
* on DMA transfer completion.
* onReceive used to set the callback in case of dmaTransfer (tx/rx), once rx is completed
* onTransmit used to set the callback in case of dmaSend (tx only). That function
* will NOT be called in case of TX/RX
*/
void onReceive(void(*)(void));
void onTransmit(void(*)(void));
/*
* I/O
*/
@ -279,7 +304,9 @@ public:
* @param receiveBuf buffer Bytes to save received data.
* @param length Number of bytes in buffer to transmit.
*/
uint8 dmaTransfer(void * transmitBuf, void * receiveBuf, uint16 length);
uint8 dmaTransfer(void * transmitBuf, void * receiveBuf, uint16 length);
void dmaTransferSet(void *transmitBuf, void *receiveBuf);
uint8 dmaTransferRepeat(uint16 length);
/**
* @brief Sets up a DMA Transmit for SPI 8 or 16 bit transfer mode.
@ -289,9 +316,13 @@ public:
*
* @param data buffer half words to transmit,
* @param length Number of bytes in buffer to transmit.
* @param minc Set to use Memory Increment mode, clear to use Circular mode.
*/
uint8 dmaSend(void * transmitBuf, uint16 length, bool minc = 1);
uint8 dmaSendAsync(void * transmitBuf, uint16 length, bool minc = 1);
uint8 dmaSend(void * transmitBuf, uint16 length, bool minc = 1);
void dmaSendSet(void * transmitBuf, bool minc);
uint8 dmaSendRepeat(uint16 length);
uint8 dmaSendAsync(void * transmitBuf, uint16 length, bool minc = 1);
/*
* Pin accessors
*/
@ -325,7 +356,7 @@ public:
spi_dev* c_dev(void) { return _currentSetting->spi_d; }
spi_dev *dev(){ return _currentSetting->spi_d;}
spi_dev *dev(){ return _currentSetting->spi_d;}
/**
* @brief Sets the number of the SPI peripheral to be used by
@ -335,10 +366,10 @@ public:
* or 1-3 in high density devices.
*/
void setModule(int spi_num)
{
_currentSetting=&_settings[spi_num-1];// SPI channels are called 1 2 and 3 but the array is zero indexed
}
void setModule(int spi_num)
{
_currentSetting=&_settings[spi_num-1];// SPI channels are called 1 2 and 3 but the array is zero indexed
}
/* -- The following methods are deprecated --------------------------- */
@ -374,19 +405,23 @@ public:
uint8 recv(void);
private:
/*
static inline void DMA1_CH3_Event() {
dma1_ch3_Active = 0;
// dma_disable(DMA1, DMA_CH3);
// dma_disable(DMA1, DMA_CH2);
// To Do. Need to wait for
}
*/
SPISettings _settings[BOARD_NR_SPI];
SPISettings *_currentSetting;
void updateSettings(void);
/*
* Functions added for DMA transfers with Callback.
* Experimental.
*/
void EventCallback(void);
static void _spi1EventCallback(void);
static void _spi2EventCallback(void);
#if BOARD_NR_SPI >= 3
static void _spi3EventCallback(void);
#endif
/*
spi_dev *spi_d;
uint8_t _SSPin;

View File

@ -0,0 +1,87 @@
#include <HardwareTimer.h>
#include <STM32ADC.h>
#define pinLED PC13
#define pinOUT PB0
#define _SEND_BY_USB
#ifdef SEND_BY_USB
USBSerial usb;
#endif
// Channels to be acquired.
// A0 (adc1 channel 1)
uint8 pins = 0;
#define maxSamples 2000
uint16_t buffer[maxSamples];
uint16_t *buffers[2];
uint8_t bufr;
uint8_t bufw;
#define sampleFreqKhz 200
#define samplePeriodus 1000 / sampleFreqKhz
#define ticksPerSecond 2 * sampleFreqKhz * 1000 / maxSamples
STM32ADC myADC(ADC1);
long ticks;
void TimerIRQ(void) {
ticks++;
}
void DmaIRQ(void) {
digitalWrite(pinOUT, ! digitalRead(pinOUT));
bufw = (bufw+1)%2;
ticks++;
}
void setup() {
pinMode(pinLED, OUTPUT);
pinMode(pinOUT, OUTPUT);
pinMode(pins, INPUT_ANALOG);
Serial.begin(115200);
Serial.println("START");
#ifdef SEND_BY_USB
usb.begin();
while (!usb.isConnected()) ;
#endif
ticks = 0;
bufr = 0;
bufw = 0;
buffers[0] = &buffer[0];
buffers[1] = &buffer[maxSamples/2];
Timer3.setPeriod(samplePeriodus);
Timer3.setMasterModeTrGo(TIMER_CR2_MMS_UPDATE);
myADC.calibrate();
myADC.setSampleRate(ADC_SMPR_1_5); // ?
myADC.setPins(&pins, 1);
myADC.setDMA(buffer, maxSamples, (DMA_MINC_MODE | DMA_CIRC_MODE | DMA_HALF_TRNS | DMA_TRNS_CMPLT), DmaIRQ);
myADC.setTrigger(ADC_EXT_EV_TIM3_TRGO);
myADC.startConversion();
}
void loop() {
if (bufr!=bufw) {
// process data
#ifdef SEND_BY_USB
if (usb.isConnected()) usb.write((uint8_t *)buffers[bufr],maxSamples); // send it : (maxSamples /2 )*2 (bytes)
#endif
bufr = (bufr+1)%2;
}
if (ticks==ticksPerSecond) {
digitalWrite(pinLED, ! digitalRead(pinLED));
ticks = 0;
}
}

View File

@ -45,7 +45,7 @@ void enable_adc_irq(adc_dev* dev) {//ADC1 for now.
Enable the reading of the internal variables (Temperature and Vref).
*/
void enable_internal_reading(adc_dev *dev) {
dev->regs->CR2 |= ADC_CR2_TSEREFE;
dev->regs->CR2 |= ADC_CR2_TSVREFE;
}
/*

View File

@ -84,3 +84,18 @@ void HardWire::end() {
i2c_disable(sel_hard);
sel_hard = 0;
}
void HardWire::setClock(uint32_t frequencyHz)
{
switch(frequencyHz)
{
case 400000:
dev_flags |= I2C_FAST_MODE;// set FAST_MODE bit
break;
case 100000:
default:
dev_flags &= ~I2C_FAST_MODE;// clear FAST_MODE bit
break;
}
}

View File

@ -66,6 +66,7 @@ public:
*/
void end();
void setClock(uint32_t frequencyHz);
/*
* Disables the I2C device and remove the device address.
*/

View File

@ -56,7 +56,9 @@
void TwoWire::set_scl(bool state) {
I2C_DELAY(this->i2c_delay);
digitalWrite(this->scl_pin,state);
gpio_write_bit(sclDevice,sclBit, state);
// digitalWrite(this->scl_pin,state);
//Allow for clock stretching - dangerous currently
if (state == HIGH) {
while(digitalRead(this->scl_pin) == 0);
@ -65,7 +67,8 @@ void TwoWire::set_scl(bool state) {
void TwoWire::set_sda(bool state) {
I2C_DELAY(this->i2c_delay);
digitalWrite(this->sda_pin, state);
gpio_write_bit(sdaDevice,sdaBit, state);
//digitalWrite(this->sda_pin, state);
}
void TwoWire::i2c_start() {
@ -198,6 +201,11 @@ void TwoWire::begin(uint8 self_addr) {
rx_buf_len = 0;
pinMode(this->scl_pin, OUTPUT_OPEN_DRAIN);
pinMode(this->sda_pin, OUTPUT_OPEN_DRAIN);
sclDevice = PIN_MAP[this->scl_pin].gpio_device;
sclBit = PIN_MAP[this->scl_pin].gpio_bit;
sdaDevice = PIN_MAP[this->sda_pin].gpio_device;
sdaBit = PIN_MAP[this->sda_pin].gpio_bit;
set_scl(HIGH);
set_sda(HIGH);
}
@ -214,6 +222,20 @@ void TwoWire::end()
}
}
void TwoWire::setClock(uint32_t frequencyHz)
{
switch(frequencyHz)
{
case 400000:
i2c_delay = SOFT_FAST;
break;
case 100000:
default:
i2c_delay = SOFT_STANDARD;
break;
}
}
TwoWire::~TwoWire() {
this->scl_pin=0;
this->sda_pin=0;

View File

@ -50,7 +50,7 @@
#define SDA PB7
#define SCL PB6
#define SOFT_STANDARD 27
#define SOFT_STANDARD 19
#define SOFT_FAST 0
@ -126,6 +126,11 @@ class TwoWire : public WireBase {
*/
uint8 process(uint8);
uint8 process();
private:
gpio_dev *sdaDevice;
uint8 sdaBit;
gpio_dev *sclDevice;
uint8 sclBit;
public:
/*
* Accept pin numbers for SCL and SDA lines. Set the delay needed
@ -139,6 +144,8 @@ class TwoWire : public WireBase {
* .begin(uint8) in WireBase
*/
void begin(uint8 = 0x00);
void setClock(uint32_t frequencyHz);
/*
* Sets pins SDA and SCL to INPUT

View File

@ -44,7 +44,7 @@ generic_f407v.upload.protocol=stlink
generic_f407v.upload.file_type=bin
generic_f407v.upload.maximum_size=514288
generic_f407v.upload.ram.maximum_size=131072
generic_f407v.upload.maximum_data_size=131072
#generic_f407v.upload.usbID=0483:3748
#generic_f407v.upload.altID=1

View File

@ -32,11 +32,11 @@
#include "fsmc.h"
#include "gpio.h"
#ifdef STM32_HIGH_DENSITY
#if defined(STM32_HIGH_DENSITY) && defined(BOARD_generic_f407v) // pins not yet defined for disco F407
/**
* Configure FSMC GPIOs for use with LCDs.
*/
*/
void fsmc_init(void) {
rcc_clk_enable(RCC_FSMC);

View File

@ -40,7 +40,7 @@
#ifndef _FSMC_H_
#define _FSMC_H_
#include <libmaple\util.h>
#include <libmaple/util.h>
#include "libmaple_types.h"
#ifdef __cplusplus

View File

@ -54,16 +54,14 @@ spi_dev *SPI3 = &spi3;
* Routines
*/
void spi_config_gpios(spi_dev *ignored,
void spi_config_gpios(spi_dev *dev,
uint8 as_master,
uint8 nss_pin,
uint8 sck_pin,
uint8 miso_pin,
uint8 mosi_pin) {
if (as_master) {
// gpio_set_mode(nss_dev, nss_bit, GPIO_AF_OUTPUT_PP);
gpio_set_mode(sck_pin, GPIO_AF_OUTPUT_PP);
// gpio_set_mode(comm_dev, miso_bit, GPIO_INPUT_FLOATING);
gpio_set_mode(miso_pin, GPIO_AF_INPUT_PD);
gpio_set_mode(mosi_pin, GPIO_AF_OUTPUT_PP);
} else {
@ -72,6 +70,15 @@ void spi_config_gpios(spi_dev *ignored,
gpio_set_mode(miso_pin, GPIO_AF_OUTPUT_PP);
gpio_set_mode(mosi_pin, GPIO_INPUT_FLOATING);
}
uint8_t af_mode = 6;
if(dev->clk_id <= RCC_SPI2) { af_mode = 5; }
if(!as_master) {
gpio_set_af_mode(nss_pin, af_mode);
}
gpio_set_af_mode(sck_pin, af_mode);
gpio_set_af_mode(miso_pin, af_mode);
gpio_set_af_mode(mosi_pin, af_mode);
}
void spi_foreach(void (*fn)(spi_dev*)) {

View File

@ -26,7 +26,7 @@
#include "usbd_ioreq.h"
#include "usbd_req.h"
#include <VCP\usbd_desc.h>
#include <VCP/usbd_desc.h>

View File

@ -24,8 +24,8 @@
#ifndef __USB_CDC_CORE_H_
#define __USB_CDC_CORE_H_
#include <STM32_USB_Device_Library\Core\inc/usbd_ioreq.h>
#include <STM32_USB_OTG_Driver\inc\usb_core.h>
#include <STM32_USB_Device_Library/Core/inc/usbd_ioreq.h>
#include <STM32_USB_OTG_Driver/inc/usb_core.h>
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
* @{

View File

@ -58,10 +58,10 @@
*/
/* Includes ------------------------------------------------------------------*/
#include <VCP\usb_conf.h>
#include <STM32_USB_Device_Library\Class\cdc\inc\usbd_cdc_core.h>
#include <VCP\usbd_desc.h>
#include <STM32_USB_Device_Library\Core\inc\usbd_req.h>
#include <VCP/usb_conf.h>
#include <STM32_USB_Device_Library/Class/cdc/inc/usbd_cdc_core.h>
#include <VCP/usbd_desc.h>
#include <STM32_USB_Device_Library/Core/inc/usbd_req.h>
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY

View File

@ -26,7 +26,7 @@
/* Includes ------------------------------------------------------------------*/
#include <STM32_USB_OTG_Driver/inc/usb_dcd.h>
#include "usbd_def.h"
#include <VCP\usbd_conf.h>
#include <VCP/usbd_conf.h>
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
* @{

View File

@ -24,7 +24,7 @@
#ifndef __USBD_DEF_H
#define __USBD_DEF_H
/* Includes ------------------------------------------------------------------*/
#include <VCP\usbd_conf.h>
#include <VCP/usbd_conf.h>
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
* @{

View File

@ -27,7 +27,7 @@
/* Includes ------------------------------------------------------------------*/
#include "usbd_def.h"
#include "usbd_core.h"
#include <VCP\usbd_conf.h>
#include <VCP/usbd_conf.h>
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY

View File

@ -20,11 +20,11 @@
*/
/* Includes ------------------------------------------------------------------*/
#include <STM32_USB_Device_Library\Core\inc\usbd_core.h>
#include <STM32_USB_Device_Library\Core\inc\usbd_req.h>
#include <STM32_USB_Device_Library\Core\inc\usbd_ioreq.h>
#include <STM32_USB_OTG_Driver\inc\usb_dcd_int.h>
#include <STM32_USB_OTG_Driver\inc\usb_bsp.h>
#include <STM32_USB_Device_Library/Core/inc/usbd_core.h>
#include <STM32_USB_Device_Library/Core/inc/usbd_req.h>
#include <STM32_USB_Device_Library/Core/inc/usbd_ioreq.h>
#include <STM32_USB_OTG_Driver/inc/usb_dcd_int.h>
#include <STM32_USB_OTG_Driver/inc/usb_bsp.h>
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
* @{

View File

@ -20,7 +20,7 @@
*/
/* Includes ------------------------------------------------------------------*/
#include <STM32_USB_Device_Library\Core\inc\usbd_ioreq.h>
#include <STM32_USB_Device_Library/Core/inc/usbd_ioreq.h>
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
* @{
*/

View File

@ -20,9 +20,9 @@
*/
/* Includes ------------------------------------------------------------------*/
#include <STM32_USB_Device_Library\Core\inc\usbd_req.h>
#include <STM32_USB_Device_Library\Core\inc\usbd_ioreq.h>
#include <VCP\usbd_desc.h>
#include <STM32_USB_Device_Library/Core/inc/usbd_req.h>
#include <STM32_USB_Device_Library/Core/inc/usbd_ioreq.h>
#include <VCP/usbd_desc.h>
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY

View File

@ -24,7 +24,7 @@
#define __USB_CORE_H__
/* Includes ------------------------------------------------------------------*/
#include <VCP\usbd_conf.h>
#include <VCP/usbd_conf.h>
#include "usb_regs.h"
#include "usb_defines.h"

View File

@ -24,7 +24,7 @@
#define __USB_DEF_H__
/* Includes ------------------------------------------------------------------*/
#include <VCP\usbd_conf.h>
#include <VCP/usbd_conf.h>
/** @addtogroup USB_OTG_DRIVER
* @{

View File

@ -24,8 +24,8 @@
#define __USB_OTG_REGS_H__
/* Includes ------------------------------------------------------------------*/
#include <VCP\usbd_conf.h>
#include <libmaple\libmaple_types.h>
#include <VCP/usbd_conf.h>
#include <libmaple/libmaple_types.h>
/** @addtogroup USB_OTG_DRIVER
* @{

View File

@ -20,8 +20,8 @@
*/
/* Includes ------------------------------------------------------------------*/
#include <STM32_USB_OTG_Driver\inc\usb_bsp.h>
#include <STM32_USB_OTG_Driver\inc\usb_core.h>
#include <STM32_USB_OTG_Driver/inc/usb_bsp.h>
#include <STM32_USB_OTG_Driver/inc/usb_core.h>
/** @addtogroup USB_OTG_DRIVER

View File

@ -20,8 +20,8 @@
*/
/* Includes ------------------------------------------------------------------*/
#include <STM32_USB_OTG_Driver\inc\usb_dcd.h>
#include <STM32_USB_OTG_Driver\inc\usb_bsp.h>
#include <STM32_USB_OTG_Driver/inc/usb_dcd.h>
#include <STM32_USB_OTG_Driver/inc/usb_bsp.h>
/** @addtogroup USB_OTG_DRIVER

View File

@ -20,12 +20,12 @@
*/
/* Includes ------------------------------------------------------------------*/
#include <STM32_USB_OTG_Driver\inc\usb_dcd_int.h>
#include <STM32_USB_OTG_Driver/inc/usb_dcd_int.h>
typedef int IRQn_Type;
#define __NVIC_PRIO_BITS 4
#define __Vendor_SysTickConfig 1
#include <VCP\core_cm4.h>
#include <VCP/core_cm4.h>
/** @addtogroup USB_OTG_DRIVER

View File

@ -21,7 +21,7 @@
*/
/* Includes ------------------------------------------------------------------*/
#include <STM32_USB_OTG_Driver\inc\usb_bsp.h>
#include <STM32_USB_OTG_Driver/inc/usb_bsp.h>
#include "usbd_conf.h"
#include <libmaple/gpio.h>
typedef enum {DISABLE = 0, ENABLE = !DISABLE} FunctionalState;

View File

@ -26,7 +26,7 @@
/* Includes ------------------------------------------------------------------*/
//#include "stm32f4xx.h"
#include <STM32_USB_Device_Library\Class\cdc\inc\usbd_cdc_core.h>
#include <STM32_USB_Device_Library/Class/cdc/inc/usbd_cdc_core.h>
#include "usbd_conf.h"

View File

@ -20,11 +20,11 @@
*/
/* Includes ------------------------------------------------------------------*/
#include <STM32_USB_Device_Library\Core\inc\usbd_core.h>
#include <STM32_USB_Device_Library/Core/inc/usbd_core.h>
#include "usbd_desc.h"
#include <STM32_USB_Device_Library\Core\inc\usbd_req.h>
#include <STM32_USB_Device_Library/Core/inc/usbd_req.h>
#include "usbd_conf.h"
#include <STM32_USB_OTG_Driver\inc\usb_regs.h>
#include <STM32_USB_OTG_Driver/inc/usb_regs.h>
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
* @{

View File

@ -25,7 +25,7 @@
#define __USB_DESC_H
/* Includes ------------------------------------------------------------------*/
#include <STM32_USB_Device_Library\Core\inc\usbd_def.h>
#include <STM32_USB_Device_Library/Core/inc/usbd_def.h>
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
* @{

View File

@ -20,8 +20,8 @@
*/
/* Includes ------------------------------------------------------------------*/
#include <STM32_USB_Device_Library\Core\inc\usbd_usr.h>
#include <STM32_USB_Device_Library\Core\inc\usbd_ioreq.h>
#include <STM32_USB_Device_Library/Core/inc/usbd_usr.h>
#include <STM32_USB_Device_Library/Core/inc/usbd_ioreq.h>
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY

View File

@ -4,11 +4,11 @@
#include <STM32_USB_Device_Library/Class/cdc/inc/usbd_cdc_core.h>
#include <STM32_USB_Device_Library/Core/inc/usbd_usr.h>
#include <VCP\usbd_desc.h>
#include <VCP/usbd_desc.h>
#include "usb.h"
#include <libmaple/gpio.h>
#include <libmaple/rccF4.h>
#include <VCP\usbd_cdc_vcp.h>
#include <VCP/usbd_cdc_vcp.h>
#include <boards.h>
USB_OTG_CORE_HANDLE USB_OTG_dev;
@ -96,7 +96,7 @@ RESULT usbPowerOff(void) {
void usbDsbISR(void) {};
#include <STM32_USB_OTG_Driver\inc\usb_dcd_int.h>
#include <STM32_USB_OTG_Driver/inc/usb_dcd_int.h>
void __irq_OTG_FS_IRQHandler(void)
{
USBD_OTG_ISR_Handler (&USB_OTG_dev);

View File

@ -5,7 +5,7 @@
extern "C" {
#endif
#include <VCP\usb_conf.h>
#include <VCP/usb_conf.h>
typedef enum _RESULT
{

View File

@ -24,11 +24,12 @@
#include <boards.h>
#define USE_DEBUG_MODE 0
#define USE_YIELD 0
//==============================================================================
//#define SDHC_PROCTL_DTW_4BIT 0x01
#define CMD8_RETRIES 10
#define BUSY_TIMEOUT_MILLIS 500
#define BUSY_TIMEOUT_MILLIS 750
//==============================================================================
#define CMD_RESP_NONE SDIO_CMD_WAIT_NO_RESP
#define CMD_RESP_R1 SDIO_CMD_WAIT_SHORT_RESP // normal response
@ -137,7 +138,8 @@ static void _panic(const char *message, uint32_t code)
delay(250);
}
}
/*===========================================================================
/*===========================================================================*/
#if USE_YIELD
void yield(void)
{
uint32_t val = SDIO->STA;
@ -169,7 +171,8 @@ void yield(void)
_panic(" - DMA: Data Transmission Error ", val);
}
//Serial.write('.');
}*/
}
#endif
//=============================================================================
// Error function and macro.
inline bool setSdErrorCode(uint8_t code, uint32_t line) {
@ -191,11 +194,11 @@ void sdhc_isr() {
//-----------------------------------------------------------------------------
static bool cardCommand(uint16_t xfertyp, uint32_t arg)
{
#if USE_DEBUG_MODE
#if USE_DEBUG_MODE==2
Serial.print("cardCommand: "); Serial.print(xfertyp&SDIO_CMD_CMDINDEX); Serial.print(", arg: "); Serial.print(arg, HEX);
#endif
uint8_t resp = sdio_cmd_send(xfertyp, arg); // returns non-zero if fails, zero if OK
#if USE_DEBUG_MODE
#if USE_DEBUG_MODE==2
Serial.print(", resp: "); Serial.print(resp, HEX);
Serial.print(", SDIO->STA: "); Serial.print(SDIO->STA, HEX); Serial.print(", cmd_resp: "); Serial.print(SDIO->RESP[0], HEX);
if ( (xfertyp&SDIO_CMD_WAIT_LONG_RESP)==SDIO_CMD_WAIT_LONG_RESP ) {
@ -330,6 +333,7 @@ static bool dmaTrxStart(uint8_t* buf, uint32_t n, uint8_t dir)
static bool dmaTrxEnd(bool multi_block)
{
if ( !waitDmaStatus() ) {
DBG_PRINT();
return sdError(SD_CARD_ERROR_DMA);
}
if ( waitTimeout(isBusyTransferComplete) ) {
@ -536,6 +540,9 @@ uint32_t SdioCard::kHzSdClk() {
/*---------------------------------------------------------------------------*/
bool SdioCard::readBlock(uint32_t lba, uint8_t* buf)
{
#if USE_DEBUG_MODE
Serial.print("readBlock: "); Serial.println(lba); //Serial.print(", buf: "); Serial.println((uint32_t)buf, HEX);
#endif
// prepare SDIO and DMA for data read transfer
dmaTrxStart((uint32_t)buf & 3 ? (uint8_t*)aligned : buf, 512, TRX_RD);
// send command to start data transfer
@ -560,6 +567,11 @@ bool SdioCard::readBlock(uint32_t lba, uint8_t* buf)
/*---------------------------------------------------------------------------*/
bool SdioCard::readBlocks(uint32_t lba, uint8_t* buf, size_t n)
{
#if USE_DEBUG_MODE
Serial.print("readBlocks: "); Serial.print(lba);
//Serial.print(", buf: "); Serial.print((uint32_t)buf, HEX);
Serial.print(", "); Serial.println(n);
#endif
if ((uint32_t)buf & 3) {
for (size_t i = 0; i < n; i++, lba++, buf += 512) {
if (!readBlock(lba, buf)) {
@ -672,9 +684,12 @@ uint8_t SdioCard::type() {
/*---------------------------------------------------------------------------*/
bool SdioCard::writeBlock(uint32_t lba, const uint8_t* buf)
{
#if USE_DEBUG_MODE
Serial.print("writeBlock: "); Serial.println(lba); //Serial.print(", buf: "); Serial.println((uint32_t)buf, HEX);
#endif
uint8_t * ptr = (uint8_t *)buf;
if (3 & (uint32_t)ptr) {
//Serial.print("writeBlock: "); Serial.print(lba);
Serial.print("writeBlock: "); Serial.print(lba);
Serial.print(", buf: "); Serial.print((uint32_t)ptr, HEX);
//memcpy(aligned, buf, 512);
register uint8_t * src = (uint8_t *)ptr;
@ -701,6 +716,11 @@ bool SdioCard::writeBlock(uint32_t lba, const uint8_t* buf)
/*---------------------------------------------------------------------------*/
bool SdioCard::writeBlocks(uint32_t lba, const uint8_t* buf, size_t n)
{
#if USE_DEBUG_MODE
Serial.print("writeBlocks: "); Serial.print(lba);
//Serial.print(", buf: "); Serial.print((uint32_t)buf, HEX);
Serial.print(", "); Serial.println(n);
#endif
if (3 & (uint32_t)buf) { // misaligned buffer address, write single blocks
for (size_t i = 0; i < n; i++, lba++, buf += 512) {
if (!writeBlock(lba, buf)) {
@ -709,7 +729,6 @@ bool SdioCard::writeBlocks(uint32_t lba, const uint8_t* buf, size_t n)
}
return true;
}
//Serial.print("writeBlocks: "); Serial.print(lba); Serial.print(", "); Serial.print(n);
if (yieldTimeout(isBusyCMD13)) {
return sdError(SD_CARD_ERROR_CMD13);
}

View File

@ -611,29 +611,6 @@ static void configure_gpios(spi_dev *dev, bool as_master) {
Serial.println(")");
#endif
#ifdef STM32F4
if(dev->clk_id <= RCC_SPI2) {
if(nssi) {
if(!as_master) {
gpio_set_af_mode(pins->nss, 5);
}
}
gpio_set_af_mode(pins->sck, 5);
gpio_set_af_mode(pins->miso, 5);
gpio_set_af_mode(pins->mosi, 5);
} else {
if(nssi) {
if(!as_master) {
gpio_set_af_mode(pins->nss, 6);
}
}
gpio_set_af_mode(pins->sck, 6);
gpio_set_af_mode(pins->miso, 6);
gpio_set_af_mode(pins->mosi, 6);
}
#endif
spi_config_gpios(dev, as_master, pins->nss, pins->sck, pins->miso, pins->mosi);
}
@ -674,4 +651,4 @@ static spi_baud_rate determine_baud_rate(spi_dev *dev, uint32_t freq) {
}
//SPIClass SPI(3);
SPIClass SPI(3); // needed for external libs

View File

@ -6,6 +6,6 @@ paragraph=implements the same API as stock Ethernet-lib. Just replace the includ
category=Communication
url=https://github.com/ntruchsess/arduino_uip
architectures=STM32F4
version=1.04
version=1.0.4
dependencies=
core-dependencies=arduino (>=1.5.0)

View File

@ -10,13 +10,13 @@ version=0.1.0
# ----------------------
compiler.path={runtime.tools.arm-none-eabi-gcc.path}/bin/
compiler.c.cmd=arm-none-eabi-gcc
compiler.c.flags=-c -g -Os -w -MMD -std=gnu11 -ffunction-sections -fdata-sections -nostdlib --param max-inline-insns-single=500 -DBOARD_{build.variant} -D{build.vect} -DERROR_LED_PORT={build.error_led_port} -DERROR_LED_PIN={build.error_led_pin}
compiler.c.flags=-c -g -Os -Wall -MMD -std=gnu11 -ffunction-sections -fdata-sections -nostdlib --param max-inline-insns-single=500 -DBOARD_{build.variant} -D{build.vect} -DERROR_LED_PORT={build.error_led_port} -DERROR_LED_PIN={build.error_led_pin}
compiler.c.elf.cmd=arm-none-eabi-g++
compiler.c.elf.flags=-Os -Wl,--gc-sections
compiler.S.cmd=arm-none-eabi-gcc
compiler.S.flags=-c -g -x assembler-with-cpp -MMD
compiler.cpp.cmd=arm-none-eabi-g++
compiler.cpp.flags=-c -g -Os -w -MMD -std=gnu++11 -ffunction-sections -fdata-sections -nostdlib --param max-inline-insns-single=500 -fno-rtti -fno-exceptions -DBOARD_{build.variant} -D{build.vect} -DERROR_LED_PORT={build.error_led_port} -DERROR_LED_PIN={build.error_led_pin}
compiler.cpp.flags=-c -g -Os -Wall -MMD -std=gnu++11 -ffunction-sections -fdata-sections -nostdlib --param max-inline-insns-single=500 -fno-rtti -fno-exceptions -DBOARD_{build.variant} -D{build.vect} -DERROR_LED_PORT={build.error_led_port} -DERROR_LED_PIN={build.error_led_pin}
compiler.ar.cmd=arm-none-eabi-ar
compiler.ar.flags=rcs
compiler.objcopy.cmd=arm-none-eabi-objcopy
@ -123,4 +123,3 @@ tools.stlink_upload.path.linux64={runtime.hardware.path}/tools/linux64
tools.stlink_upload.upload.params.verbose=-d
tools.stlink_upload.upload.params.quiet=
tools.stlink_upload.upload.pattern="{path}/{cmd}" {serial.port.file} {upload.altID} {upload.usbID} "{build.path}/{build.project_name}.bin"

View File

@ -27,7 +27,6 @@
#ifndef _WIRISH_ARDUINO_H_
#define _WIRISH_ARDUINO_H_
//#warning Include Arduino.h from system\libmaple
#include "wirish.h"

View File

@ -34,8 +34,8 @@
#include "discovery_f4.h"
#include <libmaple\gpio.h>
#include <libmaple\rcc.h>
#include <libmaple/gpio.h>
#include <libmaple/rcc.h>
#include "wirish_types.h"

View File

@ -39,9 +39,9 @@ extern "C"{
//#include "generic_f407v.h"
//#include "fsmc.h"
#include <libmaple\gpio.h>
#include <libmaple\rcc.h>
#include <libmaple\timer.h>
#include <libmaple/gpio.h>
#include <libmaple/rcc.h>
#include <libmaple/timer.h>
#include <wirish_types.h>