Skip to content

Commit

Permalink
fixup! cpu/rpx0xx: add spi functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
fengelhardt committed Apr 28, 2023
1 parent 51e5866 commit 3aa3344
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 30 deletions.
19 changes: 19 additions & 0 deletions cpu/rpx0xx/include/periph_cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -731,6 +731,25 @@ void rosc_stop(void);

/** @} */

/**
* @brief Override SPI clock speed values
* @{
*/
#define HAVE_SPI_CLK_T
enum {
SPI_CLK_100KHZ = KHZ(100), /**< drive the SPI bus with 100KHz */
SPI_CLK_400KHZ = KHZ(400), /**< drive the SPI bus with 400KHz */
SPI_CLK_1MHZ = MHZ(1), /**< drive the SPI bus with 1MHz */
SPI_CLK_5MHZ = MHZ(5), /**< drive the SPI bus with 5MHz */
SPI_CLK_10MHZ = MHZ(10), /**< drive the SPI bus with 10MHz */
};

/**
* @brief SPI clock type
*/
typedef uint32_t spi_clk_t;
/** @} */

/**
* @brief Configuration details for an SPI interface needed by the RPX0XX peripheral
*/
Expand Down
49 changes: 19 additions & 30 deletions cpu/rpx0xx/periph/spi.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,19 +43,19 @@ typedef struct {
} _pl022_clk_t;
static _pl022_clk_t pl022_clk[SPI_NUMOF];

gpio_t spi_pin_clk(spi_t spi)
gpio_t spi_pin_clk(spi_t spi)
{
assert((unsigned)spi < SPI_NUMOF);
return spi_config[spi].clk_pin;
}

gpio_t spi_pin_miso(spi_t spi)
gpio_t spi_pin_miso(spi_t spi)
{
assert((unsigned)spi < SPI_NUMOF);
return spi_config[spi].miso_pin;
}

gpio_t spi_pin_mosi(spi_t spi)
gpio_t spi_pin_mosi(spi_t spi)
{
assert((unsigned)spi < SPI_NUMOF);
return spi_config[spi].mosi_pin;
Expand Down Expand Up @@ -99,19 +99,20 @@ void spi_init_pins(spi_t spi)
assert((unsigned)spi < SPI_NUMOF);

const gpio_pad_ctrl_t mosi_pad_config = {
/* SPI should typically draw less than 2 mA */
.drive_strength = DRIVE_STRENGTH_2MA,
};
const gpio_io_ctrl_t mosi_io_config = {
.function_select = FUNCTION_SELECT_SPI,
};
const gpio_pad_ctrl_t clk_pad_config = {
/* SPI should typically draw less than 2 mA */
.drive_strength = DRIVE_STRENGTH_2MA,
};
const gpio_io_ctrl_t clk_io_config = {
.function_select = FUNCTION_SELECT_SPI,
};
const gpio_pad_ctrl_t miso_pad_config = {
.pull_up_enable = 1,
.input_enable = 1,
.schmitt_trig_enable = 1,
};
Expand All @@ -131,12 +132,18 @@ void spi_init_pins(spi_t spi)
gpio_set_pad_config(spi_config[spi].miso_pin, miso_pad_config);
gpio_set_io_config(spi_config[spi].miso_pin, miso_io_config);
}

/* allow access to the bus */
mutex_unlock(&locks[spi]);
}

void spi_deinit_pins(spi_t spi)
{
DEBUG("[rpx0xx] Call spi_deinit_pins(spi=%" PRIdFAST8 ")\n", spi);

/* lock mutex to block usage of the SPI bus */
mutex_lock(&locks[spi]);

assert((unsigned)spi < SPI_NUMOF);

if (gpio_is_valid(spi_config[spi].mosi_pin)) {
Expand Down Expand Up @@ -208,29 +215,7 @@ static inline void _check_best_clk_result(uint16_t target_dvsr,

static void _calc_pl022_clk(_pl022_clk_t *pl022_clk, spi_clk_t clk)
{
uint32_t clk_hz;

switch (clk) {
case SPI_CLK_100KHZ:
clk_hz = KHZ(100);
break;
case SPI_CLK_400KHZ:
clk_hz = KHZ(400);
break;
case SPI_CLK_1MHZ:
clk_hz = MHZ(1);
break;
case SPI_CLK_5MHZ:
clk_hz = MHZ(5);
break;
case SPI_CLK_10MHZ:
clk_hz = MHZ(10);
break;
default:
clk_hz = KHZ(100);
break;
}
uint16_t dvsr = CLOCK_PERIPH / clk_hz;
uint16_t dvsr = CLOCK_PERIPH / clk;
/* The divisor must be split into two 8-bit divisors, cpsdvsr and scr,
* dvsr = cpsdvsr*scr. cpsdvsr must be an even number greater than 0. */
uint8_t cpsdvsr = 2, best_cpsdvsr = 2;
Expand Down Expand Up @@ -269,10 +254,12 @@ static void _calc_pl022_clk(_pl022_clk_t *pl022_clk, spi_clk_t clk)

void spi_acquire(spi_t spi, spi_cs_t cs, spi_mode_t mode, spi_clk_t clk)
{
DEBUG("[rpx0xx] Call spi_acquire(spi=%" PRIdFAST8 ", cs=%" PRIu32
", mode=%" PRIu16 ", clk=%" PRIu16 ")\n", spi, cs, mode, clk);
DEBUG("[rpx0xx] Call spi_acquire(spi=%" PRIuFAST8 ", cs=%" PRIu32
", mode=%" PRIu16 ", clk=%" PRIu32 ")\n", spi, cs, mode, clk);

assert((unsigned)spi < SPI_NUMOF);
assert(clk == SPI_CLK_100KHZ || clk == SPI_CLK_10MHZ || clk == SPI_CLK_1MHZ
|| clk == SPI_CLK_400KHZ || clk == SPI_CLK_5MHZ);
(void)cs;

/* lock bus */
Expand All @@ -288,6 +275,7 @@ void spi_acquire(spi_t spi, spi_cs_t cs, spi_mode_t mode, spi_clk_t clk)
/* uncomment the following line for debug loopback mode */
/* io_reg_atomic_set(&dev->SSPCR1, SPI0_SSPCR1_LBM_Msk); */

/* set SPI mode */
switch (mode) {
case SPI_MODE_0:
io_reg_atomic_clear(&dev->SSPCR0, SPI0_SSPCR0_SPO_Msk);
Expand All @@ -307,6 +295,7 @@ void spi_acquire(spi_t spi, spi_cs_t cs, spi_mode_t mode, spi_clk_t clk)
break;
}

/* set clock speed */
if (clk != pl022_clk[spi].clk) {
_calc_pl022_clk(&pl022_clk[spi], clk);
}
Expand All @@ -327,9 +316,9 @@ void spi_release(spi_t spi)

assert((unsigned)spi < SPI_NUMOF);

/* disable SPI */
SPI0_Type *dev = spi_config[spi].dev;

/* disable SPI */
io_reg_atomic_clear(&dev->SSPCR1, SPI0_SSPCR1_SSE_Msk);

_poweroff(spi);
Expand Down

0 comments on commit 3aa3344

Please sign in to comment.