Skip to content

Commit

Permalink
Maple STM32F1 added
Browse files Browse the repository at this point in the history
  • Loading branch information
greiman committed Mar 24, 2015
1 parent c092796 commit fe80cc3
Show file tree
Hide file tree
Showing 3 changed files with 214 additions and 37 deletions.
2 changes: 1 addition & 1 deletion SdFat/SdFat.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
#include "utility/FatLib.h"
//------------------------------------------------------------------------------
/** SdFat version YYYYMMDD */
#define SD_FAT_VERSION 20150321
#define SD_FAT_VERSION 20150324
//==============================================================================
/**
* \class SdBaseFile
Expand Down
171 changes: 171 additions & 0 deletions SdFat/SdSpiSTM32F1.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
/* 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
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This Library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with the Arduino SdSpi Library. If not, see
* <http://www.gnu.org/licenses/>.
*/
#if defined(__STM32F1__)
#include "SdSpi.h"
#include <SPI.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);
}
//------------------------------------------------------------------------------
void SdSpi::begin() {
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::init(uint8_t sckDivisor) {
if (sckDivisor < SPI_CLOCK_DIV2 || sckDivisor > SPI_CLOCK_DIV256) {
sckDivisor = SPI_CLOCK_DIV2; // may not be needed, testing.
}
SPI.setClockDivider(sckDivisor);
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
}
//------------------------------------------------------------------------------
// STM32
static inline uint8_t spiTransfer(uint8_t b) {
return SPI.transfer(b);
}
//------------------------------------------------------------------------------
// should be valid for STM32
/** SPI receive a byte */
uint8_t SdSpi::receive() {
return spiTransfer(0xFF);
}
//------------------------------------------------------------------------------
/** SPI receive multiple bytes */
// check and finish.

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;
}
}

#else // USE_STM32F1_DMAC
for (size_t i = 0; i < n; i++) {
buf[i] = SPI.transfer(0xFF);
}
#endif // USE_STM32F1_DMAC
return rtn;
}
//------------------------------------------------------------------------------
/** SPI send a byte */
void SdSpi::send(uint8_t b) {
spiTransfer(b);
}
//------------------------------------------------------------------------------
void SdSpi::send(const uint8_t* buf , size_t n) {
#if USE_STM32F1_DMAC
spiDmaTX(buf, n);
while (SPI_DMA_TX_Active) {}

#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_NATIVE_STM32F1_SPI
78 changes: 42 additions & 36 deletions SdFat/utility/DigitalPin.h
Original file line number Diff line number Diff line change
Expand Up @@ -213,41 +213,47 @@ static const pin_map_t pinMap[] = {

#ifdef PORT_D0
// Newer version of 1284P
static const pin_map_t pinMap[] = {
{PORT_TO_MODE(PORT_D0), PORT_TO_INPUT(PORT_D0), PORT_TO_OUTPUT(PORT_D0), BIT_D0},
{PORT_TO_MODE(PORT_D1), PORT_TO_INPUT(PORT_D1), PORT_TO_OUTPUT(PORT_D1), BIT_D1},
{PORT_TO_MODE(PORT_D2), PORT_TO_INPUT(PORT_D2), PORT_TO_OUTPUT(PORT_D2), BIT_D2},
{PORT_TO_MODE(PORT_D3), PORT_TO_INPUT(PORT_D3), PORT_TO_OUTPUT(PORT_D3), BIT_D3},
{PORT_TO_MODE(PORT_D4), PORT_TO_INPUT(PORT_D4), PORT_TO_OUTPUT(PORT_D4), BIT_D4},
{PORT_TO_MODE(PORT_D5), PORT_TO_INPUT(PORT_D5), PORT_TO_OUTPUT(PORT_D5), BIT_D5},
{PORT_TO_MODE(PORT_D6), PORT_TO_INPUT(PORT_D6), PORT_TO_OUTPUT(PORT_D6), BIT_D6},
{PORT_TO_MODE(PORT_D7), PORT_TO_INPUT(PORT_D7), PORT_TO_OUTPUT(PORT_D7), BIT_D7},
{PORT_TO_MODE(PORT_D8), PORT_TO_INPUT(PORT_D8), PORT_TO_OUTPUT(PORT_D8), BIT_D8},
{PORT_TO_MODE(PORT_D9), PORT_TO_INPUT(PORT_D9), PORT_TO_OUTPUT(PORT_D9), BIT_D9},
{PORT_TO_MODE(PORT_D10), PORT_TO_INPUT(PORT_D10), PORT_TO_OUTPUT(PORT_D10), BIT_D10},
{PORT_TO_MODE(PORT_D11), PORT_TO_INPUT(PORT_D11), PORT_TO_OUTPUT(PORT_D11), BIT_D11},
{PORT_TO_MODE(PORT_D12), PORT_TO_INPUT(PORT_D12), PORT_TO_OUTPUT(PORT_D12), BIT_D12},
{PORT_TO_MODE(PORT_D13), PORT_TO_INPUT(PORT_D13), PORT_TO_OUTPUT(PORT_D13), BIT_D13},
{PORT_TO_MODE(PORT_D14), PORT_TO_INPUT(PORT_D14), PORT_TO_OUTPUT(PORT_D14), BIT_D14},
{PORT_TO_MODE(PORT_D15), PORT_TO_INPUT(PORT_D15), PORT_TO_OUTPUT(PORT_D15), BIT_D15},
{PORT_TO_MODE(PORT_D16), PORT_TO_INPUT(PORT_D16), PORT_TO_OUTPUT(PORT_D16), BIT_D16},
{PORT_TO_MODE(PORT_D17), PORT_TO_INPUT(PORT_D17), PORT_TO_OUTPUT(PORT_D17), BIT_D17},
{PORT_TO_MODE(PORT_D18), PORT_TO_INPUT(PORT_D18), PORT_TO_OUTPUT(PORT_D18), BIT_D18},
{PORT_TO_MODE(PORT_D19), PORT_TO_INPUT(PORT_D19), PORT_TO_OUTPUT(PORT_D19), BIT_D19},
{PORT_TO_MODE(PORT_D20), PORT_TO_INPUT(PORT_D20), PORT_TO_OUTPUT(PORT_D20), BIT_D20},
{PORT_TO_MODE(PORT_D21), PORT_TO_INPUT(PORT_D21), PORT_TO_OUTPUT(PORT_D21), BIT_D21},
{PORT_TO_MODE(PORT_D22), PORT_TO_INPUT(PORT_D22), PORT_TO_OUTPUT(PORT_D22), BIT_D22},
{PORT_TO_MODE(PORT_D23), PORT_TO_INPUT(PORT_D23), PORT_TO_OUTPUT(PORT_D23), BIT_D23},
{PORT_TO_MODE(PORT_D24), PORT_TO_INPUT(PORT_D24), PORT_TO_OUTPUT(PORT_D24), BIT_D24},
{PORT_TO_MODE(PORT_D25), PORT_TO_INPUT(PORT_D25), PORT_TO_OUTPUT(PORT_D25), BIT_D25},
{PORT_TO_MODE(PORT_D26), PORT_TO_INPUT(PORT_D26), PORT_TO_OUTPUT(PORT_D26), BIT_D26},
{PORT_TO_MODE(PORT_D27), PORT_TO_INPUT(PORT_D27), PORT_TO_OUTPUT(PORT_D27), BIT_D27},
{PORT_TO_MODE(PORT_D28), PORT_TO_INPUT(PORT_D28), PORT_TO_OUTPUT(PORT_D28), BIT_D28},
{PORT_TO_MODE(PORT_D29), PORT_TO_INPUT(PORT_D29), PORT_TO_OUTPUT(PORT_D29), BIT_D29},
{PORT_TO_MODE(PORT_D30), PORT_TO_INPUT(PORT_D30), PORT_TO_OUTPUT(PORT_D30), BIT_D30},
{PORT_TO_MODE(PORT_D31), PORT_TO_INPUT(PORT_D31), PORT_TO_OUTPUT(PORT_D31), BIT_D31}
#define DPM(x) {PORT_TO_MODE(PORT_D##x), PORT_TO_INPUT(PORT_D##x), \
PORT_TO_OUTPUT(PORT_D##x), BIT_D##x}

static const pin_map_t pinMap[] = {
DPM(0),
DPM(1),
DPM(2),
DPM(3),
DPM(4),
DPM(5),
DPM(6),
DPM(7),
DPM(8),
DPM(9),
DPM(10),
DPM(11),
DPM(12),
DPM(13),
DPM(14),
DPM(15),
DPM(16),
DPM(17),
DPM(18),
DPM(19),
DPM(20),
DPM(21),
DPM(22),
DPM(23),
DPM(24),
DPM(25),
DPM(26),
DPM(27),
DPM(28),
DPM(29),
DPM(30),
DPM(31)
};
#elif analogInputToDigitalPin(0)==24

#undef DPM

#elif analogInputToDigitalPin(0) == 24
// Mighty Layout
static const pin_map_t pinMap[] = {
{&DDRB, &PINB, &PORTB, 0}, // B0 0
Expand Down Expand Up @@ -283,7 +289,7 @@ static const pin_map_t pinMap[] = {
{&DDRA, &PINA, &PORTA, 6}, // A6 30
{&DDRA, &PINA, &PORTA, 7} // A7 31
};
#elif analogInputToDigitalPin(0)==21
#elif analogInputToDigitalPin(0) == 21
// Bobuino Layout
static const pin_map_t pinMap[] = {
{&DDRD, &PIND, &PORTD, 0}, // D0 0
Expand Down Expand Up @@ -319,7 +325,7 @@ static const pin_map_t pinMap[] = {
{&DDRD, &PIND, &PORTD, 4}, // D4 30
{&DDRD, &PIND, &PORTD, 7} // D7 31
};
#elif analogInputToDigitalPin(0)==31
#elif analogInputToDigitalPin(0) == 31
// Standard Layout
static const pin_map_t pinMap[] = {
{&DDRB, &PINB, &PORTB, 0}, // B0 0
Expand Down

0 comments on commit fe80cc3

Please sign in to comment.