diff options
author | Florian Heilmann <Florian.Heilmann@gmx.net> | 2019-01-13 02:14:50 +0100 |
---|---|---|
committer | KevinOConnor <kevin@koconnor.net> | 2019-01-12 20:14:50 -0500 |
commit | 6256599a6dfc0c52a3c5e019c470d4cc46feeb82 (patch) | |
tree | 4453913a6178a06e3f58dbfc530e6d65291473d3 /src/sam3/spi.c | |
parent | 432e6c490a229f71d608ec0391773ab7f90534d1 (diff) | |
download | kutter-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.c | 285 |
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); -} |