summaryrefslogtreecommitdiff
path: root/src/lpc
diff options
context:
space:
mode:
authorBdale Garbee <bdale@gag.com>2015-02-07 22:39:54 -0700
committerBdale Garbee <bdale@gag.com>2015-02-07 22:39:54 -0700
commitf766a457323268857b3f2dfc7f42427437b71cb7 (patch)
tree8afc8a661d682fc34b16fc0b1b44f2844d34f336 /src/lpc
parentdb51224af01731e7323f6f696a7397d64eb80b92 (diff)
parente2cefd8593d269ce603aaf33f4a53a5c2dcb3350 (diff)
Merge branch 'branch-1.6' into debian
Conflicts: ChangeLog altoslib/AltosTelemetryReader.java configure.ac
Diffstat (limited to 'src/lpc')
-rw-r--r--src/lpc/ao_arch.h3
-rw-r--r--src/lpc/ao_arch_funcs.h18
-rw-r--r--src/lpc/ao_led_lpc.c11
-rw-r--r--src/lpc/ao_spi_lpc.c44
-rw-r--r--src/lpc/ao_usb_lpc.c91
5 files changed, 98 insertions, 69 deletions
diff --git a/src/lpc/ao_arch.h b/src/lpc/ao_arch.h
index 5fbb8dfa..42faf06f 100644
--- a/src/lpc/ao_arch.h
+++ b/src/lpc/ao_arch.h
@@ -130,12 +130,15 @@ ao_serial_init(void);
/* SPI definitions */
#define AO_SPI_SPEED_12MHz 4
+#define AO_SPI_SPEED_8MHz 6
#define AO_SPI_SPEED_6MHz 8
#define AO_SPI_SPEED_4MHz 12
#define AO_SPI_SPEED_2MHz 24
#define AO_SPI_SPEED_1MHz 48
#define AO_SPI_SPEED_500kHz 96
#define AO_SPI_SPEED_250kHz 192
+#define AO_SPI_SPEED_125kHz 384
+#define AO_SPI_SPEED_62500Hz 768
#define AO_SPI_SPEED_FAST AO_SPI_SPEED_12MHz
diff --git a/src/lpc/ao_arch_funcs.h b/src/lpc/ao_arch_funcs.h
index 21a7a8e5..fbe641d8 100644
--- a/src/lpc/ao_arch_funcs.h
+++ b/src/lpc/ao_arch_funcs.h
@@ -30,8 +30,19 @@
#define ao_gpio_get(port, bit, pin) (lpc_gpio.byte[lpc_all_bit(port,bit)])
+#define PORT0_JTAG_REGS ((1 << 11) | (1 << 12) | (1 << 14))
+
+static inline void lpc_set_gpio(int port, int bit) {
+ if (port == 0 && (1 << bit) & (PORT0_JTAG_REGS)) {
+ vuint32_t *_ioconf = &lpc_ioconf.pio0_0 + ((port)*24+(bit));
+
+ *_ioconf = (*_ioconf & ~LPC_IOCONF_FUNC_MASK) | LPC_IOCONF_FUNC_PIO0_11;
+ }
+}
+
#define ao_enable_output(port,bit,pin,v) do { \
ao_enable_port(port); \
+ lpc_set_gpio(port,bit); \
ao_gpio_set(port, bit, pin, v); \
lpc_gpio.dir[port] |= (1 << bit); \
} while (0)
@@ -52,6 +63,7 @@
#define ao_enable_input(port,bit,mode) do { \
ao_enable_port(port); \
+ lpc_set_gpio(port,bit); \
lpc_gpio.dir[port] &= ~(1 << bit); \
ao_gpio_set_mode(port,bit,mode); \
} while (0)
@@ -201,7 +213,7 @@ void
ao_spi_put(uint8_t spi_index);
void
-ao_spi_send(void *block, uint16_t len, uint8_t spi_index);
+ao_spi_send(const void *block, uint16_t len, uint8_t spi_index);
void
ao_spi_send_fixed(uint8_t value, uint16_t len, uint8_t spi_index);
@@ -210,9 +222,7 @@ void
ao_spi_recv(void *block, uint16_t len, uint8_t spi_index);
void
-ao_spi_duplex(void *out, void *in, uint16_t len, uint8_t spi_index);
-
-extern uint16_t ao_spi_speed[LPC_NUM_SPI];
+ao_spi_duplex(const void *out, void *in, uint16_t len, uint8_t spi_index);
void
ao_spi_init(void);
diff --git a/src/lpc/ao_led_lpc.c b/src/lpc/ao_led_lpc.c
index d983437c..a0b293b9 100644
--- a/src/lpc/ao_led_lpc.c
+++ b/src/lpc/ao_led_lpc.c
@@ -59,6 +59,15 @@ void
ao_led_init(AO_PORT_TYPE enable)
{
ao_led_enable = enable;
- lpc_scb.sysahbclkctrl |= (1 << LPC_SCB_SYSAHBCLKCTRL_GPIO);
+ ao_enable_port(LED_PORT);
+ if (LED_PORT == 0) {
+ if (enable & (1 << 11))
+ lpc_ioconf.pio0_11 = LPC_IOCONF_FUNC_PIO0_11 | (1 << LPC_IOCONF_ADMODE);
+ if (enable & (1 << 12))
+ lpc_ioconf.pio0_12 = LPC_IOCONF_FUNC_PIO0_12 | (1 << LPC_IOCONF_ADMODE);
+ if (enable & (1 << 14))
+ lpc_ioconf.pio0_14 = LPC_IOCONF_FUNC_PIO0_14 | (1 << LPC_IOCONF_ADMODE);
+ }
lpc_gpio.dir[LED_PORT] |= enable;
+ ao_led_off(enable);
}
diff --git a/src/lpc/ao_spi_lpc.c b/src/lpc/ao_spi_lpc.c
index e72b8286..f091c89c 100644
--- a/src/lpc/ao_spi_lpc.c
+++ b/src/lpc/ao_spi_lpc.c
@@ -21,34 +21,27 @@ static uint8_t ao_spi_mutex[LPC_NUM_SPI];
static struct lpc_ssp * const ao_lpc_ssp[LPC_NUM_SPI] = { &lpc_ssp0, &lpc_ssp1 };
-#define tx_busy(lpc_ssp) (lpc_ssp->sr & ((1 << LPC_SSP_SR_BSY) | (1 << LPC_SSP_SR_TNF))) != (1 << LPC_SSP_SR_TNF)
-#define rx_busy(lpc_ssp) (lpc_ssp->sr & ((1 << LPC_SSP_SR_BSY) | (1 << LPC_SSP_SR_RNE))) != (1 << LPC_SSP_SR_RNE)
-
#define spi_loop(len, put, get) do { \
while (len--) { \
- /* Wait for space in the fifo */ \
- while (tx_busy(lpc_ssp)) \
- ; \
- \
/* send a byte */ \
lpc_ssp->dr = put; \
- \
- /* Wait for byte to appear in the fifo */ \
- while (rx_busy(lpc_ssp)) \
+ /* wait for the received byte to appear */ \
+ while ((lpc_ssp->sr & (1 << LPC_SSP_SR_RNE)) == 0) \
; \
- \
- /* recv a byte */ \
+ /* receive a byte */ \
get lpc_ssp->dr; \
} \
+ /* Wait for the SSP to go idle (it already should be) */ \
+ while (lpc_ssp->sr & (1 << LPC_SSP_SR_BSY)); \
} while (0)
void
-ao_spi_send(void *block, uint16_t len, uint8_t id)
+ao_spi_send(const void *block, uint16_t len, uint8_t id)
{
- uint8_t *b = block;
struct lpc_ssp *lpc_ssp = ao_lpc_ssp[id];
+ const uint8_t *o = block;
- spi_loop(len, *b++, (void));
+ spi_loop(len, *o++, (void));
}
void
@@ -62,18 +55,18 @@ ao_spi_send_fixed(uint8_t value, uint16_t len, uint8_t id)
void
ao_spi_recv(void *block, uint16_t len, uint8_t id)
{
- uint8_t *b = block;
struct lpc_ssp *lpc_ssp = ao_lpc_ssp[id];
+ uint8_t *i = block;
- spi_loop(len, 0xff, *b++ =);
+ spi_loop(len, 0xff, *i++ =);
}
void
-ao_spi_duplex(void *out, void *in, uint16_t len, uint8_t id)
+ao_spi_duplex(const void *out, void *in, uint16_t len, uint8_t id)
{
- uint8_t *o = out;
- uint8_t *i = in;
struct lpc_ssp *lpc_ssp = ao_lpc_ssp[id];
+ const uint8_t *o = out;
+ uint8_t *i = in;
spi_loop(len, *o++, *i++ =);
}
@@ -84,7 +77,7 @@ ao_spi_get(uint8_t id, uint32_t speed)
struct lpc_ssp *lpc_ssp = ao_lpc_ssp[id];
ao_mutex_get(&ao_spi_mutex[id]);
-
+
/* Set the clock prescale */
lpc_ssp->cpsr = speed;
}
@@ -101,6 +94,11 @@ ao_spi_channel_init(uint8_t id)
struct lpc_ssp *lpc_ssp = ao_lpc_ssp[id];
uint8_t d;
+ /* Clear interrupt registers */
+ lpc_ssp->imsc = 0;
+ lpc_ssp->ris = 0;
+ lpc_ssp->mis = 0;
+
lpc_ssp->cr0 = ((LPC_SSP_CR0_DSS_8 << LPC_SSP_CR0_DSS) |
(LPC_SSP_CR0_FRF_SPI << LPC_SSP_CR0_FRF) |
(0 << LPC_SSP_CR0_CPOL) |
@@ -151,7 +149,7 @@ ao_spi_init(void)
lpc_scb.presetctrl &= ~(1 << LPC_SCB_PRESETCTRL_SSP0_RST_N);
lpc_scb.presetctrl |= (1 << LPC_SCB_PRESETCTRL_SSP0_RST_N);
ao_spi_channel_init(0);
-#endif
+#endif
#if HAS_SPI_1
@@ -190,7 +188,7 @@ ao_spi_init(void)
#ifndef HAS_MOSI1
#error "No pin specified for MOSI1"
#endif
-
+
/* Enable the device */
lpc_scb.sysahbclkctrl |= (1 << LPC_SCB_SYSAHBCLKCTRL_SSP1);
diff --git a/src/lpc/ao_usb_lpc.c b/src/lpc/ao_usb_lpc.c
index 12f5d8e6..0dfaece4 100644
--- a/src/lpc/ao_usb_lpc.c
+++ b/src/lpc/ao_usb_lpc.c
@@ -80,14 +80,12 @@ static uint8_t *ao_usb_ep0_setup_buffer;
static uint8_t *ao_usb_ep0_rx_buffer;
/* Pointer to bulk data tx/rx buffers in USB memory */
-static uint8_t *ao_usb_in_tx_buffer;
-static uint8_t *ao_usb_out_rx_buffer;
-
-/* Our data buffers */
-static uint8_t ao_usb_tx_buffer[AO_USB_IN_SIZE];
+static uint8_t *ao_usb_in_tx_buffer[2];
+static uint8_t ao_usb_in_tx_cur;
static uint8_t ao_usb_tx_count;
-static uint8_t ao_usb_rx_buffer[AO_USB_OUT_SIZE];
+static uint8_t *ao_usb_out_rx_buffer[2];
+static uint8_t ao_usb_out_rx_cur;
static uint8_t ao_usb_rx_count, ao_usb_rx_pos;
extern struct lpc_usb_endpoint lpc_usb_endpoint;
@@ -234,15 +232,15 @@ ao_usb_ep0_in(void)
}
static inline vuint32_t *
-ao_usb_epn_out(uint8_t n)
+ao_usb_epn_out(uint8_t n, uint8_t i)
{
- return &lpc_usb_endpoint.epn[n-1].out[0];
+ return &lpc_usb_endpoint.epn[n-1].out[i];
}
static inline vuint32_t *
-ao_usb_epn_in(uint8_t n)
+ao_usb_epn_in(uint8_t n, uint8_t i)
{
- return &lpc_usb_endpoint.epn[n-1].in[0];
+ return &lpc_usb_endpoint.epn[n-1].in[i];
}
#if UNUSED
@@ -256,26 +254,26 @@ ao_usb_set_epn_in(uint8_t n, uint8_t *addr, uint16_t nbytes)
static void
ao_usb_set_epn_out(uint8_t n, uint8_t *addr, uint16_t nbytes)
{
- ao_usb_set_ep(ao_usb_epn_out(n), addr, nbytes);
+ ao_usb_set_ep(ao_usb_epn_out(n, 0), addr, nbytes);
}
static inline uint16_t
ao_usb_epn_out_count(uint8_t n)
{
- return ao_usb_ep_count(ao_usb_epn_out(n));
+ return ao_usb_ep_count(ao_usb_epn_out(n, 0));
}
static inline uint16_t
ao_usb_epn_in_count(uint8_t n)
{
- return ao_usb_ep_count(ao_usb_epn_in(n));
+ return ao_usb_ep_count(ao_usb_epn_in(n, 0));
}
static uint8_t *
ao_usb_enable_ep(vuint32_t *ep, uint16_t nbytes, uint16_t set_nbytes)
{
uint8_t *addr = ao_usb_alloc_sram(nbytes);
-
+
ao_usb_set_ep(ep, addr, set_nbytes);
return addr;
}
@@ -294,28 +292,34 @@ ao_usb_disable_ep(vuint32_t *ep)
}
static void
-ao_usb_enable_epn(uint8_t n, uint16_t out_bytes, uint8_t **out_addr, uint16_t in_bytes, uint8_t **in_addr)
+ao_usb_enable_epn(uint8_t n,
+ uint16_t out_bytes, uint8_t *out_addrs[2],
+ uint16_t in_bytes, uint8_t *in_addrs[2])
{
uint8_t *addr;
- addr = ao_usb_enable_ep(ao_usb_epn_out(n), out_bytes, out_bytes);
- if (out_addr)
- *out_addr = addr;
- ao_usb_disable_ep(&lpc_usb_endpoint.epn[n-1].out[1]);
+ addr = ao_usb_enable_ep(ao_usb_epn_out(n, 0), out_bytes * 2, out_bytes);
+ if (out_addrs) {
+ out_addrs[0] = addr;
+ out_addrs[1] = addr + out_bytes;
+ }
+ ao_usb_disable_ep(ao_usb_epn_out(n, 1));
- addr = ao_usb_enable_ep(ao_usb_epn_in(n), in_bytes, 0);
- if (in_addr)
- *in_addr = addr;
- ao_usb_disable_ep(&lpc_usb_endpoint.epn[n-1].in[1]);
+ addr = ao_usb_enable_ep(ao_usb_epn_in(n, 0), in_bytes * 2, 0);
+ if (in_addrs) {
+ in_addrs[0] = addr;
+ in_addrs[1] = addr + in_bytes;
+ }
+ ao_usb_disable_ep(ao_usb_epn_in(n, 1));
}
static void
ao_usb_disable_epn(uint8_t n)
{
- ao_usb_disable_ep(ao_usb_epn_out(n));
- ao_usb_disable_ep(&lpc_usb_endpoint.epn[n-1].out[1]);
- ao_usb_disable_ep(ao_usb_epn_in(n));
- ao_usb_disable_ep(&lpc_usb_endpoint.epn[n-1].in[1]);
+ ao_usb_disable_ep(ao_usb_epn_out(n, 0));
+ ao_usb_disable_ep(ao_usb_epn_out(n, 1));
+ ao_usb_disable_ep(ao_usb_epn_in(n, 0));
+ ao_usb_disable_ep(ao_usb_epn_in(n, 1));
}
static void
@@ -362,12 +366,18 @@ ao_usb_set_configuration(void)
/* Set up the INT end point */
ao_usb_enable_epn(AO_USB_INT_EP, 0, NULL, 0, NULL);
-
+
/* Set up the OUT end point */
- ao_usb_enable_epn(AO_USB_OUT_EP, AO_USB_OUT_SIZE, &ao_usb_out_rx_buffer, 0, NULL);
+ ao_usb_enable_epn(AO_USB_OUT_EP, AO_USB_OUT_SIZE, ao_usb_out_rx_buffer, 0, NULL);
+
+ /* Set the current RX pointer to the *other* buffer so that when buffer 0 gets
+ * data, we'll switch to it and pull bytes from there
+ */
+ ao_usb_out_rx_cur = 1;
/* Set up the IN end point */
- ao_usb_enable_epn(AO_USB_IN_EP, 0, NULL, AO_USB_IN_SIZE, &ao_usb_in_tx_buffer);
+ ao_usb_enable_epn(AO_USB_IN_EP, 0, NULL, AO_USB_IN_SIZE, ao_usb_in_tx_buffer);
+ ao_usb_in_tx_cur = 0;
ao_usb_running = 1;
}
@@ -716,8 +726,8 @@ _ao_usb_in_send(void)
ao_usb_in_pending = 1;
if (ao_usb_tx_count != AO_USB_IN_SIZE)
ao_usb_in_flushed = 1;
- memcpy(ao_usb_in_tx_buffer, ao_usb_tx_buffer, ao_usb_tx_count);
- ao_usb_set_ep(ao_usb_epn_in(AO_USB_IN_EP), ao_usb_in_tx_buffer, ao_usb_tx_count);
+ ao_usb_set_ep(ao_usb_epn_in(AO_USB_IN_EP, 0), ao_usb_in_tx_buffer[ao_usb_in_tx_cur], ao_usb_tx_count);
+ ao_usb_in_tx_cur = 1 - ao_usb_in_tx_cur;
ao_usb_tx_count = 0;
_tx_dbg0("in_send end");
}
@@ -771,7 +781,7 @@ ao_usb_putchar(char c)
_ao_usb_in_wait();
ao_usb_in_flushed = 0;
- ao_usb_tx_buffer[ao_usb_tx_count++] = (uint8_t) c;
+ ao_usb_in_tx_buffer[ao_usb_in_tx_cur][ao_usb_tx_count++] = (uint8_t) c;
/* Send the packet when full */
if (ao_usb_tx_count == AO_USB_IN_SIZE) {
@@ -792,13 +802,12 @@ _ao_usb_out_recv(void)
_rx_dbg1("out_recv count", ao_usb_rx_count);
debug ("recv %d\n", ao_usb_rx_count);
- debug_data("Fill OUT len %d:", ao_usb_rx_count);
- memcpy(ao_usb_rx_buffer, ao_usb_out_rx_buffer, ao_usb_rx_count);
- debug_data("\n");
+ debug_data("Fill OUT len %d\n", ao_usb_rx_count);
ao_usb_rx_pos = 0;
+ ao_usb_out_rx_cur = 1 - ao_usb_out_rx_cur;
/* ACK the packet */
- ao_usb_set_epn_out(AO_USB_OUT_EP, ao_usb_out_rx_buffer, AO_USB_OUT_SIZE);
+ ao_usb_set_epn_out(AO_USB_OUT_EP, ao_usb_out_rx_buffer[1-ao_usb_out_rx_cur], AO_USB_OUT_SIZE);
}
int
@@ -823,7 +832,7 @@ _ao_usb_pollchar(void)
}
/* Pull a character out of the fifo */
- c = ao_usb_rx_buffer[ao_usb_rx_pos++];
+ c = ao_usb_out_rx_buffer[ao_usb_out_rx_cur][ao_usb_rx_pos++];
return c;
}
@@ -897,7 +906,7 @@ ao_usb_enable(void)
/* Enable USB PHY */
lpc_scb.pdruncfg &= ~(1 << LPC_SCB_PDRUNCFG_USBPAD_PD);
-
+
/* Turn on USB PLL */
lpc_scb.pdruncfg &= ~(1 << LPC_SCB_PDRUNCFG_USBPLL_PD);
@@ -1044,7 +1053,7 @@ static void _dbg(int line, char *msg, uint32_t value)
dbg[dbg_i].primask = primask;
#if TX_DBG
dbg[dbg_i].in_count = in_count;
- dbg[dbg_i].in_ep = *ao_usb_epn_in(AO_USB_IN_EP);
+ dbg[dbg_i].in_ep = *ao_usb_epn_in(AO_USB_IN_EP, 0);
dbg[dbg_i].in_pending = ao_usb_in_pending;
dbg[dbg_i].tx_count = ao_usb_tx_count;
dbg[dbg_i].in_flushed = ao_usb_in_flushed;
@@ -1053,7 +1062,7 @@ static void _dbg(int line, char *msg, uint32_t value)
dbg[dbg_i].rx_count = ao_usb_rx_count;
dbg[dbg_i].rx_pos = ao_usb_rx_pos;
dbg[dbg_i].out_avail = ao_usb_out_avail;
- dbg[dbg_i].out_ep = *ao_usb_epn_out(AO_USB_OUT_EP);
+ dbg[dbg_i].out_ep = *ao_usb_epn_out(AO_USB_OUT_EP, 0);
#endif
if (++dbg_i == NUM_USB_DBG)
dbg_i = 0;