diff --git a/boards/cc2538dk/include/periph_conf.h b/boards/cc2538dk/include/periph_conf.h index 098df406f4d72d4c16cca47ddfe589b1b94572a6..ecce1b51f3d9730a5611f5805abac0d3f01268cf 100644 --- a/boards/cc2538dk/include/periph_conf.h +++ b/boards/cc2538dk/include/periph_conf.h @@ -103,11 +103,11 @@ static const i2c_conf_t i2c_config[] = { */ static const spi_conf_t spi_config[] = { { - .dev = SSI0, - .mosi_pin = GPIO_PA4, - .miso_pin = GPIO_PA5, - .sck_pin = GPIO_PA2, - .cs_pin = GPIO_PD0 + .num = 0, + .mosi_pin = GPIO_PIN(0, 4), + .miso_pin = GPIO_PIN(0, 5), + .sck_pin = GPIO_PIN(0, 2), + .cs_pin = GPIO_PIN(3, 0) } }; diff --git a/boards/openmote-b/include/periph_conf.h b/boards/openmote-b/include/periph_conf.h index ec5a11bcf717a89b816e71431e9792b75ecc86d0..cadfc6b8aeac78c0d45dfb8612a5b3a3e70a8b3b 100644 --- a/boards/openmote-b/include/periph_conf.h +++ b/boards/openmote-b/include/periph_conf.h @@ -130,11 +130,11 @@ static const i2c_conf_t i2c_config[] = { */ static const spi_conf_t spi_config[] = { { - .dev = SSI0, - .mosi_pin = GPIO_PA5, - .miso_pin = GPIO_PA4, - .sck_pin = GPIO_PA2, - .cs_pin = GPIO_PA3, + .num = 0, + .mosi_pin = GPIO_PIN(0, 5), + .miso_pin = GPIO_PIN(0, 4), + .sck_pin = GPIO_PIN(0, 2), + .cs_pin = GPIO_PIN(0, 3) }, }; diff --git a/boards/openmote-cc2538/include/periph_conf.h b/boards/openmote-cc2538/include/periph_conf.h index 2db19aae76ee47f4e5bc985409e739cecde1594e..8cd35e4d50a0baa579c1fa1e11a606d122126d1a 100644 --- a/boards/openmote-cc2538/include/periph_conf.h +++ b/boards/openmote-cc2538/include/periph_conf.h @@ -126,11 +126,11 @@ static const i2c_conf_t i2c_config[] = { */ static const spi_conf_t spi_config[] = { { - .dev = SSI0, - .mosi_pin = GPIO_PA5, - .miso_pin = GPIO_PA4, - .sck_pin = GPIO_PA2, - .cs_pin = GPIO_PA3, + .num = 0, + .mosi_pin = GPIO_PIN(0, 5), + .miso_pin = GPIO_PIN(0, 4), + .sck_pin = GPIO_PIN(0, 2), + .cs_pin = GPIO_PIN(0, 3) }, }; diff --git a/boards/remote-pa/include/periph_conf.h b/boards/remote-pa/include/periph_conf.h index a21e022c7c94e8617d437f3e7e86f6944031ca84..e5049f9221d8914b371f98d3c9829bbc1dff024d 100644 --- a/boards/remote-pa/include/periph_conf.h +++ b/boards/remote-pa/include/periph_conf.h @@ -51,17 +51,17 @@ static const i2c_conf_t i2c_config[] = { */ static const spi_conf_t spi_config[] = { { - .dev = SSI0, - .mosi_pin = GPIO_PD0, - .miso_pin = GPIO_PC4, - .sck_pin = GPIO_PD1, - .cs_pin = GPIO_PD3 + .num = 0, + .mosi_pin = GPIO_PIN(3, 0), + .miso_pin = GPIO_PIN(2, 4), + .sck_pin = GPIO_PIN(3, 1), + .cs_pin = GPIO_PIN(3, 3) }, { - .dev = SSI1, - .mosi_pin = GPIO_PC7, - .miso_pin = GPIO_PA4, - .sck_pin = GPIO_PB5, + .num = 1, + .mosi_pin = GPIO_PIN(2, 7), + .miso_pin = GPIO_PIN(0, 4), + .sck_pin = GPIO_PIN(1 ,5), .cs_pin = GPIO_UNDEF } }; diff --git a/boards/remote-reva/include/periph_conf.h b/boards/remote-reva/include/periph_conf.h index c2d713d2d91c95891d791612dcaf19ee38df6892..e2044e77a15e03c07b4a94527bdd4511f83646d7 100644 --- a/boards/remote-reva/include/periph_conf.h +++ b/boards/remote-reva/include/periph_conf.h @@ -51,18 +51,18 @@ static const i2c_conf_t i2c_config[] = { */ static const spi_conf_t spi_config[] = { { - .dev = SSI0, - .mosi_pin = GPIO_PB1, - .miso_pin = GPIO_PB3, - .sck_pin = GPIO_PB2, - .cs_pin = GPIO_PB5 + .num = 0, + .mosi_pin = GPIO_PIN(1, 1), + .miso_pin = GPIO_PIN(1, 3), + .sck_pin = GPIO_PIN(1, 2), + .cs_pin = GPIO_PIN(1, 5) }, { - .dev = SSI1, - .mosi_pin = GPIO_PC5, - .miso_pin = GPIO_PC6, - .sck_pin = GPIO_PC4, - .cs_pin = GPIO_PA7 + .num = 1, + .mosi_pin = GPIO_PIN(2, 5), + .miso_pin = GPIO_PIN(2, 6), + .sck_pin = GPIO_PIN(2, 4), + .cs_pin = GPIO_PIN(0, 7) } }; diff --git a/boards/remote-revb/include/periph_conf.h b/boards/remote-revb/include/periph_conf.h index 8b7322a3fa67741135604667c809f4e0919db2e5..14139802b5755f04f99769818ee872b718ec6358 100644 --- a/boards/remote-revb/include/periph_conf.h +++ b/boards/remote-revb/include/periph_conf.h @@ -54,18 +54,18 @@ static const i2c_conf_t i2c_config[] = { */ static const spi_conf_t spi_config[] = { { - .dev = SSI0, - .mosi_pin = GPIO_PB1, - .miso_pin = GPIO_PB3, - .sck_pin = GPIO_PB2, - .cs_pin = GPIO_PB5 + .num = 0, + .mosi_pin = GPIO_PIN(1, 1), + .miso_pin = GPIO_PIN(1, 3), + .sck_pin = GPIO_PIN(1, 2), + .cs_pin = GPIO_PIN(1, 5) }, { - .dev = SSI1, - .mosi_pin = GPIO_PC5, - .miso_pin = GPIO_PC6, - .sck_pin = GPIO_PC4, - .cs_pin = GPIO_PA7 + .num = 1, + .mosi_pin = GPIO_PIN(2, 5), + .miso_pin = GPIO_PIN(2, 6), + .sck_pin = GPIO_PIN(2, 4), + .cs_pin = GPIO_PIN(0, 7) } }; #define SPI_NUMOF (sizeof(spi_config) / sizeof(spi_config[0])) diff --git a/cpu/cc2538/include/cc2538_ssi.h b/cpu/cc2538/include/cc2538_ssi.h index 5fbdc004dbc7c2eabb1c05b00133382ca74ac84a..8efd0f3ba68fca2f25131d880888a971662437fa 100644 --- a/cpu/cc2538/include/cc2538_ssi.h +++ b/cpu/cc2538/include/cc2538_ssi.h @@ -14,6 +14,7 @@ * @brief CC2538 SSI interface * * @author Ian Martin <ian@locicontrols.com> + * @author Sebastian Meiling <s@mlng.net> */ #ifndef CC2538_SSI_H @@ -29,92 +30,31 @@ extern "C" { * @brief SSI component registers */ typedef struct { - union { - cc2538_reg_t CR0; /**< SSI Control Register 0 */ - struct { - cc2538_reg_t DSS : 4; /**< SSI data size select */ - cc2538_reg_t FRF : 2; /**< SSI frame format select */ - cc2538_reg_t SPO : 1; /**< SSI serial clock polarity */ - cc2538_reg_t SPH : 1; /**< SSI serial clock phase */ - cc2538_reg_t SCR : 8; /**< SSI serial clock rate */ - cc2538_reg_t RESERVED : 16; /**< Reserved bits */ - } CR0bits; - }; - - union { - cc2538_reg_t CR1; /**< SSI Control Register 1 */ - struct { - cc2538_reg_t LBM : 1; /**< SSI loop-back mode */ - cc2538_reg_t SSE : 1; /**< SSI synchronous serial port enable */ - cc2538_reg_t MS : 1; /**< SSI master and slave select */ - cc2538_reg_t SOD : 1; /**< SSI slave mode output disable */ - cc2538_reg_t RESERVED : 28; /**< Reserved bits */ - } CR1bits; - }; - - cc2538_reg_t DR; /**< SSI Data register */ - - union { - cc2538_reg_t SR; /**< SSI FIFO/busy Status Register */ - struct { - cc2538_reg_t TFE : 1; /**< SSI transmit FIFO empty */ - cc2538_reg_t TNF : 1; /**< SSI transmit FIFO not full */ - cc2538_reg_t RNE : 1; /**< SSI receive FIFO not empty */ - cc2538_reg_t RFF : 1; /**< SSI receive FIFO full */ - cc2538_reg_t BSY : 1; /**< SSI busy bit */ - cc2538_reg_t RESERVED : 27; /**< Reserved bits */ - } SRbits; - }; - cc2538_reg_t CPSR; /**< SSI Clock Register */ - cc2538_reg_t IM; /**< SSI Interrupt Mask register */ - cc2538_reg_t RIS; /**< SSI Raw Interrupt Status register */ - cc2538_reg_t MIS; /**< SSI Masked Interrupt Status register */ - cc2538_reg_t ICR; /**< SSI Interrupt Clear Register */ - cc2538_reg_t DMACTL; /**< SSI uDMA Control Register. */ - cc2538_reg_t CC; /**< SSI clock configuration */ + cc2538_reg_t CR0; /**< SSI Control Register 0 */ + cc2538_reg_t CR1; /**< SSI Control Register 1 */ + cc2538_reg_t DR; /**< SSI Data register */ + cc2538_reg_t SR; /**< SSI FIFO/busy Status Register */ + cc2538_reg_t CPSR; /**< SSI Clock Register */ + cc2538_reg_t IM; /**< SSI Interrupt Mask register */ + cc2538_reg_t RIS; /**< SSI Raw Interrupt Status register */ + cc2538_reg_t MIS; /**< SSI Masked Interrupt Status register */ + cc2538_reg_t ICR; /**< SSI Interrupt Clear Register */ + cc2538_reg_t DMACTL; /**< SSI uDMA Control Register. */ + cc2538_reg_t CC; /**< SSI clock configuration */ } cc2538_ssi_t; -#define SSI0 ( (cc2538_ssi_t*)0x40008000 ) /**< SSI0 Instance */ -#define SSI1 ( (cc2538_ssi_t*)0x40009000 ) /**< SSI1 Instance */ - -/** - * @brief Define CR0 register bitfields - * @{ - */ -#define SSI_CR0_DSS(x) ((x - 1) << 0) -#define SSI_CR0_SPO (1 << 6) -#define SSI_CR0_SPH (1 << 7) -/** @} */ - -/** - * @brief Define CR1 register bitfields - * @{ - */ -#define SSI_CR1_LBM (1 << 0) -#define SSI_CR1_SSE (1 << 1) -#define SSI_CR1_MS (1 << 2) -#define SSI_CR1_SOD (1 << 3) -/** @} */ - /** - * @brief Define SR register bitfields - * @{ + * @brief Set CR0 data size (bits) */ -#define SSI_SR_TFE (1 << 0) -#define SSI_SR_TNF (1 << 1) -#define SSI_SR_RNE (1 << 2) -#define SSI_SR_RFF (1 << 3) -#define SSI_SR_BSY (1 << 4) -/** @} */ +#define SSI_CR0_DSS(x) (x - 1) /** * @brief Define CC register bitfields * @{ */ -#define SSI_SS_PIOSC (1 << 0) -#define SSI_SS_DSEN (1 << 2) -#define SSI_SS_SYSDIV (0) -#define SSI_SS_IODIV (SSI_SS_PIOSC) +#define SSI_CC_CS_SYSDIV (0x0) +#define SSI_CC_CS_IODIV (0x1) +#define SSI_CC_CS_DSEN (0x4) /** @} */ #ifdef __cplusplus diff --git a/cpu/cc2538/include/periph_cpu.h b/cpu/cc2538/include/periph_cpu.h index 05e819065ae44ca1541e3c585acaa57625cabc39..807727e6dd91df0025e8e29d5633738c5c304762 100644 --- a/cpu/cc2538/include/periph_cpu.h +++ b/cpu/cc2538/include/periph_cpu.h @@ -25,6 +25,7 @@ #include <stdio.h> #include "cpu.h" +#include "vendor/hw_ssi.h" #ifdef __cplusplus extern "C" { @@ -221,7 +222,7 @@ static const spi_clk_conf_t spi_clk_config[] = { * @{ */ typedef struct { - cc2538_ssi_t *dev; /**< SSI device */ + uint8_t num; /**< number of SSI device, i.e. 0 or 1 */ gpio_t mosi_pin; /**< pin used for MOSI */ gpio_t miso_pin; /**< pin used for MISO */ gpio_t sck_pin; /**< pin used for SCK */ diff --git a/cpu/cc2538/periph/spi.c b/cpu/cc2538/periph/spi.c index af1b08a259e7d8fe8468d9c8c9a5a5f1ee55af36..0a44df94055aac7bcac791e2055364879c45154d 100644 --- a/cpu/cc2538/periph/spi.c +++ b/cpu/cc2538/periph/spi.c @@ -21,6 +21,9 @@ * @} */ +#include "vendor/hw_memmap.h" +#include "vendor/hw_ssi.h" + #include "cpu.h" #include "mutex.h" #include "assert.h" @@ -33,33 +36,36 @@ static mutex_t locks[SPI_NUMOF]; static inline cc2538_ssi_t *dev(spi_t bus) { - return spi_config[bus].dev; + /* .num is either 0 or 1, return respective base address */ + return (spi_config[bus].num) ? (cc2538_ssi_t *)SSI1_BASE : (cc2538_ssi_t *)SSI0_BASE; } static inline void poweron(spi_t bus) { - SYS_CTRL_RCGCSSI |= (1 << bus); - SYS_CTRL_SCGCSSI |= (1 << bus); - SYS_CTRL_DCGCSSI |= (1 << bus); + SYS_CTRL_RCGCSSI |= (1 << spi_config[bus].num); + SYS_CTRL_SCGCSSI |= (1 << spi_config[bus].num); + SYS_CTRL_DCGCSSI |= (1 << spi_config[bus].num); } static inline void poweroff(spi_t bus) { - SYS_CTRL_RCGCSSI &= ~(1 << bus); - SYS_CTRL_SCGCSSI &= ~(1 << bus); - SYS_CTRL_DCGCSSI &= ~(1 << bus); + SYS_CTRL_RCGCSSI &= ~(1 << spi_config[bus].num); + SYS_CTRL_SCGCSSI &= ~(1 << spi_config[bus].num); + SYS_CTRL_DCGCSSI &= ~(1 << spi_config[bus].num); } void spi_init(spi_t bus) { - assert(bus <= SPI_NUMOF); + assert(bus < SPI_NUMOF); + /* init mutex for given bus */ + mutex_init(&locks[bus]); /* temporarily power on the device */ poweron(bus); /* configure device to be a master and disable SSI operation mode */ dev(bus)->CR1 = 0; /* configure system clock as SSI clock source */ - dev(bus)->CC = SSI_SS_IODIV; + dev(bus)->CC = SSI_CC_CS_IODIV; /* and power off the bus again */ poweroff(bus); @@ -69,33 +75,16 @@ void spi_init(spi_t bus) void spi_init_pins(spi_t bus) { - switch ((uintptr_t)spi_config[bus].dev) { - case (uintptr_t)SSI0: - IOC_PXX_SEL[spi_config[bus].mosi_pin] = SSI0_TXD; - IOC_PXX_SEL[spi_config[bus].sck_pin ] = SSI0_CLK_OUT; - IOC_PXX_SEL[spi_config[bus].cs_pin ] = SSI0_FSS_OUT; - - IOC_SSIRXD_SSI0 = spi_config[bus].miso_pin; - break; - - case (uintptr_t)SSI1: - IOC_PXX_SEL[spi_config[bus].mosi_pin] = SSI1_TXD; - IOC_PXX_SEL[spi_config[bus].sck_pin ] = SSI1_CLK_OUT; - IOC_PXX_SEL[spi_config[bus].cs_pin ] = SSI1_FSS_OUT; - - IOC_SSIRXD_SSI1 = spi_config[bus].miso_pin; - break; - } - - IOC_PXX_OVER[spi_config[bus].mosi_pin] = IOC_OVERRIDE_OE; - IOC_PXX_OVER[spi_config[bus].miso_pin] = IOC_OVERRIDE_DIS; - IOC_PXX_OVER[spi_config[bus].sck_pin ] = IOC_OVERRIDE_OE; - IOC_PXX_OVER[spi_config[bus].cs_pin ] = IOC_OVERRIDE_OE; - - gpio_hardware_control(spi_config[bus].mosi_pin); - gpio_hardware_control(spi_config[bus].miso_pin); - gpio_hardware_control(spi_config[bus].sck_pin); - gpio_hardware_control(spi_config[bus].cs_pin); + /* select values according to SPI device */ + cc2538_ioc_sel_t txd = spi_config[bus].num ? SSI1_TXD : SSI0_TXD; + cc2538_ioc_sel_t clk = spi_config[bus].num ? SSI1_CLK_OUT : SSI0_CLK_OUT; + cc2538_ioc_sel_t fss = spi_config[bus].num ? SSI1_FSS_OUT : SSI0_FSS_OUT; + cc2538_ioc_pin_t rxd = spi_config[bus].num ? SSI1_RXD : SSI0_RXD; + /* init pin functions and multiplexing */ + gpio_init_mux(spi_config[bus].mosi_pin, OVERRIDE_ENABLE, txd, GPIO_MUX_NONE); + gpio_init_mux(spi_config[bus].sck_pin, OVERRIDE_ENABLE, clk, GPIO_MUX_NONE); + gpio_init_mux(spi_config[bus].cs_pin, OVERRIDE_ENABLE, fss, GPIO_MUX_NONE); + gpio_init_mux(spi_config[bus].miso_pin, OVERRIDE_DISABLE, GPIO_MUX_NONE, rxd); } int spi_acquire(spi_t bus, spi_cs_t cs, spi_mode_t mode, spi_clk_t clk) @@ -167,8 +156,8 @@ void spi_transfer_bytes(spi_t bus, spi_cs_t cs, bool cont, while (!(dev(bus)->SR & SSI_SR_RNE)){} in_buf[i] = dev(bus)->DR; } - /* wait until no more busy */ - while ((dev(bus)->SR & SSI_SR_BSY)) {} + /* wait until no more busy */ + while ((dev(bus)->SR & SSI_SR_BSY)) {} } if ((!cont) && (cs != SPI_CS_UNDEF)) {