summaryrefslogtreecommitdiff
path: root/src-avr/ao_spi_slave.c
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2011-08-13 18:27:02 -0700
committerKeith Packard <keithp@keithp.com>2011-08-13 18:27:02 -0700
commit0beebf5b8659014c5e8ba194e42e5dcd9be1a2a6 (patch)
tree55288ec5f4b2243c12769f8266166e876132d50e /src-avr/ao_spi_slave.c
parent28a6127668a333f5d6a6234e2ee4527267c459d2 (diff)
altos-avr: Include serial/flight in companion commands
This lets TeleScience log these values so the log can be matched with a suitable TeleMetrum log. Signed-off-by: Keith Packard <keithp@keithp.com>
Diffstat (limited to 'src-avr/ao_spi_slave.c')
-rw-r--r--src-avr/ao_spi_slave.c69
1 files changed, 47 insertions, 22 deletions
diff --git a/src-avr/ao_spi_slave.c b/src-avr/ao_spi_slave.c
index d44e4d0e..9ef30ead 100644
--- a/src-avr/ao_spi_slave.c
+++ b/src-avr/ao_spi_slave.c
@@ -18,7 +18,8 @@
#include "ao.h"
#include "ao_product.h"
-static struct ao_companion_command ao_companion_command;
+struct ao_companion_command ao_companion_command;
+
static const struct ao_companion_setup ao_companion_setup = {
.board_id = AO_idProduct_NUMBER,
.board_id_inverse = ~AO_idProduct_NUMBER,
@@ -26,29 +27,46 @@ static const struct ao_companion_setup ao_companion_setup = {
.channels = NUM_ADC
};
-static uint8_t ao_spi_slave_recv(void)
+static uint8_t
+ao_spi_read(uint8_t *buf, uint8_t len)
{
- uint8_t *buf;
- uint8_t len;
-
- len = sizeof (ao_companion_command);
- buf = (uint8_t *) &ao_companion_command;
while (len--) {
while (!(SPSR & (1 << SPIF)))
if ((PINB & (1 << PINB0)))
return 0;
*buf++ = SPDR;
}
+ return 1;
+}
+
+static void
+ao_spi_write(uint8_t *buf, uint8_t len)
+{
+ while (len--) {
+ SPDR = *buf++;
+ while (!(SPSR & (1 << SPIF)))
+ if ((PINB & (1 << PINB0)))
+ return;
+ }
+ /* Clear pending SPIF bit by reading */
+ (void) SPDR;
+}
+
+static uint8_t ao_spi_slave_recv(void)
+{
+ if (!ao_spi_read((uint8_t *) &ao_companion_command,
+ sizeof (ao_companion_command)))
+ return 0;
/* Figure out the outbound data */
switch (ao_companion_command.command) {
case AO_COMPANION_SETUP:
- buf = (uint8_t *) &ao_companion_setup;
- len = sizeof (ao_companion_setup);
+ ao_spi_write((uint8_t *) &ao_companion_setup,
+ sizeof (ao_companion_setup));
break;
case AO_COMPANION_FETCH:
- buf = (uint8_t *) &ao_adc_ring[ao_adc_ring_prev(ao_adc_head)].adc;
- len = NUM_ADC * sizeof (uint16_t);
+ ao_spi_write((uint8_t *) &ao_adc_ring[ao_adc_ring_prev(ao_adc_head)].adc,
+ NUM_ADC * sizeof (uint16_t));
break;
case AO_COMPANION_STATE:
break;
@@ -56,16 +74,6 @@ static uint8_t ao_spi_slave_recv(void)
return 0;
}
- if (len) {
- /* Send the outbound data */
- while (len--) {
- SPDR = *buf++;
- while (!(SPSR & (1 << SPIF)))
- if ((PINB & (1 << PINB0)))
- return 0;
- }
- (void) SPDR;
- }
ao_log_store.tm_tick = ao_companion_command.tick;
if (ao_log_store.tm_state != ao_companion_command.flight_state) {
ao_log_store.tm_state = ao_companion_command.flight_state;
@@ -107,7 +115,24 @@ ao_spi_slave_init(void)
PCMSK0 |= (1 << PCINT0); /* Enable PCINT0 pin change */
PCICR |= (1 << PCIE0); /* Enable pin change interrupt */
- DDRB = (DDRB & 0xf0) | (1 << 3);
+ DDRB = ((DDRB & 0xf0) |
+ (1 << 3) | /* MISO, output */
+ (0 << 2) | /* MOSI, input */
+ (0 << 1) | /* SCK, input */
+ (0 << 0)); /* SS, input */
+
+ /* We'd like to have a pull-up on SS so that disconnecting the
+ * TM would cause any SPI transaction to abort. However, when
+ * I tried that, SPI transactions would spontaneously abort,
+ * making me assume that we needed a less aggressive pull-up
+ * than is offered inside the AVR
+ */
+ PORTB = ((PORTB & 0xf0) |
+ (1 << 3) | /* MISO, output */
+ (0 << 2) | /* MOSI, no pull-up */
+ (0 << 1) | /* SCK, no pull-up */
+ (0 << 0)); /* SS, no pull-up */
+
SPCR = (0 << SPIE) | /* Disable SPI interrupts */
(1 << SPE) | /* Enable SPI */
(0 << DORD) | /* MSB first */