aboutsummaryrefslogtreecommitdiffstats
path: root/src/lpc176x
diff options
context:
space:
mode:
authorakatik <aka@pxe.ru>2020-01-15 07:06:29 +0400
committerKevinOConnor <kevin@koconnor.net>2020-01-14 22:06:29 -0500
commitb3c3b61387dcced140d5669bfb100c22afceeac6 (patch)
tree50948b4e29a03691f471038c9a7364cdc870a336 /src/lpc176x
parentb70416167b9abdcafacea81e9ef92c509360f735 (diff)
downloadkutter-b3c3b61387dcced140d5669bfb100c22afceeac6.tar.gz
kutter-b3c3b61387dcced140d5669bfb100c22afceeac6.tar.xz
kutter-b3c3b61387dcced140d5669bfb100c22afceeac6.zip
lpc176x: Add support for ssp1 (#2393)
Signed-off-by: Andrey Kovalev <aka@pxe.ru>
Diffstat (limited to 'src/lpc176x')
-rw-r--r--src/lpc176x/gpio.h1
-rw-r--r--src/lpc176x/internal.h1
-rw-r--r--src/lpc176x/spi.c59
3 files changed, 39 insertions, 22 deletions
diff --git a/src/lpc176x/gpio.h b/src/lpc176x/gpio.h
index 30f8ab13..97eb909b 100644
--- a/src/lpc176x/gpio.h
+++ b/src/lpc176x/gpio.h
@@ -30,6 +30,7 @@ uint16_t gpio_adc_read(struct gpio_adc g);
void gpio_adc_cancel_sample(struct gpio_adc g);
struct spi_config {
+ void *spi;
uint32_t cr0, cpsr;
};
struct spi_config spi_setup(uint32_t bus, uint8_t mode, uint32_t rate);
diff --git a/src/lpc176x/internal.h b/src/lpc176x/internal.h
index 5dcf99a4..2a1d0150 100644
--- a/src/lpc176x/internal.h
+++ b/src/lpc176x/internal.h
@@ -10,6 +10,7 @@
#define PCLK_TIMER0 1
#define PCLK_UART0 3
+#define PCLK_SSP1 10
#define PCLK_ADC 12
#define PCLK_I2C1 19
#define PCLK_SSP0 21
diff --git a/src/lpc176x/spi.c b/src/lpc176x/spi.c
index c297fb01..28bce200 100644
--- a/src/lpc176x/spi.c
+++ b/src/lpc176x/spi.c
@@ -9,42 +9,55 @@
#include "internal.h" // gpio_peripheral
#include "sched.h" // sched_shutdown
+struct spi_info {
+ LPC_SSP_TypeDef *spi;
+ uint8_t miso_pin, mosi_pin, sck_pin, pclk;
+};
+
DECL_ENUMERATION("spi_bus", "ssp0", 0);
DECL_CONSTANT_STR("BUS_PINS_ssp0", "P0.17,P0.18,P0.15");
+DECL_ENUMERATION("spi_bus", "ssp1", 1);
+DECL_CONSTANT_STR("BUS_PINS_ssp1", "P0.8,P0.9,P0.7");
+
+static const struct spi_info spi_bus[] = {
+ { LPC_SSP0, GPIO(0, 17), GPIO(0, 18), GPIO(0, 15), PCLK_SSP0 },
+ { LPC_SSP1, GPIO(0, 8), GPIO(0, 9), GPIO(0, 7), PCLK_SSP1 },
+};
static void
-spi_init(void)
+spi_init(uint32_t bus)
{
- static int have_run_init;
- if (have_run_init)
+ static int have_run_init[ARRAY_SIZE(spi_bus)];
+ if (have_run_init[bus])
return;
- have_run_init = 1;
+ have_run_init[bus] = 1;
// Configure MISO0, MOSI0, SCK0 pins
- gpio_peripheral(GPIO(0, 17), 2, 0);
- gpio_peripheral(GPIO(0, 18), 2, 0);
- gpio_peripheral(GPIO(0, 15), 2, 0);
+ gpio_peripheral(spi_bus[bus].miso_pin, 2, 0);
+ gpio_peripheral(spi_bus[bus].mosi_pin, 2, 0);
+ gpio_peripheral(spi_bus[bus].sck_pin, 2, 0);
// Setup clock
- enable_pclock(PCLK_SSP0);
+ enable_pclock(spi_bus[bus].pclk);
// Set initial registers
- LPC_SSP0->CR0 = 0x07;
- LPC_SSP0->CPSR = 254;
- LPC_SSP0->CR1 = 1<<1;
+ LPC_SSP_TypeDef *spi = spi_bus[bus].spi;
+ spi->CR0 = 0x07;
+ spi->CPSR = 254;
+ spi->CR1 = 1<<1;
}
struct spi_config
spi_setup(uint32_t bus, uint8_t mode, uint32_t rate)
{
- if (bus)
+ if (bus >= ARRAY_SIZE(spi_bus))
shutdown("Invalid spi_setup parameters");
// Make sure bus is enabled
- spi_init();
+ spi_init(bus);
// Setup clock rate and mode
- struct spi_config res = {0, 0};
+ struct spi_config res = {spi_bus[bus].spi, 0, 0};
uint32_t pclk = SystemCoreClock;
uint32_t div = DIV_ROUND_UP(pclk/2, rate) << 1;
res.cpsr = div < 2 ? 2 : (div > 254 ? 254 : div);
@@ -56,31 +69,33 @@ spi_setup(uint32_t bus, uint8_t mode, uint32_t rate)
void
spi_prepare(struct spi_config config)
{
- LPC_SSP0->CR0 = config.cr0;
- LPC_SSP0->CPSR = config.cpsr;
+ LPC_SSP_TypeDef *spi = config.spi;
+ spi->CR0 = config.cr0;
+ spi->CPSR = config.cpsr;
}
void
spi_transfer(struct spi_config config, uint8_t receive_data
, uint8_t len, uint8_t *data)
{
+ LPC_SSP_TypeDef *spi = config.spi;
if (receive_data) {
while (len--) {
- LPC_SSP0->DR = *data;
+ spi->DR = *data;
// wait for read data to be ready
- while (!(LPC_SSP0->SR & (1<<2)))
+ while (!(spi->SR & (1<<2)))
;
// get data
- *data++ = LPC_SSP0->DR;
+ *data++ = spi->DR;
}
} else {
while (len--) {
- LPC_SSP0->DR = *data++;
+ spi->DR = *data++;
// wait for read data to be ready
- while (!(LPC_SSP0->SR & (1<<2)))
+ while (!(spi->SR & (1<<2)))
;
// read data (to clear receive fifo)
- LPC_SSP0->DR;
+ spi->DR;
}
}
}