diff options
-rw-r--r-- | boards/OLIMEX_SAM7_EX256/board.h | 9 | ||||
-rw-r--r-- | boards/OLIMEX_SAM7_P256/board.h | 9 | ||||
-rw-r--r-- | demos/ARM7-AT91SAM7X-FATFS-GCC/main.c | 4 | ||||
-rw-r--r-- | os/hal/platforms/AT91SAM7/serial_lld.c | 13 | ||||
-rw-r--r-- | os/hal/platforms/AT91SAM7/spi_lld.c | 121 | ||||
-rw-r--r-- | os/hal/platforms/AT91SAM7/spi_lld.h | 110 | ||||
-rw-r--r-- | os/hal/platforms/STM32/spi_lld.h | 2 |
7 files changed, 201 insertions, 67 deletions
diff --git a/boards/OLIMEX_SAM7_EX256/board.h b/boards/OLIMEX_SAM7_EX256/board.h index 40040617b..22add597e 100644 --- a/boards/OLIMEX_SAM7_EX256/board.h +++ b/boards/OLIMEX_SAM7_EX256/board.h @@ -91,13 +91,4 @@ #define PIOB_PHY_IRQ 26
#define PIOB_PHY_IRQ_MASK (1 << PIOB_PHY_IRQ)
-#define MMC_CSR_NUM 1
-
-/*
- * SPI0 pins
- */
-#define SPI_MISO (1 << 16)
-#define SPI_MOSI (1 << 17)
-#define SPI_SCK (1 << 18)
-
#endif /* _BOARD_H_ */
diff --git a/boards/OLIMEX_SAM7_P256/board.h b/boards/OLIMEX_SAM7_P256/board.h index b547f969b..0e2a3d783 100644 --- a/boards/OLIMEX_SAM7_P256/board.h +++ b/boards/OLIMEX_SAM7_P256/board.h @@ -71,13 +71,4 @@ #define PIOA_MMC_NPCS0 11
#define PIOA_MMC_NPCS0_MASK (1 << PIOA_MMC_NPCS0_MASK)
-#define MMC_CSR_NUM 0
-
-/*
- * SPI pins
- */
-#define SPI_MISO (1 << 12)
-#define SPI_MOSI (1 << 13)
-#define SPI_SCK (1 << 14)
-
#endif /* _BOARD_H_ */
diff --git a/demos/ARM7-AT91SAM7X-FATFS-GCC/main.c b/demos/ARM7-AT91SAM7X-FATFS-GCC/main.c index fc8139146..9cc9221a3 100644 --- a/demos/ARM7-AT91SAM7X-FATFS-GCC/main.c +++ b/demos/ARM7-AT91SAM7X-FATFS-GCC/main.c @@ -45,17 +45,17 @@ static bool_t fs_ready = FALSE; /* Maximum speed SPI configuration (__MHz, NCPHA=1, CPOL=0).*/
static SPIConfig hs_spicfg = {
+ NULL,
IOPORT1,
PIOA_CS_MMC,
- AT91C_SPI_MSTR | AT91C_SPI_MODFDIS,
(MAX_SPI_BITRATE << 8) | AT91C_SPI_NCPHA | AT91C_SPI_BITS_8
};
/* Low speed SPI configuration (192KHz, NCPHA=1, CPOL=0).*/
static SPIConfig ls_spicfg = {
+ NULL,
IOPORT1,
PIOA_CS_MMC,
- AT91C_SPI_MSTR | AT91C_SPI_MODFDIS,
(MIN_SPI_BITRATE << 8) | AT91C_SPI_NCPHA | AT91C_SPI_BITS_8
};
diff --git a/os/hal/platforms/AT91SAM7/serial_lld.c b/os/hal/platforms/AT91SAM7/serial_lld.c index df57e5ed4..10833f497 100644 --- a/os/hal/platforms/AT91SAM7/serial_lld.c +++ b/os/hal/platforms/AT91SAM7/serial_lld.c @@ -248,8 +248,8 @@ CH_IRQ_HANDLER(USART1IrqHandler) { }
#endif
-// note - DBGU_UART IRQ is the SysIrq in board.c
-// since it's not vectored separately by the AIC
+/* note - DBGU_UART IRQ is the SysIrq in board.c
+ since it's not vectored separately by the AIC.*/
/*===========================================================================*/
/* Driver exported functions. */
@@ -286,9 +286,9 @@ void sd_lld_init(void) { #if USE_SAM7_DBGU_UART
sdObjectInit(&SD3, NULL, notify3);
- // this is a little cheap, but OK for now since there's enough overlap
- // between dbgu and usart register maps. it means we can reuse all the
- // same usart interrupt handling and config that already exists
+ /* this is a little cheap, but OK for now since there's enough overlap
+ between dbgu and usart register maps. it means we can reuse all the
+ same usart interrupt handling and config that already exists.*/
SD3.usart = (AT91PS_USART)AT91C_BASE_DBGU;
AT91C_BASE_PIOA->PIO_PDR = SAM7_DBGU_RX | SAM7_DBGU_TX;
AT91C_BASE_PIOA->PIO_ASR = SAM7_DBGU_RX | SAM7_DBGU_TX;
@@ -328,7 +328,8 @@ void sd_lld_start(SerialDriver *sdp, const SerialConfig *config) { AIC_EnableIT(AT91C_ID_US1);
}
#endif
- // note - no explicit start for SD3 (DBGU_UART) since it's not included in the AIC or PMC
+ /* Note - no explicit start for SD3 (DBGU_UART) since it's not included + in the AIC or PMC.*/
}
usart_init(sdp, config);
}
diff --git a/os/hal/platforms/AT91SAM7/spi_lld.c b/os/hal/platforms/AT91SAM7/spi_lld.c index d614aabb5..592bc092e 100644 --- a/os/hal/platforms/AT91SAM7/spi_lld.c +++ b/os/hal/platforms/AT91SAM7/spi_lld.c @@ -34,9 +34,14 @@ /* Driver exported variables. */
/*===========================================================================*/
-#if USE_AT91SAM7_SPI || defined(__DOXYGEN__)
-/** @brief SPI driver identifier.*/
-SPIDriver SPID;
+#if AT91SAM7_SPI_USE_SPI0 || defined(__DOXYGEN__)
+/** @brief SPI1 driver identifier.*/
+SPIDriver SPID1;
+#endif
+
+#if AT91SAM7_SPI_USE_SPI1 || defined(__DOXYGEN__)
+/** @brief SPI2 driver identifier.*/
+SPIDriver SPID2;
#endif
/*===========================================================================*/
@@ -81,6 +86,36 @@ void rw8(size_t n, const uint8_t *txbuf, uint8_t *rxbuf) { /* Driver interrupt handlers. */
/*===========================================================================*/
+#if AT91SAM7_SPI_USE_SPI0 || defined(__DOXYGEN__)
+/**
+ * @brief SPI0 interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(SPI0IrqHandler) {
+
+ CH_IRQ_PROLOGUE();
+ spi_lld_serve_interrupt(&SPID1);
+ AT91C_BASE_AIC->AIC_EOICR = 0;
+ CH_IRQ_EPILOGUE();
+}
+#endif
+
+#if AT91SAM7_SPI_USE_SPI1 || defined(__DOXYGEN__)
+/**
+ * @brief SPI1 interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(SPI1IrqHandler) {
+
+ CH_IRQ_PROLOGUE();
+ spi_lld_serve_interrupt(&SPID2);
+ AT91C_BASE_AIC->AIC_EOICR = 0;
+ CH_IRQ_EPILOGUE();
+}
+#endif
+
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
@@ -92,8 +127,32 @@ void rw8(size_t n, const uint8_t *txbuf, uint8_t *rxbuf) { */
void spi_lld_init(void) {
-#if USE_AT91SAM7_SPI
- spiObjectInit(&SPID);
+#if AT91SAM7_SPI_USE_SPI0
+ spiObjectInit(&SPID1);
+ /* Software reset must be written twice (errata for revision B parts).*/
+ AT91C_BASE_SPI0->SPI_CR = AT91C_SPI_SWRST;
+ AT91C_BASE_SPI0->SPI_CR = AT91C_SPI_SWRST;
+ AT91C_BASE_PIOA->PIO_PDR = SPI0_MISO | SPI0_MOSI | SPI0_SCK;
+ AT91C_BASE_PIOA->PIO_ASR = SPI0_MISO | SPI0_MOSI | SPI0_SCK;
+ AT91C_BASE_PIOA->PIO_PPUDR = SPI0_MISO | SPI0_MOSI | SPI0_SCK;
+ SPID1.spd_spi = AT91C_BASE_SPI0;
+ AIC_ConfigureIT(AT91C_ID_SPI0,
+ AT91C_AIC_SRCTYPE_HIGH_LEVEL | AT91SAM7_SPI0_PRIORITY,
+ SPI0IrqHandler);
+#endif
+
+#if AT91SAM7_SPI_USE_SPI1
+ spiObjectInit(&SPID2);
+ /* Software reset must be written twice (errata for revision B parts).*/
+ AT91C_BASE_SPI1->SPI_CR = AT91C_SPI_SWRST;
+ AT91C_BASE_SPI1->SPI_CR = AT91C_SPI_SWRST;
+ AT91C_BASE_PIOA->PIO_PDR = SPI1_MISO | SPI1_MOSI | SPI1_SCK;
+ AT91C_BASE_PIOA->PIO_BSR = SPI1_MISO | SPI1_MOSI | SPI1_SCK;
+ AT91C_BASE_PIOA->PIO_PPUDR = SPI1_MISO | SPI1_MOSI | SPI1_SCK;
+ SPID2.spd_spi = AT91C_BASE_SPI1;
+ AIC_ConfigureIT(AT91C_ID_SPI1,
+ AT91C_AIC_SRCTYPE_HIGH_LEVEL | AT91SAM7_SPI1_PRIORITY,
+ SPI1IrqHandler);
#endif
}
@@ -107,21 +166,29 @@ void spi_lld_init(void) { void spi_lld_start(SPIDriver *spip) {
if (spip->spd_state == SPI_STOP) {
- /* disable general-purpose I/O for SPI pins */
- AT91C_BASE_PIOA->PIO_PDR = SPI_MISO | SPI_MOSI | SPI_SCK;
- /* select perepheral A for SPI pins*/
- AT91C_BASE_PIOA->PIO_ASR = SPI_MISO | SPI_MOSI | SPI_SCK;
- /* Clock activation.*/
- AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_SPI);
+#if AT91SAM7_SPI_USE_SPI0
+ if (&SPID1 == spip) {
+ /* Clock activation.*/
+ AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_SPI0);
+ /* Enables associated interrupt vector.*/
+ AIC_EnableIT(AT91C_ID_SPI0);
+ }
+#endif
+#if AT91SAM7_SPI_USE_SPI1
+ if (&SPID2 == spip) {
+ /* Clock activation.*/
+ AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_SPI1);
+ /* Enables associated interrupt vector.*/
+ AIC_EnableIT(AT91C_ID_SPI1);
+ }
+#endif
}
- /* software reset must be written twice (errata for revision B parts) */
- AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SWRST;
- AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SWRST;
+ else
+ spip->spd_spi->SPI_CR = AT91C_SPI_SPIDIS;
/* Configuration.*/
- AT91C_BASE_SPI->SPI_MR = spip->spd_config->spc_mr;
- AT91C_BASE_SPI->SPI_CSR[MMC_CSR_NUM] = spip->spd_config->spc_csr;
- /* Enable SPI */
- AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SPIEN;
+ spip->spd_spi->SPI_MR = AT91C_SPI_MSTR | AT91C_SPI_MODFDIS;
+ spip->spd_spi->SPI_CSR[0] = spip->spd_config->spc_csr;
+ spip->spd_spi->SPI_CR = AT91C_SPI_SPIEN;
}
/**
@@ -134,10 +201,20 @@ void spi_lld_start(SPIDriver *spip) { void spi_lld_stop(SPIDriver *spip) {
if (spip->spd_state != SPI_STOP) {
- /* disable SPI */
- AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SPIDIS;
- /* disable clocks to SPI perepheral */
- AT91C_BASE_PMC->PMC_PCDR = (1 << AT91C_ID_SPI);
+#if AT91SAM7_SPI_USE_SPI0
+ if (&SPID1 == spip) {
+ spip->spd_spi->SPI_CR = AT91C_SPI_SPIDIS;
+ spip->spd_spi->PMC_PCDR = (1 << AT91C_ID_SPI0);
+ AIC_DisableIT(AT91C_ID_SPI0);
+ }
+#endif
+#if AT91SAM7_SPI_USE_SPI1
+ if (&SPID1 == spip) {
+ spip->spd_spi->SPI_CR = AT91C_SPI_SPIDIS;
+ spip->spd_spi->PMC_PCDR = (1 << AT91C_ID_SPI1);
+ AIC_DisableIT(AT91C_ID_SPI0);
+ }
+#endif
}
}
diff --git a/os/hal/platforms/AT91SAM7/spi_lld.h b/os/hal/platforms/AT91SAM7/spi_lld.h index 4c5ed4388..db896fe18 100644 --- a/os/hal/platforms/AT91SAM7/spi_lld.h +++ b/os/hal/platforms/AT91SAM7/spi_lld.h @@ -31,11 +31,24 @@ #if CH_HAL_USE_SPI || defined(__DOXYGEN__)
/*===========================================================================*/
-/* Device compatibility. SAM7X have 2 SPIs. */
+/* Device compatibility.. */
/*===========================================================================*/
-#if defined (AT91SAM7X256_H)
-#define AT91C_BASE_SPI AT91C_BASE_SPI0
-#define AT91C_ID_SPI AT91C_ID_SPI0
+
+#if defined (AT91C_BASE_SPI)
+#define AT91C_BASE_SPI0 AT91C_BASE_SPI
+#define AT91C_ID_SPI0 AT91C_ID_SPI
+
+#define SPI0_MISO (1 << 12)
+#define SPI0_MOSI (1 << 13)
+#define SPI0_SCK (1 << 14)
+#else
+#define SPI0_MISO (1 << 16)
+#define SPI0_MOSI (1 << 17)
+#define SPI0_SCK (1 << 18)
+
+#define SPI1_MISO (1 << 24)
+#define SPI1_MOSI (1 << 23)
+#define SPI1_SCK (1 << 22)
#endif
/*===========================================================================*/
@@ -47,27 +60,75 @@ /*===========================================================================*/
/**
- * @brief SPI driver enable switch.
+ * @brief SPID1 enable switch (SPI0 device).
* @details If set to @p TRUE the support for SPI0 is included.
* @note The default is @p TRUE.
*/
-#if !defined(USE_AT91SAM7_SPI) || defined(__DOXYGEN__)
-#define USE_AT91SAM7_SPI TRUE
+#if !defined(AT91SAM7_SPI_USE_SPI0) || defined(__DOXYGEN__)
+#define AT91SAM7_SPI_USE_SPI0 TRUE
+#endif
+
+/**
+ * @brief SPID2 enable switch (SPI1 device).
+ * @details If set to @p TRUE the support for SPI1 is included.
+ * @note The default is @p TRUE.
+ */
+#if !defined(AT91SAM7_SPI_USE_SPI1) || defined(__DOXYGEN__)
+#define AT91SAM7_SPI_USE_SPI1 TRUE
+#endif
+
+/**
+ * @brief SPI0 device interrupt priority level setting.
+ */
+#if !defined(AT91SAM7_SPI0_PRIORITY) || defined(__DOXYGEN__)
+#define AT91SAM7_SPI0_PRIORITY (AT91C_AIC_PRIOR_HIGHEST - 1)
+#endif
+
+/**
+ * @brief SPI1 device interrupt priority level setting.
+ */
+#if !defined(AT91SAM7_SPI1_PRIORITY) || defined(__DOXYGEN__)
+#define AT91SAM7_SPI1_PRIORITY (AT91C_AIC_PRIOR_HIGHEST - 1)
#endif
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
+#if !AT91SAM7_SPI_USE_SPI0 && !AT91SAM7_SPI_USE_SPI1
+#error "SPI driver activated but no SPI peripheral assigned"
+#endif
+
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
/**
+ * @brief Type of a structure representing an SPI driver.
+ */
+typedef struct SPIDriver SPIDriver;
+
+/**
+ * @brief SPI notification callback type.
+ *
+ * @param[in] spip pointer to the @p SPIDriver object triggering the
+ * callback
+ */
+typedef void (*spicallback_t)(SPIDriver *spip);
+
+/**
* @brief Driver configuration structure.
*/
typedef struct {
/**
+ * @brief Operation complete callback or @p NULL.
+ * @note In order to use synchronous functions this field must be set to
+ * @p NULL, callbacks and synchronous operations are mutually
+ * exclusive.
+ */
+ spicallback_t spc_endcb;
+ /* End of the mandatory fields.*/
+ /**
* @brief The chip select line port.
*/
ioportid_t spc_ssport;
@@ -76,10 +137,6 @@ typedef struct { */
uint16_t spc_sspad;
/**
- * @brief SPI Mode Register initialization data.
- */
- uint32_t spc_mr;
- /**
* @brief SPI Chip Select Register initialization data.
*/
uint32_t spc_csr;
@@ -88,11 +145,21 @@ typedef struct { /**
* @brief Structure representing a SPI driver.
*/
-typedef struct {
+struct SPIDriver {
/**
* @brief Driver state.
*/
spistate_t spd_state;
+ /**
+ * @brief Current configuration data.
+ */
+ const SPIConfig *spd_config;
+#if SPI_USE_WAIT || defined(__DOXYGEN__)
+ /**
+ * @brief Waiting thread.
+ */
+ Thread *spd_thread;
+#endif /* SPI_USE_WAIT */
#if SPI_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__)
#if CH_USE_MUTEXES || defined(__DOXYGEN__)
/**
@@ -103,12 +170,15 @@ typedef struct { Semaphore spd_semaphore;
#endif
#endif /* SPI_USE_MUTUAL_EXCLUSION */
+#if defined(SPI_DRIVER_EXT_FIELDS)
+ SPI_DRIVER_EXT_FIELDS
+#endif
+ /* End of the mandatory fields.*/
/**
- * @brief Current configuration data.
+ * @brief Pointer to the SPIx registers block.
*/
- const SPIConfig *spd_config;
- /* End of the mandatory fields.*/
-} SPIDriver;
+ AT91PS_SPI spd_spi;
+};
/*===========================================================================*/
/* Driver macros. */
@@ -118,8 +188,12 @@ typedef struct { /* External declarations. */
/*===========================================================================*/
-#if USE_AT91SAM7_SPI && !defined(__DOXYGEN__)
-extern SPIDriver SPID;
+#if AT91SAM7_SPI_USE_SPI0 && !defined(__DOXYGEN__)
+extern SPIDriver SPID1;
+#endif
+
+#if AT91SAM7_SPI_USE_SPI1 && !defined(__DOXYGEN__)
+extern SPIDriver SPID2;
#endif
#ifdef __cplusplus
diff --git a/os/hal/platforms/STM32/spi_lld.h b/os/hal/platforms/STM32/spi_lld.h index 5da92d1f7..e08a1bb64 100644 --- a/os/hal/platforms/STM32/spi_lld.h +++ b/os/hal/platforms/STM32/spi_lld.h @@ -244,7 +244,7 @@ struct SPIDriver{ */
stm32_dma_channel_t *spd_dmatx;
/**
- * @brief DMA priority bit mask.\
+ * @brief DMA priority bit mask.
*/
uint32_t spd_dmaccr;
};
|