@@ -75,12 +75,13 @@ void setup() { | |||
#if WAIT_TO_START | |||
cout << F("Type any character to start\n"); | |||
while (Serial.read() <= 0) { | |||
while (!Serial.available()) { | |||
SysCall::yield(); | |||
} | |||
// Discard input. | |||
do { | |||
delay(10); | |||
} while(Serial.read() >= 0); | |||
} while(Serial.available() && Serial.read() >= 0); | |||
#endif // WAIT_TO_START | |||
#if USE_DS1307 |
@@ -21,7 +21,7 @@ void setup() { | |||
SysCall::yield(); | |||
} | |||
Serial.println("type any character to start"); | |||
while (Serial.read() < 0) { | |||
while (!Serial.available()) { | |||
SysCall::yield(); | |||
} | |||
if (!sd.begin()) { |
@@ -36,11 +36,14 @@ void loop() { | |||
uint32_t minLatency; | |||
uint32_t totalLatency; | |||
while (Serial.read() >= 0) { | |||
} | |||
// Read any existing Serial data. | |||
do { | |||
delay(10); | |||
} while (Serial.available() && Serial.read() >= 0); | |||
// F() stores strings in flash to save RAM | |||
Serial.println(F("Type any character to start")); | |||
while (Serial.read() <= 0) { | |||
while (!Serial.available()) { | |||
yield(); | |||
} | |||
@@ -32,7 +32,7 @@ void setup() { | |||
} | |||
// F() stores strings in flash to save RAM | |||
cout << endl << F("Type any character to start\n"); | |||
while (Serial.read() <= 0) { | |||
while (!Serial.available()) { | |||
SysCall::yield(); | |||
} | |||
@@ -61,7 +61,7 @@ void setup() { | |||
} | |||
// F() stores strings in flash to save RAM | |||
cout << F("Type any character to start\n"); | |||
while (Serial.read() <= 0) { | |||
while (!Serial.available()) { | |||
SysCall::yield(); | |||
} | |||
@@ -39,15 +39,15 @@ void loop() { | |||
uint32_t minLatency; | |||
uint32_t totalLatency; | |||
// discard any input | |||
// Discard any input. | |||
do { | |||
delay(10); | |||
} while (Serial.read() >= 0); | |||
} while (Serial.available() && Serial.read() >= 0); | |||
// F() stores strings in flash to save RAM | |||
Serial.println(F("Type any character to start")); | |||
while (Serial.read() <= 0) { | |||
while (!Serial.available()) { | |||
yield(); | |||
} | |||
if (!SD.begin(chipSelect)) { |
@@ -42,7 +42,7 @@ void setup() { | |||
} | |||
// F() stores strings in flash to save RAM | |||
cout << F("Type any character to start\n"); | |||
while (Serial.read() <= 0) { | |||
while (!Serial.available()) { | |||
SysCall::yield(); | |||
} | |||
delay(400); // catch Due reset problem |
@@ -91,7 +91,7 @@ void setup() { | |||
SysCall::yield(); | |||
} | |||
cout << F("Type any character to start\n"); | |||
while (Serial.read() <= 0) { | |||
while (!Serial.available()) { | |||
SysCall::yield(); | |||
} | |||
@@ -791,10 +791,10 @@ void setup(void) { | |||
} | |||
//------------------------------------------------------------------------------ | |||
void loop(void) { | |||
// discard any input | |||
// Read any Serial data. | |||
do { | |||
delay(10); | |||
} while (Serial.read() >= 0); | |||
} while (Serial.available() && Serial.read() >= 0); | |||
Serial.println(); | |||
Serial.println(F("type:")); | |||
Serial.println(F("c - convert file to csv")); | |||
@@ -809,10 +809,10 @@ void loop(void) { | |||
if (ERROR_LED_PIN >= 0) { | |||
digitalWrite(ERROR_LED_PIN, LOW); | |||
} | |||
// Read any extra Serial data. | |||
// Read any Serial data. | |||
do { | |||
delay(10); | |||
} while (Serial.read() >= 0); | |||
} while (Serial.available() && Serial.read() >= 0); | |||
if (c == 'c') { | |||
binaryToCsv(); |
@@ -63,13 +63,16 @@ void setup() { | |||
void loop() { | |||
int c; | |||
// Discard any Serial input. | |||
while (Serial.read() > 0) {} | |||
// Read any existing Serial data. | |||
do { | |||
delay(10); | |||
} while (Serial.available() && Serial.read() >= 0); | |||
Serial.print(F("\r\nEnter File Number: ")); | |||
while ((c = Serial.read()) < 0) { | |||
while (!Serial.available()) { | |||
SysCall::yield(); | |||
} | |||
c = Serial.read(); | |||
uint8_t i = c - '0'; | |||
if (!isdigit(c) || i >= n) { | |||
Serial.println(F("Invald number")); |
@@ -16,6 +16,7 @@ | |||
#include <SPI.h> | |||
#include "SdFat.h" | |||
#include "FreeStack.h" | |||
#include "UserDataType.h" // Edit this include file to change data_t. | |||
//------------------------------------------------------------------------------ | |||
// Set useSharedSpi true for use of an SPI sensor. | |||
const bool useSharedSpi = false; | |||
@@ -24,7 +25,6 @@ const bool useSharedSpi = false; | |||
uint32_t startMicros; | |||
//------------------------------------------------------------------------------ | |||
// User data functions. Modify these functions for your data items. | |||
#include "UserDataType.h" // Edit this include file to change data_t. | |||
// Acquire a data record. | |||
void acquireData(data_t* data) { | |||
@@ -67,6 +67,7 @@ const uint8_t SD_CS_PIN = SS; | |||
// Digital pin to indicate an error, set to -1 if not used. | |||
// The led blinks for fatal errors. The led goes on solid for SD write | |||
// overrun errors and logging continues. | |||
#undef ERROR_LED_PIN | |||
const int8_t ERROR_LED_PIN = -1; | |||
//------------------------------------------------------------------------------ | |||
// File definitions. | |||
@@ -544,10 +545,10 @@ void setup(void) { | |||
} | |||
//------------------------------------------------------------------------------ | |||
void loop(void) { | |||
// discard any input | |||
// Read any Serial data. | |||
do { | |||
delay(10); | |||
} while (Serial.read() >= 0); | |||
} while (Serial.available() && Serial.read() >= 0); | |||
Serial.println(); | |||
Serial.println(F("type:")); | |||
Serial.println(F("c - convert file to csv")); | |||
@@ -563,7 +564,7 @@ void loop(void) { | |||
// Discard extra Serial data. | |||
do { | |||
delay(10); | |||
} while (Serial.read() >= 0); | |||
} while (Serial.available() && Serial.read() >= 0); | |||
if (ERROR_LED_PIN >= 0) { | |||
digitalWrite(ERROR_LED_PIN, LOW); |
@@ -21,7 +21,7 @@ void setup() { | |||
} | |||
Serial.println("Type any character to start"); | |||
while (Serial.read() <= 0) { | |||
while (!Serial.available()) { | |||
SysCall::yield(); | |||
} | |||
@@ -36,11 +36,14 @@ void loop() { | |||
uint32_t minLatency; | |||
uint32_t totalLatency; | |||
while (Serial.read() >= 0) { | |||
} | |||
// Read any existing Serial data. | |||
do { | |||
delay(10); | |||
} while (Serial.available() && Serial.read() >= 0); | |||
// F stores strings in flash to save RAM | |||
cout << F("Type any character to start\n"); | |||
while (Serial.read() <= 0) { | |||
while (!Serial.available()) { | |||
SysCall::yield(); | |||
} | |||
delay(400); // catch Due reset problem | |||
@@ -67,10 +67,10 @@ void setup() { | |||
bool firstTry = true; | |||
void loop() { | |||
// read any existing Serial data | |||
// Read any existing Serial data. | |||
do { | |||
delay(10); | |||
} while (Serial.read() >= 0); | |||
} while (Serial.available() && Serial.read() >= 0); | |||
if (!firstTry) { | |||
cout << F("\nRestarting\n"); | |||
@@ -155,10 +155,12 @@ void loop() { | |||
reformatMsg(); | |||
return; | |||
} | |||
// read any existing Serial data | |||
while (Serial.read() >= 0) {} | |||
// Read any extra Serial data. | |||
do { | |||
delay(10); | |||
} while (Serial.available() && Serial.read() >= 0); | |||
cout << F("\nSuccess! Type any character to restart.\n"); | |||
while (Serial.read() < 0) { | |||
while (!Serial.available()) { | |||
SysCall::yield(); | |||
} | |||
} |
@@ -59,12 +59,13 @@ void setup(void) { | |||
} | |||
//------------------------------------------------------------------------------ | |||
void loop(void) { | |||
// Read any extra Serial data. | |||
do { | |||
delay(10); | |||
} while (Serial.read() >= 0); | |||
} while (Serial.available() && Serial.read() >= 0); | |||
// F stores strings in flash to save RAM | |||
cout << F("Type any character to start\n"); | |||
while (Serial.read() <= 0) { | |||
while (!Serial.available()) { | |||
SysCall::yield(); | |||
} | |||
@@ -57,7 +57,7 @@ void setup() { | |||
SysCall::yield(); | |||
} | |||
Serial.println("Type any character to start"); | |||
while (Serial.read() <= 0) { | |||
while (!Serial.available()) { | |||
SysCall::yield(); | |||
} | |||
// Initialize the SD. |
@@ -54,7 +54,7 @@ void setup() { | |||
SysCall::yield(); | |||
} | |||
Serial.println("Type any character to start"); | |||
while (Serial.read() <= 0) { | |||
while (!Serial.available()) { | |||
SysCall::yield(); | |||
} | |||
// Initialize the SD. |
@@ -33,7 +33,7 @@ void setup() { | |||
SysCall::yield(); | |||
} | |||
Serial.println("Type any character to start"); | |||
while (Serial.read() <= 0) { | |||
while (!Serial.available()) { | |||
SysCall::yield(); | |||
} | |||
// Initialize SdFat or print a detailed error message and halt |
@@ -445,11 +445,13 @@ void setup() { | |||
SysCall::yield(); | |||
} | |||
cout << F("Type any character to start\n"); | |||
while (Serial.read() <= 0) { | |||
while (!Serial.available()) { | |||
SysCall::yield(); | |||
} | |||
// Discard any extra characters. | |||
do {delay(10);} while (Serial.read() >= 0); | |||
do { | |||
delay(10); | |||
} while (Serial.available() && Serial.read() >= 0); | |||
cout << F( | |||
"\n" | |||
"This program can erase and/or format SD/SDHC cards.\n" | |||
@@ -473,10 +475,10 @@ void setup() { | |||
cout << F("Quiting, you did not enter 'Y'.\n"); | |||
return; | |||
} | |||
// read any existing Serial data | |||
// Read any existing Serial data. | |||
do { | |||
delay(10); | |||
} while (Serial.read() >= 0); | |||
} while (Serial.available() && Serial.read() >= 0); | |||
cout << F( | |||
"\n" |
@@ -171,14 +171,14 @@ void setup() { | |||
} | |||
//------------------------------------------------------------------------------ | |||
void loop() { | |||
// read any existing Serial data | |||
// Read any existing Serial data. | |||
do { | |||
delay(10); | |||
} while (Serial.read() >= 0); | |||
} while (Serial.available() && Serial.read() >= 0); | |||
// F stores strings in flash to save RAM | |||
cout << F("\ntype any character to start\n"); | |||
while (Serial.read() <= 0) { | |||
while (!Serial.available()) { | |||
SysCall::yield(); | |||
} | |||
@@ -28,7 +28,7 @@ void setup() { | |||
SysCall::yield(); | |||
} | |||
Serial.println("Type any character to start"); | |||
while (Serial.read() <= 0) { | |||
while (!Serial.available()) { | |||
SysCall::yield(); | |||
} | |||
@@ -58,7 +58,7 @@ void setup() { | |||
buf[i] = i; | |||
} | |||
Serial.println(F("type any character to start")); | |||
while (Serial.read() <= 0) { | |||
while (!Serial.available()) { | |||
SysCall::yield(); | |||
} | |||
// disable sd2 while initializing sd1 |
@@ -38,7 +38,7 @@ void setup() { | |||
} | |||
Serial.println(F("type any character to start")); | |||
while (Serial.read() <= 0) { | |||
while (!Serial.available()) { | |||
SysCall::yield(); | |||
} | |||
@@ -46,7 +46,7 @@ void setup() { | |||
} | |||
// F stores strings in flash to save RAM | |||
cout << F("Type any character to start\n"); | |||
while (Serial.read() <= 0) { | |||
while (!Serial.available()) { | |||
SysCall::yield(); | |||
} | |||
// initialize the SD card at SPI_HALF_SPEED to avoid bus errors with |
@@ -15,10 +15,10 @@ const size_t BUF_SIZE = 512; | |||
const uint32_t FILE_SIZE_MB = 5; | |||
// Write pass count. | |||
const uint8_t WRITE_COUNT = 10; | |||
const uint8_t WRITE_COUNT = 2; | |||
// Read pass count. | |||
const uint8_t READ_COUNT = 5; | |||
const uint8_t READ_COUNT = 2; | |||
//============================================================================== | |||
// End of configuration constants. | |||
//------------------------------------------------------------------------------ | |||
@@ -29,6 +29,10 @@ uint8_t buf[BUF_SIZE]; | |||
// file system | |||
SdFat sd; | |||
// Set SD_SPI_CONFIGURATION to three to test next two definitions. | |||
// SdFatLibSpi sd; | |||
// Args are misoPin, mosiPin, sckPin. | |||
// SdFatSoftSpi<6, 7, 5> sd; | |||
// test file | |||
SdFile file; | |||
@@ -81,14 +85,14 @@ void loop() { | |||
uint32_t minLatency; | |||
uint32_t totalLatency; | |||
// discard any input | |||
// Discard any input. | |||
do { | |||
delay(10); | |||
} while (Serial.read() >= 0); | |||
} while (Serial.available() && Serial.read() >= 0); | |||
// F( stores strings in flash to save RAM | |||
cout << F("Type any character to start\n"); | |||
while (Serial.read() <= 0) { | |||
while (!Serial.available()) { | |||
SysCall::yield(); | |||
} | |||
@@ -102,9 +102,10 @@ void setup() { | |||
if (!file.open(fileName, O_CREAT | O_WRITE | O_EXCL)) { | |||
error("file.open"); | |||
} | |||
// Read any Serial data. | |||
do { | |||
delay(10); | |||
} while (Serial.read() >= 0); | |||
} while (Serial.available() && Serial.read() >= 0); | |||
Serial.print(F("Logging to: ")); | |||
Serial.println(fileName); |
@@ -67,7 +67,9 @@ void setup(void) { | |||
} | |||
cout << F("Type any character to start\n"); | |||
while (Serial.read() <= 0) {} | |||
while (!Serial.available()) { | |||
SysCall::yield(); | |||
} | |||
delay(400); // catch Due reset problem | |||
// initialize the SD card at SPI_HALF_SPEED to avoid bus errors with |
@@ -62,8 +62,9 @@ void setup(void) { | |||
// F stores strings in flash to save RAM | |||
cout << F("Type any character to start\n"); | |||
while (Serial.read() <= 0) {} | |||
delay(400); // catch Due reset problem | |||
while (!Serial.available()) { | |||
SysCall::yield(); | |||
} | |||
// initialize the SD card at SPI_HALF_SPEED to avoid bus errors with | |||
// breadboards. use SPI_FULL_SPEED for better performance. |
@@ -97,8 +97,9 @@ void setup() { | |||
SysCall::yield(); | |||
} | |||
cout << F("Type any character to start\n"); | |||
while (Serial.read() <= 0) {} | |||
delay(400); // catch Due reset problem | |||
while (!Serial.available()) { | |||
SysCall::yield(); | |||
} | |||
// initialize the SD card at SPI_HALF_SPEED to avoid bus errors with | |||
// breadboards. use SPI_FULL_SPEED for better performance |
@@ -25,7 +25,7 @@ void setup() { | |||
SysCall::yield(); | |||
} | |||
cout << F("Insert an empty SD. Type any character to start.") << endl; | |||
while (Serial.read() <= 0) { | |||
while (!Serial.available()) { | |||
SysCall::yield(); | |||
} | |||
@@ -13,9 +13,10 @@ void setup() { | |||
SysCall::yield(); | |||
} | |||
Serial.println("Type 'Y' to wipe all data."); | |||
while ((c = Serial.read()) <= 0) { | |||
while (!Serial.available()) { | |||
SysCall::yield(); | |||
} | |||
c = Serial.read(); | |||
if (c != 'Y') { | |||
sd.errorHalt("Quitting, you did not type 'Y'."); | |||
} |
@@ -32,7 +32,7 @@ | |||
#endif // ARDUINO | |||
//------------------------------------------------------------------------------ | |||
/** SdFat version YYYYMMDD */ | |||
#define SD_FAT_VERSION 20160411 | |||
#define SD_FAT_VERSION 20160422 | |||
//============================================================================== | |||
/** | |||
* \class SdBaseFile |
@@ -229,28 +229,34 @@ void fastDigitalWrite(uint8_t pin, bool value) { | |||
//------------------------------------------------------------------------------ | |||
/** Set pin value | |||
* @param[in] pin Arduino pin number | |||
* @param[in] level value to write | |||
* @param[in] val value to write | |||
*/ | |||
static inline __attribute__((always_inline)) | |||
void fastDigitalWrite(uint8_t pin, uint8_t val) { | |||
if(pin < 16){ | |||
if(val) GPOS = (1 << pin); | |||
else GPOC = (1 << pin); | |||
} else if(pin == 16){ | |||
if(val) GP16O |= 1; | |||
else GP16O &= ~1; | |||
if (pin < 16) { | |||
if (val) { | |||
GPOS = (1 << pin); | |||
} else { | |||
GPOC = (1 << pin); | |||
} | |||
} else if (pin == 16) { | |||
if (val) { | |||
GP16O |= 1; | |||
} else { | |||
GP16O &= ~1; | |||
} | |||
} | |||
} | |||
//------------------------------------------------------------------------------ | |||
/** read pin value | |||
/** Read pin value | |||
* @param[in] pin Arduino pin number | |||
* @return value read | |||
*/ | |||
static inline __attribute__((always_inline)) | |||
bool fastDigitalRead(uint8_t pin) { | |||
if(pin < 16){ | |||
if (pin < 16) { | |||
return GPIP(pin); | |||
} else if(pin == 16){ | |||
} else if (pin == 16) { | |||
return GP16I & 0x01; | |||
} | |||
return 0; | |||
@@ -268,7 +274,7 @@ inline void fastDigitalToggle(uint8_t pin) { | |||
fastDigitalWrite(pin, !fastDigitalRead(pin)); | |||
} | |||
//------------------------------------------------------------------------------ | |||
inline void fastPinMode(uint8_t pin, uint8_t mode) {pinMode(pin, mode);} | |||
#define fastPinMode(pin, mode) pinMode(pin, mode) | |||
#endif // __AVR__ | |||
//------------------------------------------------------------------------------ | |||
/** set pin configuration | |||
@@ -277,11 +283,8 @@ inline void fastPinMode(uint8_t pin, uint8_t mode) {pinMode(pin, mode);} | |||
* @param[in] level If mode is output, set level high/low. | |||
* If mode is input, enable or disable the pin's 20K pullup. | |||
*/ | |||
static inline __attribute__((always_inline)) | |||
void fastPinConfig(uint8_t pin, uint8_t mode, bool level) { | |||
fastPinMode(pin, mode); | |||
fastDigitalWrite(pin, level); | |||
} | |||
#define fastPinConfig(pin, mode, level)\ | |||
{fastPinMode(pin, mode); fastDigitalWrite(pin, level);} | |||
//============================================================================== | |||
/** | |||
* @class DigitalPin |
@@ -1,8 +1,6 @@ | |||
/* Arduino SdSpi Library | |||
* Copyright (C) 2013 by William Greiman | |||
* | |||
* STM32F1 code for Maple and Maple Mini support, 2015 by Victor Perez | |||
* | |||
* This file is part of the Arduino SdSpi Library | |||
* | |||
* This Library is free software: you can redistribute it and/or modify | |||
@@ -21,162 +19,104 @@ | |||
*/ | |||
#if defined(__STM32F1__) | |||
#include "SdSpi.h" | |||
#include <libmaple/dma.h> | |||
/** Use STM32 DMAC if nonzero */ | |||
#define USE_STM32F1_DMAC 1 | |||
/** Time in ms for DMA receive timeout */ | |||
#define STM32F1_DMA_TIMEOUT 100 | |||
/** DMAC receive channel */ | |||
#define SPI1_DMAC_RX_CH DMA_CH2 | |||
/** DMAC transmit channel */ | |||
#define SPI1_DMAC_TX_CH DMA_CH3 | |||
volatile bool SPI_DMA_TX_Active = false; | |||
volatile bool SPI_DMA_RX_Active = false; | |||
/** ISR for DMA TX event. */ | |||
inline void SPI_DMA_TX_Event() { | |||
SPI_DMA_TX_Active = false; | |||
dma_disable(DMA1, SPI_DMAC_TX_CH); | |||
} | |||
/** ISR for DMA RX event. */ | |||
inline void SPI_DMA_RX_Event() { | |||
SPI_DMA_RX_Active = false; | |||
dma_disable(DMA1, SPI1_DMAC_RX_CH); | |||
} | |||
//------------------------------------------------------------------------------ | |||
/** Disable DMA Channel. */ | |||
static void dmac_channel_disable(dma_channel ul_num) { | |||
dma_disable(DMA1, ul_num); | |||
} | |||
/** Enable DMA Channel. */ | |||
static void dmac_channel_enable(dma_channel ul_num) { | |||
dma_enable(DMA1, ul_num); | |||
} | |||
//------------------------------------------------------------------------------ | |||
/** Initialize the SPI bus. | |||
* | |||
* \param[in] chipSelectPin SD card chip select pin. | |||
*/ | |||
void SdSpi::begin(uint8_t chipSelectPin) { | |||
pinMode(chipSelectPin, OUTPUT); | |||
digitalWrite(chipSelectPin, HIGH); | |||
SPI.begin(); | |||
} | |||
//------------------------------------------------------------------------------ | |||
// start RX DMA | |||
static void spiDmaRX(uint8_t* dst, uint16_t count) { | |||
// spi_rx_dma_enable(SPI1); | |||
if (count < 1) return; | |||
dma_setup_transfer(DMA1, SPI1_DMAC_RX_CH, &SPI1->regs->DR, DMA_SIZE_8BITS, | |||
dst, DMA_SIZE_8BITS, (DMA_MINC_MODE | DMA_TRNS_CMPLT)); | |||
dma_set_num_transfers(DMA1, SPI1_DMAC_RX_CH, count); // 2 bytes per pixel | |||
SPI_DMA_RX_Active = true; | |||
dma_enable(DMA1, SPI1_DMAC_RX_CH); | |||
} | |||
//------------------------------------------------------------------------------ | |||
// start TX DMA | |||
static void spiDmaTX(const uint8_t* src, uint16_t count) { | |||
if (count < 1) return; | |||
static uint8_t ff = 0XFF; | |||
if (!src) { | |||
src = &ff; | |||
dma_setup_transfer(DMA1, SPI1_DMAC_TX_CH, &SPI1->regs->DR, DMA_SIZE_8BITS, | |||
const_cast<uint8_t*>(src), DMA_SIZE_8BITS, | |||
(DMA_FROM_MEM | DMA_TRNS_CMPLT)); | |||
} else { | |||
dma_setup_transfer(DMA1, SPI1_DMAC_TX_CH, &SPI1->regs->DR, DMA_SIZE_8BITS, | |||
const_cast<uint8_t*>(src), DMA_SIZE_8BITS, | |||
(DMA_MINC_MODE | DMA_FROM_MEM | DMA_TRNS_CMPLT)); | |||
} | |||
dma_set_num_transfers(DMA1, SPI1_DMAC_TX_CH, count); // 2 bytes per pixel | |||
SPI_DMA_TX_Active = true; | |||
dma_enable(DMA1, SPI1_DMAC_TX_CH); | |||
} | |||
//------------------------------------------------------------------------------ | |||
// initialize SPI controller STM32F1 | |||
void SdSpi::beginTransaction(uint8_t sckDivisor) { | |||
/** Set SPI options for access to SD/SDHC cards. | |||
* | |||
* \param[in] divisor SCK clock divider relative to the APB1 or APB2 clock. | |||
*/ | |||
void SdSpi::beginTransaction(uint8_t divisor) { | |||
#if ENABLE_SPI_TRANSACTIONS | |||
SPI.beginTransaction(SPISettings()); | |||
// Correct divisor will be set below. | |||
SPI.beginTransaction(SPISettings(4000000, MSBFIRST, SPI_MODE0)); | |||
#endif // ENABLE_SPI_TRANSACTIONS | |||
if (sckDivisor < SPI_CLOCK_DIV2 || sckDivisor > SPI_CLOCK_DIV256) { | |||
sckDivisor = SPI_CLOCK_DIV2; // may not be needed, testing. | |||
uint32_t br; // Baud rate control field in SPI_CR1. | |||
if (divisor <= 2) { | |||
br = SPI_CLOCK_DIV2; | |||
} else if (divisor <= 4) { | |||
br = SPI_CLOCK_DIV4; | |||
} else if (divisor <= 8) { | |||
br = SPI_CLOCK_DIV8; | |||
} else if (divisor <= 16) { | |||
br = SPI_CLOCK_DIV16; | |||
} else if (divisor <= 32) { | |||
br = SPI_CLOCK_DIV32; | |||
} else if (divisor <= 64) { | |||
br = SPI_CLOCK_DIV64; | |||
} else if (divisor <= 128) { | |||
br = SPI_CLOCK_DIV128; | |||
} else { | |||
br = SPI_CLOCK_DIV256; | |||
} | |||
SPI.setClockDivider(sckDivisor); | |||
SPI.setClockDivider(br); | |||
#if !ENABLE_SPI_TRANSACTIONS | |||
SPI.setBitOrder(MSBFIRST); | |||
SPI.setDataMode(SPI_MODE0); | |||
#if USE_STM32F1_DMAC | |||
dma_init(DMA1); | |||
dma_attach_interrupt(DMA1, SPI1_DMAC_TX_CH, SPI_DMA_TX_Event); | |||
dma_attach_interrupt(DMA1, SPI1_DMAC_RX_CH, SPI_DMA_RX_Event); | |||
spi_tx_dma_enable(SPI1); | |||
spi_rx_dma_enable(SPI1); | |||
#endif // USE_STM32F1_DMAC | |||
#endif // !ENABLE_SPI_TRANSACTIONS | |||
} | |||
//------------------------------------------------------------------------------ | |||
/** | |||
* End SPI transaction. | |||
*/ | |||
void SdSpi::endTransaction() { | |||
#if ENABLE_SPI_TRANSACTIONS | |||
SPI.endTransaction(); | |||
#endif // ENABLE_SPI_TRANSACTIONS | |||
} | |||
//------------------------------------------------------------------------------ | |||
// STM32 | |||
static inline uint8_t spiTransfer(uint8_t b) { | |||
return SPI.transfer(b); | |||
} | |||
//------------------------------------------------------------------------------ | |||
// should be valid for STM32 | |||
/** SPI receive a byte */ | |||
/** Receive a byte. | |||
* | |||
* \return The byte. | |||
*/ | |||
uint8_t SdSpi::receive() { | |||
return spiTransfer(0xFF); | |||
return SPI.transfer(0XFF); | |||
} | |||
//------------------------------------------------------------------------------ | |||
/** SPI receive multiple bytes */ | |||
// check and finish. | |||
/** Receive multiple bytes. | |||
* | |||
* \param[out] buf Buffer to receive the data. | |||
* \param[in] n Number of bytes to receive. | |||
* | |||
* \return Zero for no error or nonzero error code. | |||
*/ | |||
uint8_t SdSpi::receive(uint8_t* buf, size_t n) { | |||
int rtn = 0; | |||
#if USE_STM32F1_DMAC | |||
spiDmaRX(buf, n); | |||
spiDmaTX(0, n); | |||
uint32_t m = millis(); | |||
while (SPI_DMA_RX_Active) { | |||
if ((millis() - m) > STM32F1_DMA_TIMEOUT) { | |||
dmac_channel_disable(SPI_DMAC_RX_CH); | |||
dmac_channel_disable(SPI_DMAC_TX_CH); | |||
rtn = 2; | |||
break; | |||
} | |||
} | |||
rtn = SPI.dmaTransfer(0, const_cast<uint8*>(buf), n); | |||
#else // USE_STM32F1_DMAC | |||
for (size_t i = 0; i < n; i++) { | |||
buf[i] = SPI.transfer(0xFF); | |||
} | |||
SPI.read(buf, n); | |||
#endif // USE_STM32F1_DMAC | |||
return rtn; | |||
} | |||
//------------------------------------------------------------------------------ | |||
/** SPI send a byte */ | |||
/** Send a byte. | |||
* | |||
* \param[in] b Byte to send | |||
*/ | |||
void SdSpi::send(uint8_t b) { | |||
spiTransfer(b); | |||
SPI.transfer(b); | |||
} | |||
//------------------------------------------------------------------------------ | |||
/** Send multiple bytes. | |||
* | |||
* \param[in] buf Buffer for data to be sent. | |||
* \param[in] n Number of bytes to send. | |||
*/ | |||
void SdSpi::send(const uint8_t* buf , size_t n) { | |||
#if USE_STM32F1_DMAC | |||
spiDmaTX(buf, n); | |||
while (SPI_DMA_TX_Active) {} | |||
SPI.dmaSend(const_cast<uint8*>(buf), n); | |||
#else // #if USE_STM32F1_DMAC | |||
SPI.write(buf, n); | |||
#endif // #if USE_STM32F1_DMAC | |||
// leave RX register empty | |||
// while (spi_is_rx_nonempty(SPI1)) | |||
uint8_t b = spi_rx_reg(SPI1); | |||
#endif // USE_STM32F1_DMAC | |||
} | |||
#endif // USE_NATIVE_STM32F1_SPI |
@@ -34,13 +34,13 @@ | |||
#define nop asm volatile ("nop\n\t") | |||
//------------------------------------------------------------------------------ | |||
/** Pin Mode for MISO is input.*/ | |||
const bool MISO_MODE = false; | |||
#define MISO_MODE INPUT | |||
/** Pullups disabled for MISO are disabled. */ | |||
const bool MISO_LEVEL = false; | |||
#define MISO_LEVEL false | |||
/** Pin Mode for MOSI is output.*/ | |||
const bool MOSI_MODE = true; | |||
#define MOSI_MODE OUTPUT | |||
/** Pin Mode for SCK is output. */ | |||
const bool SCK_MODE = true; | |||
#define SCK_MODE OUTPUT | |||
//------------------------------------------------------------------------------ | |||
/** | |||
* @class SoftSPI |