1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

cpu/cc2538: adapt periph/spi to gpio API

Rework SPI periph driver to use proper RIOT GPIO API functions.
    Also cleanup header files by using vendor defines and remove
    obsolete code. Further, adapt board config accordingly.
This commit is contained in:
smlng 2018-08-03 16:05:53 +02:00
parent d8e2611ed9
commit e246c19fe1
9 changed files with 90 additions and 160 deletions

View File

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

View File

@ -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)
},
};

View File

@ -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)
},
};

View File

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

View File

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

View File

@ -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]))

View File

@ -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
* @{
* @brief Set CR0 data size (bits)
*/
#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
* @{
*/
#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

View File

@ -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 */

View File

@ -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)) {