aboutsummaryrefslogtreecommitdiffstats
path: root/src/sam3/spi.c
diff options
context:
space:
mode:
authorFlorian Heilmann <Florian.Heilmann@gmx.net>2019-01-13 02:14:50 +0100
committerKevinOConnor <kevin@koconnor.net>2019-01-12 20:14:50 -0500
commit6256599a6dfc0c52a3c5e019c470d4cc46feeb82 (patch)
tree4453913a6178a06e3f58dbfc530e6d65291473d3 /src/sam3/spi.c
parent432e6c490a229f71d608ec0391773ab7f90534d1 (diff)
downloadkutter-6256599a6dfc0c52a3c5e019c470d4cc46feeb82.tar.gz
kutter-6256599a6dfc0c52a3c5e019c470d4cc46feeb82.tar.xz
kutter-6256599a6dfc0c52a3c5e019c470d4cc46feeb82.zip
src: Rename source folders for atsam and atsamd architectures
Signed-off-by: Florian Heilmann <Florian.Heilmann@gmx.net>
Diffstat (limited to 'src/sam3/spi.c')
-rw-r--r--src/sam3/spi.c285
1 files changed, 0 insertions, 285 deletions
diff --git a/src/sam3/spi.c b/src/sam3/spi.c
deleted file mode 100644
index 5f79a02c..00000000
--- a/src/sam3/spi.c
+++ /dev/null
@@ -1,285 +0,0 @@
-// SPI transmissions on sam3
-//
-// Copyright (C) 2018 Petri Honkala <cruwaller@gmail.com>
-// Copyright (C) 2018 Florian Heilmann <Florian.Heilmann@gmx.net>
-// Copyright (C) 2018 Kevin O'Connor <kevin@koconnor.net>
-//
-// This file may be distributed under the terms of the GNU GPLv3 license.
-
-#include "command.h" // shutdown
-#include "gpio.h" // spi_setup
-#include "internal.h" // gpio_peripheral
-#include "sched.h" // sched_shutdown
-
-
-/****************************************************************
- * SPI/USART buses and pins
- ****************************************************************/
-
-struct spi_info {
- void *dev;
- uint32_t dev_id;
- uint8_t miso_pin, mosi_pin, sck_pin, rxtx_periph, sck_periph;
-};
-
-static const struct spi_info spi_bus[] = {
-#if CONFIG_MACH_SAM3X8E
- { SPI0, ID_SPI0, GPIO('A', 25), GPIO('A', 26), GPIO('A', 27), 'A', 'A' },
- { USART0, ID_USART0, GPIO('A', 10), GPIO('A', 11), GPIO('A', 17), 'A', 'B'},
- { USART1, ID_USART1, GPIO('A', 12), GPIO('A', 13), GPIO('A', 16), 'A', 'A'},
- { USART2, ID_USART2, GPIO('B', 21), GPIO('B', 20), GPIO('B', 24), 'A', 'A'},
-#elif CONFIG_MACH_SAM4S8C
- { SPI, ID_SPI, GPIO('A', 12), GPIO('A', 13), GPIO('A', 14), 'A', 'A' },
- { USART0, ID_USART0, GPIO('A', 5), GPIO('A', 6), GPIO('A', 2), 'A', 'B' },
- { USART1, ID_USART1, GPIO('A', 21), GPIO('A', 22), GPIO('A', 23), 'A', 'A'},
-#elif CONFIG_MACH_SAM4E8E
- { USART0, ID_USART0, GPIO('B', 0), GPIO('B', 1), GPIO('B', 13), 'C', 'C' },
- { USART1, ID_USART1, GPIO('A', 21), GPIO('A', 22), GPIO('A', 23), 'A', 'A'},
- { SPI, ID_SPI, GPIO('A', 12), GPIO('A', 13), GPIO('A', 14), 'A', 'A' },
-#endif
-};
-
-static int
-is_spihw(void *dev)
-{
-#if CONFIG_MACH_SAM3X8E
- return dev == SPI0;
-#else
- return dev == SPI;
-#endif
-}
-
-static void
-init_pins(uint32_t bus)
-{
- const struct spi_info *si = &spi_bus[bus];
- gpio_peripheral(si->sck_pin, si->sck_periph, 0);
- gpio_peripheral(si->miso_pin, si->rxtx_periph, 1);
- gpio_peripheral(si->mosi_pin, si->rxtx_periph, 0);
- enable_pclock(si->dev_id);
-}
-
-
-/****************************************************************
- * SPI hardware
- ****************************************************************/
-
-#define CHANNEL 0 // Use same channel for all
-
-static void
-spihw_init(uint32_t bus)
-{
- init_pins(bus);
- Spi *pSpi = spi_bus[bus].dev;
-
- /* Disable SPI */
- pSpi->SPI_CR = SPI_CR_SPIDIS;
- /* Execute a software reset of the SPI twice */
- pSpi->SPI_CR = SPI_CR_SWRST;
- pSpi->SPI_CR = SPI_CR_SWRST;
-
- pSpi->SPI_MR = ( SPI_MR_MSTR | // Set master mode
- SPI_MR_MODFDIS | // Disable fault detection
- SPI_MR_PCS(CHANNEL) // Fixes peripheral select
- );
- pSpi->SPI_IDR = 0xffffffff; // Disable ISRs
-
- /* Clear Chip Select Registers */
- pSpi->SPI_CSR[0] = 0;
- pSpi->SPI_CSR[1] = 0;
- pSpi->SPI_CSR[2] = 0;
- pSpi->SPI_CSR[3] = 0;
-
- /* Set basic channel config */
- pSpi->SPI_CSR[CHANNEL] = 0;
- /* Enable SPI */
- pSpi->SPI_CR = SPI_CR_SPIEN;
-}
-
-static struct spi_config
-spihw_setup(uint32_t bus, uint8_t mode, uint32_t rate)
-{
- // Make sure bus is enabled
- spihw_init(bus);
-
- uint32_t config = 0;
- uint32_t clockDiv;
- if (rate < (CHIP_FREQ_CPU_MAX / 255)) {
- clockDiv = 255;
- } else if (rate >= (CHIP_FREQ_CPU_MAX / 2)) {
- clockDiv = 2;
- } else {
- clockDiv = (CHIP_FREQ_CPU_MAX / (rate + 1)) + 1;
- }
-
- /****** Will be written to SPI_CSRx register ******/
- // CSAAT : Chip Select Active After Transfer
- config = SPI_CSR_CSAAT;
- config |= SPI_CSR_BITS_8_BIT; // TODO: support for SPI_CSR_BITS_16_BIT
- // NOTE: NCPHA is inverted, CPHA normal!!
- switch(mode) {
- case 0:
- config |= SPI_CSR_NCPHA;
- break;
- case 1:
- config |= 0;
- break;
- case 2:
- config |= SPI_CSR_NCPHA;
- config |= SPI_CSR_CPOL;
- break;
- case 3:
- config |= SPI_CSR_CPOL;
- break;
- };
-
- config |= ((clockDiv & 0xffu) << SPI_CSR_SCBR_Pos);
- return (struct spi_config){ .spidev = spi_bus[bus].dev, .cfg = config };
-}
-
-static void
-spihw_prepare(struct spi_config config)
-{
- Spi *pSpi = config.spidev;
- pSpi->SPI_CSR[CHANNEL] = config.cfg;
-}
-
-static void
-spihw_transfer(struct spi_config config, uint8_t receive_data
- , uint8_t len, uint8_t *data)
-{
- Spi *pSpi = config.spidev;
- if (receive_data) {
- while (len--) {
- pSpi->SPI_TDR = *data;
- // wait for receive register
- while (!(pSpi->SPI_SR & SPI_SR_RDRF))
- ;
- // get data
- *data++ = pSpi->SPI_RDR;
- }
- } else {
- while (len--) {
- pSpi->SPI_TDR = *data++;
- // wait for receive register
- while (!(pSpi->SPI_SR & SPI_SR_RDRF))
- ;
- // read data (to clear RDRF)
- pSpi->SPI_RDR;
- }
- }
-}
-
-
-/****************************************************************
- * USART hardware
- ****************************************************************/
-
-static struct spi_config
-usart_setup(uint32_t bus, uint8_t mode, uint32_t rate)
-{
- init_pins(bus);
- Usart *p_usart = spi_bus[bus].dev;
-
- p_usart->US_MR = 0;
- p_usart->US_RTOR = 0;
- p_usart->US_TTGR = 0;
-
- p_usart->US_CR = US_CR_RSTTX | US_CR_RSTRX | US_CR_TXDIS | US_CR_RXDIS;
-
- uint32_t br = DIV_ROUND_UP(CHIP_FREQ_CPU_MAX, rate);
- p_usart->US_BRGR = br << US_BRGR_CD_Pos;
-
- uint32_t reg = US_MR_CHRL_8_BIT |
- US_MR_USART_MODE_SPI_MASTER |
- US_MR_CLKO |
- US_MR_CHMODE_NORMAL;
- switch (mode) {
- case 0:
- reg |= US_MR_CPHA;
- reg &= ~US_MR_CPOL;
- break;
- case 1:
- reg &= ~US_MR_CPHA;
- reg &= ~US_MR_CPOL;
- break;
- case 2:
- reg |= US_MR_CPHA;
- reg |= US_MR_CPOL;
- break;
- case 3:
- reg &= ~US_MR_CPHA;
- reg |= US_MR_CPOL;
- break;
- }
-
- p_usart->US_MR |= reg;
- p_usart->US_CR = US_CR_RXEN | US_CR_TXEN;
- return (struct spi_config){ .spidev=p_usart, .cfg=p_usart->US_MR };
-}
-
-static void
-usart_prepare(struct spi_config config)
-{
-}
-
-static void
-usart_transfer(struct spi_config config, uint8_t receive_data
- , uint8_t len, uint8_t *data)
-{
- Usart *p_usart = config.spidev;
- if (receive_data) {
- for (uint32_t i = 0; i < len; ++i) {
- uint32_t co = (uint32_t)*data & 0x000000FF;
- while(!(p_usart->US_CSR & US_CSR_TXRDY)) {}
- p_usart->US_THR = US_THR_TXCHR(co);
- uint32_t ci = 0;
- while(!(p_usart->US_CSR & US_CSR_RXRDY)) {}
- ci = p_usart->US_RHR & US_RHR_RXCHR_Msk;
- *data++ = (uint8_t)ci;
- }
- } else {
- for (uint32_t i = 0; i < len; ++i) {
- uint32_t co = (uint32_t)*data & 0x000000FF;
- while(!(p_usart->US_CSR & US_CSR_TXRDY)) {}
- p_usart->US_THR = US_THR_TXCHR(co);
- while(!(p_usart->US_CSR & US_CSR_RXRDY)) {}
- (void)(p_usart->US_RHR & US_RHR_RXCHR_Msk);
- (void)*data++;
- }
- }
-}
-
-
-/****************************************************************
- * Interface
- ****************************************************************/
-
-struct spi_config
-spi_setup(uint32_t bus, uint8_t mode, uint32_t rate)
-{
- if (bus >= ARRAY_SIZE(spi_bus))
- shutdown("Invalid spi bus");
- if (is_spihw(spi_bus[bus].dev))
- return spihw_setup(bus, mode, rate);
- return usart_setup(bus, mode, rate);
-}
-
-void
-spi_prepare(struct spi_config config)
-{
- if (is_spihw(config.spidev))
- spihw_prepare(config);
- else
- usart_prepare(config);
-}
-
-void
-spi_transfer(struct spi_config config, uint8_t receive_data
- , uint8_t len, uint8_t *data)
-{
- if (is_spihw(config.spidev))
- spihw_transfer(config, receive_data, len, data);
- else
- usart_transfer(config, receive_data, len, data);
-}