altos: Add support for multiple SPI busses and sharing device drivers
authorKeith Packard <keithp@keithp.com>
Tue, 10 Apr 2012 06:27:43 +0000 (23:27 -0700)
committerKeith Packard <keithp@keithp.com>
Sat, 14 Apr 2012 20:21:09 +0000 (13:21 -0700)
The STM32L151 has several SPI busses, and we want to use more than
one, so add a 'bus' parameter to the SPI interfaces. To avoid wasting
time on AVR and CC1111 processors which only use one SPI bus, elide
those parameters from the actual functions by wrapping them with
macros.

Configuring chip select is now all macroized so that each chip can
have its own version, allowing the STM to share the various SPI device
drivers with the cc1111 and avr processors. Note that only the M25
driver has been ported; porting the others is 'trivial', but not
necessary at this point.

Signed-off-by: Keith Packard <keithp@keithp.com>
16 files changed:
src/avr/ao_arch_funcs.h
src/avr/ao_pins.h
src/avr/ao_spi_usart.c
src/cc1111/ao_arch_funcs.h
src/cc1111/ao_pins.h
src/cc1111/ao_spi.c
src/drivers/ao_25lc1024.c
src/drivers/ao_at45db161d.c
src/drivers/ao_companion.c
src/drivers/ao_m25.c
src/drivers/ao_ms5607.c
src/megametrum-v0.1/Makefile
src/megametrum-v0.1/ao_megametrum.c
src/megametrum-v0.1/ao_pins.h
src/stm/ao_arch_funcs.h
src/teleterra-v0.2/ao_pins.h

index 9ad14fbbad0144e4b960c32be95a82244c293a67..1eeca6cc73c0f1490cc6c1240d55fdcf46df878a 100644 (file)
 
 extern __xdata uint8_t ao_spi_mutex;
 
 
 extern __xdata uint8_t ao_spi_mutex;
 
-#define ao_spi_get_mask(reg,mask) do {\
-       ao_mutex_get(&ao_spi_mutex); \
-       (reg) &= ~(mask); \
+#define ao_spi_get_mask(reg,mask,bus) do {     \
+               ao_mutex_get(&ao_spi_mutex);    \
+               (reg) &= ~(mask);               \
        } while (0)
 
        } while (0)
 
-#define ao_spi_put_mask(reg,mask) do { \
-       (reg) |= (mask); \
-       ao_mutex_put(&ao_spi_mutex); \
+#define ao_spi_put_mask(reg,mask,bus) do {     \
+               (reg) |= (mask);                \
+               ao_mutex_put(&ao_spi_mutex);    \
        } while (0)
 
        } while (0)
 
-#define ao_spi_get_bit(bit) do {\
-       ao_mutex_get(&ao_spi_mutex); \
-       (bit) = 0; \
+#define ao_spi_get_bit(bit) do {               \
+               ao_mutex_get(&ao_spi_mutex);    \
+               (bit) = 0;                      \
        } while (0)
 
        } while (0)
 
-#define ao_spi_put_bit(bit) do { \
-       (bit) = 1; \
-       ao_mutex_put(&ao_spi_mutex); \
+#define ao_spi_put_bit(bit) do {               \
+               (bit) = 1;                      \
+               ao_mutex_put(&ao_spi_mutex);    \
        } while (0)
 
 /*
        } while (0)
 
 /*
@@ -48,11 +48,18 @@ extern __xdata uint8_t      ao_spi_mutex;
  */
 
 void
  */
 
 void
-ao_spi_send(void __xdata *block, uint16_t len) __reentrant;
+ao_spi_send_bus(void __xdata *block, uint16_t len) __reentrant;
 
 void
 
 void
-ao_spi_recv(void __xdata *block, uint16_t len) __reentrant;
+ao_spi_recv_bus(void __xdata *block, uint16_t len) __reentrant;
+
+#define ao_spi_send(block, len, bus) ao_spi_send_bus(block, len)
+#define ao_spi_recv(block, len, bus) ao_spi_recv_bus(block, len)
 
 void
 ao_spi_init(void);
 
 
 void
 ao_spi_init(void);
 
+#define ao_spi_init_cs(port, mask) do {                \
+               SPI_CS_PORT |= (mask);          \
+               SPI_CS_DIR |= (mask);           \
+       } while (0)
index bf02db1b8e4dc1e0b2de54cf1b8af6c5f81210bd..6a63468f84741c43625326553449f0827ef47275 100644 (file)
@@ -85,4 +85,7 @@
        #define SPI_SLAVE_PIN_2_5       0
 #endif
 
        #define SPI_SLAVE_PIN_2_5       0
 #endif
 
+#define AO_M25_SPI_CS_PORT     SPI_CS_PORT
+#define AO_M25_SPI_CS_MASK     M25_CS_MASK
+
 #endif /* _AO_PINS_H_ */
 #endif /* _AO_PINS_H_ */
index 5ea11da6a093527a6ae96cb4caa0f8cd5ccdcaed..7c41042a4424026e99b0ea821c618a7b750298fe 100644 (file)
@@ -29,7 +29,7 @@ __xdata uint8_t       ao_spi_mutex;
  * so using interrupts would take way too long
  */
 void
  * so using interrupts would take way too long
  */
 void
-ao_spi_send(void __xdata *block, uint16_t len) __reentrant
+ao_spi_send_bus(void __xdata *block, uint16_t len) __reentrant
 {
        uint8_t *d = block;
 
 {
        uint8_t *d = block;
 
@@ -46,7 +46,7 @@ ao_spi_send(void __xdata *block, uint16_t len) __reentrant
  * Poll, sending zeros and reading data back
  */
 void
  * Poll, sending zeros and reading data back
  */
 void
-ao_spi_recv(void __xdata *block, uint16_t len) __reentrant
+ao_spi_recv_bus(void __xdata *block, uint16_t len) __reentrant
 {
        uint8_t *d = block;
 
 {
        uint8_t *d = block;
 
index 9ad14fbbad0144e4b960c32be95a82244c293a67..d9f5955a75b3326f03d0cb985bd872942062da40 100644 (file)
 
 extern __xdata uint8_t ao_spi_mutex;
 
 
 extern __xdata uint8_t ao_spi_mutex;
 
-#define ao_spi_get_mask(reg,mask) do {\
+#define ao_spi_get_mask(reg,mask,bus) do {             \
        ao_mutex_get(&ao_spi_mutex); \
        (reg) &= ~(mask); \
        } while (0)
 
        ao_mutex_get(&ao_spi_mutex); \
        (reg) &= ~(mask); \
        } while (0)
 
-#define ao_spi_put_mask(reg,mask) do { \
+#define ao_spi_put_mask(reg,mask,bus) do {             \
        (reg) |= (mask); \
        ao_mutex_put(&ao_spi_mutex); \
        } while (0)
 
        (reg) |= (mask); \
        ao_mutex_put(&ao_spi_mutex); \
        } while (0)
 
-#define ao_spi_get_bit(bit) do {\
+#define ao_spi_get_bit(bit,bus) do {    \
        ao_mutex_get(&ao_spi_mutex); \
        (bit) = 0; \
        } while (0)
 
        ao_mutex_get(&ao_spi_mutex); \
        (bit) = 0; \
        } while (0)
 
-#define ao_spi_put_bit(bit) do { \
+#define ao_spi_put_bit(bit,bus) do {           \
        (bit) = 1; \
        ao_mutex_put(&ao_spi_mutex); \
        } while (0)
 
        (bit) = 1; \
        ao_mutex_put(&ao_spi_mutex); \
        } while (0)
 
+
 /*
  * The SPI mutex must be held to call either of these
  * functions -- this mutex covers the entire SPI operation,
 /*
  * The SPI mutex must be held to call either of these
  * functions -- this mutex covers the entire SPI operation,
@@ -48,11 +49,19 @@ extern __xdata uint8_t      ao_spi_mutex;
  */
 
 void
  */
 
 void
-ao_spi_send(void __xdata *block, uint16_t len) __reentrant;
+ao_spi_send_bus(void __xdata *block, uint16_t len) __reentrant;
 
 void
 
 void
-ao_spi_recv(void __xdata *block, uint16_t len) __reentrant;
+ao_spi_recv_bus(void __xdata *block, uint16_t len) __reentrant;
+
+#define ao_spi_send(block, len, bus) ao_spi_send_bus(block, len)
+#define ao_spi_recv(block, len, bus) ao_spi_recv_bus(block, len)
 
 void
 ao_spi_init(void);
 
 
 void
 ao_spi_init(void);
 
+#define ao_spi_init_cs(port, mask) do {                \
+               SPI_CS_PORT |= mask;            \
+               SPI_CS_DIR |= mask;             \
+               SPI_CS_SEL &= ~mask;            \
+       } while (0)
index a18c74c81ce50597312a64dfb1e48feafc90957e..5c0cb7dfe73e1f5c283c1da10c5a5d429c307fc1 100644 (file)
@@ -82,7 +82,7 @@
        #define HAS_ACCEL_REF           1
        #define SPI_CS_ON_P1            1
        #define SPI_CS_ON_P0            0
        #define HAS_ACCEL_REF           1
        #define SPI_CS_ON_P1            1
        #define SPI_CS_ON_P0            0
-       #define M25_CS_MASK             0x02    /* CS0 is P1_1 */
+       #define AO_M25_SPI_CS_MASK      0x02    /* CS0 is P1_1 */
        #define M25_MAX_CHIPS           1
        #define HAS_ACCEL               1
        #define HAS_IGNITE              1
        #define M25_MAX_CHIPS           1
        #define HAS_ACCEL               1
        #define HAS_IGNITE              1
        #define HAS_ACCEL_REF           1
        #define SPI_CS_ON_P1            1
        #define SPI_CS_ON_P0            0
        #define HAS_ACCEL_REF           1
        #define SPI_CS_ON_P1            1
        #define SPI_CS_ON_P0            0
-       #define M25_CS_MASK             0x02    /* CS0 is P1_1 */
+       #define AO_M25_SPI_CS_MASK      0x02    /* CS0 is P1_1 */
        #define M25_MAX_CHIPS           1
        #define HAS_ACCEL               1
        #define HAS_IGNITE              1
        #define M25_MAX_CHIPS           1
        #define HAS_ACCEL               1
        #define HAS_IGNITE              1
        #define LEDS_AVAILABLE          (AO_LED_RED|AO_LED_GREEN)
        #define SPI_CS_ON_P1            1
        #define SPI_CS_ON_P0            0
        #define LEDS_AVAILABLE          (AO_LED_RED|AO_LED_GREEN)
        #define SPI_CS_ON_P1            1
        #define SPI_CS_ON_P0            0
-       #define M25_CS_MASK             0x04    /* CS0 is P1_2 */
+       #define AO_M25_SPI_CS_MASK      0x04    /* CS0 is P1_2 */
        #define M25_MAX_CHIPS           1
        #define HAS_ACCEL               0
        #define HAS_IGNITE              0
        #define M25_MAX_CHIPS           1
        #define HAS_ACCEL               0
        #define HAS_IGNITE              0
        #define SPI_CS_DIR      P0DIR
 #endif
 
        #define SPI_CS_DIR      P0DIR
 #endif
 
+#define AO_M25_SPI_CS_PORT     SPI_CS_PORT
+
 #ifndef IGNITE_ON_P2
 #error Please define IGNITE_ON_P2
 #endif
 #ifndef IGNITE_ON_P2
 #error Please define IGNITE_ON_P2
 #endif
index 1fa8e1282fe0374b2d6f745b366ac2b8d80bb763..1bf5e1551b0c7a9013c009880f3326e875e3dfe4 100644 (file)
@@ -38,7 +38,7 @@ static __xdata uint8_t ao_spi_const;
  * completion one byte before the transfer is actually complete
  */
 void
  * completion one byte before the transfer is actually complete
  */
 void
-ao_spi_send(void __xdata *block, uint16_t len) __reentrant
+ao_spi_send_bus(void __xdata *block, uint16_t len) __reentrant
 {
        ao_dma_set_transfer(ao_spi_dma_in_id,
                            &U0DBUFXADDR,
 {
        ao_dma_set_transfer(ao_spi_dma_in_id,
                            &U0DBUFXADDR,
@@ -76,7 +76,7 @@ ao_spi_send(void __xdata *block, uint16_t len) __reentrant
  * clocks the data coming in.
  */
 void
  * clocks the data coming in.
  */
 void
-ao_spi_recv(void __xdata *block, uint16_t len) __reentrant
+ao_spi_recv_bus(void __xdata *block, uint16_t len) __reentrant
 {
        ao_dma_set_transfer(ao_spi_dma_in_id,
                            &U0DBUFXADDR,
 {
        ao_dma_set_transfer(ao_spi_dma_in_id,
                            &U0DBUFXADDR,
index 2d047a44bf7b254471fe194e9cbfb66ff70fb228..f0fb13c97ddfb91087231356e5249f13e9fd3d40 100644 (file)
@@ -49,9 +49,9 @@ static __xdata uint8_t ao_ee_mutex;
        _asm nop _endasm; \
 } while(0)
 
        _asm nop _endasm; \
 } while(0)
 
-#define ao_ee_cs_low() ao_spi_get_bit(EE_CS)
+#define ao_ee_cs_low() ao_spi_get_bit(EE_CS, AO_EE_SPI_BUS)
 
 
-#define ao_ee_cs_high()        ao_spi_put_bit(EE_CS)
+#define ao_ee_cs_high()        ao_spi_put_bit(EE_CS, AO_EE_SPI_BUS)
 
 struct ao_ee_instruction {
        uint8_t instruction;
 
 struct ao_ee_instruction {
        uint8_t instruction;
@@ -63,7 +63,7 @@ ao_ee_write_enable(void)
 {
        ao_ee_cs_low();
        ao_ee_instruction.instruction = EE_WREN;
 {
        ao_ee_cs_low();
        ao_ee_instruction.instruction = EE_WREN;
-       ao_spi_send(&ao_ee_instruction, 1);
+       ao_spi_send(&ao_ee_instruction, 1, AO_EE_SPI_BUS);
        ao_ee_cs_high();
 }
 
        ao_ee_cs_high();
 }
 
@@ -72,8 +72,8 @@ ao_ee_rdsr(void)
 {
        ao_ee_cs_low();
        ao_ee_instruction.instruction = EE_RDSR;
 {
        ao_ee_cs_low();
        ao_ee_instruction.instruction = EE_RDSR;
-       ao_spi_send(&ao_ee_instruction, 1);
-       ao_spi_recv(&ao_ee_instruction, 1);
+       ao_spi_send(&ao_ee_instruction, 1, AO_EE_SPI_BUS);
+       ao_spi_recv(&ao_ee_instruction, 1, AO_EE_SPI_BUS);
        ao_ee_cs_high();
        return ao_ee_instruction.instruction;
 }
        ao_ee_cs_high();
        return ao_ee_instruction.instruction;
 }
@@ -84,7 +84,7 @@ ao_ee_wrsr(uint8_t status)
        ao_ee_cs_low();
        ao_ee_instruction.instruction = EE_WRSR;
        ao_ee_instruction.address[0] = status;
        ao_ee_cs_low();
        ao_ee_instruction.instruction = EE_WRSR;
        ao_ee_instruction.address[0] = status;
-       ao_spi_send(&ao_ee_instruction, 2);
+       ao_spi_send(&ao_ee_instruction, 2, AO_EE_SPI_BUS);
        ao_ee_cs_high();
 }
 
        ao_ee_cs_high();
 }
 
@@ -111,8 +111,8 @@ ao_ee_write_block(void)
        ao_ee_instruction.address[0] = ao_ee_block >> 8;
        ao_ee_instruction.address[1] = ao_ee_block;
        ao_ee_instruction.address[2] = 0;
        ao_ee_instruction.address[0] = ao_ee_block >> 8;
        ao_ee_instruction.address[1] = ao_ee_block;
        ao_ee_instruction.address[2] = 0;
-       ao_spi_send(&ao_ee_instruction, 4);
-       ao_spi_send(ao_ee_data, EE_BLOCK_SIZE);
+       ao_spi_send(&ao_ee_instruction, 4, AO_EE_SPI_BUS);
+       ao_spi_send(ao_ee_data, EE_BLOCK_SIZE, AO_EE_SPI_BUS);
        ao_ee_cs_high();
        for (;;) {
                uint8_t status = ao_ee_rdsr();
        ao_ee_cs_high();
        for (;;) {
                uint8_t status = ao_ee_rdsr();
@@ -130,8 +130,8 @@ ao_ee_read_block(void)
        ao_ee_instruction.address[0] = ao_ee_block >> 8;
        ao_ee_instruction.address[1] = ao_ee_block;
        ao_ee_instruction.address[2] = 0;
        ao_ee_instruction.address[0] = ao_ee_block >> 8;
        ao_ee_instruction.address[1] = ao_ee_block;
        ao_ee_instruction.address[2] = 0;
-       ao_spi_send(&ao_ee_instruction, 4);
-       ao_spi_recv(ao_ee_data, EE_BLOCK_SIZE);
+       ao_spi_send(&ao_ee_instruction, 4, AO_EE_SPI_BUS);
+       ao_spi_recv(ao_ee_data, EE_BLOCK_SIZE, AO_EE_SPI_BUS);
        ao_ee_cs_high();
 }
 
        ao_ee_cs_high();
 }
 
index 6cd689e5440b253df6288918a4492cee34117922..afe0080b87f78243e5f947b45549d8cf3e4a5833 100644 (file)
@@ -43,9 +43,9 @@ __xdata uint8_t ao_flash_mutex;
        _asm nop _endasm; \
 } while(0)
 
        _asm nop _endasm; \
 } while(0)
 
-#define ao_flash_cs_low()      ao_spi_get_bit(FLASH_CS)
+#define ao_flash_cs_low()      ao_spi_get_bit(FLASH_CS, AO_FLASH_SPI_BUS)
 
 
-#define ao_flash_cs_high()     ao_spi_put_bit(FLASH_CS)
+#define ao_flash_cs_high()     ao_spi_put_bit(FLASH_CS, AO_FLASH_SPI_BUS)
 
 struct ao_flash_instruction {
        uint8_t instruction;
 
 struct ao_flash_instruction {
        uint8_t instruction;
@@ -60,7 +60,7 @@ ao_flash_set_pagesize_512(void)
        ao_flash_instruction.address[0] = FLASH_SET_512_BYTE_0;
        ao_flash_instruction.address[1] = FLASH_SET_512_BYTE_1;
        ao_flash_instruction.address[2] = FLASH_SET_512_BYTE_2;
        ao_flash_instruction.address[0] = FLASH_SET_512_BYTE_0;
        ao_flash_instruction.address[1] = FLASH_SET_512_BYTE_1;
        ao_flash_instruction.address[2] = FLASH_SET_512_BYTE_2;
-       ao_spi_send(&ao_flash_instruction, 4);
+       ao_spi_send(&ao_flash_instruction, 4, AO_FLASH_SPI_BUS);
        ao_flash_cs_high();
 }
 
        ao_flash_cs_high();
 }
 
@@ -70,8 +70,8 @@ ao_flash_read_status(void)
 {
        ao_flash_cs_low();
        ao_flash_instruction.instruction = FLASH_READ_STATUS;
 {
        ao_flash_cs_low();
        ao_flash_instruction.instruction = FLASH_READ_STATUS;
-       ao_spi_send(&ao_flash_instruction, 1);
-       ao_spi_recv(&ao_flash_instruction, 1);
+       ao_spi_send(&ao_flash_instruction, 1, AO_FLASH_SPI_BUS);
+       ao_spi_recv(&ao_flash_instruction, 1, AO_FLASH_SPI_BUS);
        ao_flash_cs_high();
        return ao_flash_instruction.instruction;
 }
        ao_flash_cs_high();
        return ao_flash_instruction.instruction;
 }
@@ -190,8 +190,8 @@ ao_flash_write_block(void)
        ao_flash_instruction.address[0] = ao_flash_block >> (16 - ao_flash_block_shift);
        ao_flash_instruction.address[1] = ao_flash_block << (ao_flash_block_shift - 8);
        ao_flash_instruction.address[2] = 0;
        ao_flash_instruction.address[0] = ao_flash_block >> (16 - ao_flash_block_shift);
        ao_flash_instruction.address[1] = ao_flash_block << (ao_flash_block_shift - 8);
        ao_flash_instruction.address[2] = 0;
-       ao_spi_send(&ao_flash_instruction, 4);
-       ao_spi_send(ao_flash_data, ao_storage_block);
+       ao_spi_send(&ao_flash_instruction, 4, AO_FLASH_SPI_BUS);
+       ao_spi_send(ao_flash_data, ao_storage_block, AO_FLASH_SPI_BUS);
        ao_flash_cs_high();
        ao_flash_write_pending = 1;
 }
        ao_flash_cs_high();
        ao_flash_write_pending = 1;
 }
@@ -208,8 +208,8 @@ ao_flash_read_block(void)
        ao_flash_instruction.address[0] = ao_flash_block >> (16 - ao_flash_block_shift);
        ao_flash_instruction.address[1] = ao_flash_block << (ao_flash_block_shift - 8);
        ao_flash_instruction.address[2] = 0;
        ao_flash_instruction.address[0] = ao_flash_block >> (16 - ao_flash_block_shift);
        ao_flash_instruction.address[1] = ao_flash_block << (ao_flash_block_shift - 8);
        ao_flash_instruction.address[2] = 0;
-       ao_spi_send(&ao_flash_instruction, 4);
-       ao_spi_recv(ao_flash_data, ao_flash_block_size);
+       ao_spi_send(&ao_flash_instruction, 4, AO_FLASH_SPI_BUS);
+       ao_spi_recv(ao_flash_data, ao_flash_block_size, AO_FLASH_SPI_BUS);
        ao_flash_cs_high();
 }
 
        ao_flash_cs_high();
 }
 
index 2e587f8efd1fff3c9fd45741288d2b904fe56a6a..fe88e998f0cca54139c86245b1fd2ea2dad3d9ca 100644 (file)
@@ -27,8 +27,8 @@
                                UxGCR_ORDER_MSB |               \
                                (17 << UxGCR_BAUD_E_SHIFT)))
 
                                UxGCR_ORDER_MSB |               \
                                (17 << UxGCR_BAUD_E_SHIFT)))
 
-#define COMPANION_SELECT()     do { ao_spi_get_bit(COMPANION_CS); ao_spi_slow(); } while (0)
-#define COMPANION_DESELECT()   do { ao_spi_fast(); ao_spi_put_bit(COMPANION_CS); } while (0)
+#define COMPANION_SELECT()     do { ao_spi_get_bit(COMPANION_CS, AO_COMPANION_BUS); ao_spi_slow(); } while (0)
+#define COMPANION_DESELECT()   do { ao_spi_fast(); ao_spi_put_bit(COMPANION_CS, AO_COMPANION_BUS); } while (0)
 
 __xdata struct ao_companion_command            ao_companion_command;
 __xdata struct ao_companion_setup              ao_companion_setup;
 
 __xdata struct ao_companion_command            ao_companion_command;
 __xdata struct ao_companion_setup              ao_companion_setup;
@@ -45,7 +45,7 @@ ao_companion_send_command(uint8_t command)
        ao_companion_command.tick = ao_time();
        ao_companion_command.serial = ao_serial_number;
        ao_companion_command.flight = ao_flight_number;
        ao_companion_command.tick = ao_time();
        ao_companion_command.serial = ao_serial_number;
        ao_companion_command.flight = ao_flight_number;
-       ao_spi_send(&ao_companion_command, sizeof (ao_companion_command));
+       ao_spi_send(&ao_companion_command, sizeof (ao_companion_command), AO_COMPANION_SPI_BUS);
 }
 
 static uint8_t
 }
 
 static uint8_t
@@ -53,7 +53,7 @@ ao_companion_get_setup(void)
 {
        COMPANION_SELECT();
        ao_companion_send_command(AO_COMPANION_SETUP);
 {
        COMPANION_SELECT();
        ao_companion_send_command(AO_COMPANION_SETUP);
-       ao_spi_recv(&ao_companion_setup, sizeof (ao_companion_setup));
+       ao_spi_recv(&ao_companion_setup, sizeof (ao_companion_setup), AO_COMPANION_SPI_BUS);
        COMPANION_DESELECT();
        return (ao_companion_setup.board_id ==
                ~ao_companion_setup.board_id_inverse);
        COMPANION_DESELECT();
        return (ao_companion_setup.board_id ==
                ~ao_companion_setup.board_id_inverse);
@@ -65,7 +65,7 @@ ao_companion_get_data(void)
        COMPANION_SELECT();
        ao_companion_send_command(AO_COMPANION_FETCH);
        ao_mutex_get(&ao_companion_mutex);
        COMPANION_SELECT();
        ao_companion_send_command(AO_COMPANION_FETCH);
        ao_mutex_get(&ao_companion_mutex);
-       ao_spi_recv(&ao_companion_data, ao_companion_setup.channels * 2);
+       ao_spi_recv(&ao_companion_data, ao_companion_setup.channels * 2, AO_COMPANION_SPI_BUS);
        ao_mutex_put(&ao_companion_mutex);
        COMPANION_DESELECT();
 }
        ao_mutex_put(&ao_companion_mutex);
        COMPANION_DESELECT();
 }
index 28cb1dd73078ab71492fe033e8ba30d933888070..c807cd686cb053c06921395d81448f82ec18a8cc 100644 (file)
@@ -99,8 +99,8 @@ static __xdata uint8_t ao_m25_mutex;
 
 static __xdata uint8_t ao_m25_instruction[4];
 
 
 static __xdata uint8_t ao_m25_instruction[4];
 
-#define M25_SELECT(cs)         ao_spi_get_mask(SPI_CS_PORT,cs)
-#define M25_DESELECT(cs)       ao_spi_put_mask(SPI_CS_PORT,cs)
+#define M25_SELECT(cs)         ao_spi_get_mask(AO_M25_SPI_CS_PORT,cs,AO_M25_SPI_BUS)
+#define M25_DESELECT(cs)       ao_spi_put_mask(AO_M25_SPI_CS_PORT,cs,AO_M25_SPI_BUS)
 
 #define M25_BLOCK_SHIFT                        16
 #define M25_BLOCK                      65536L
 
 #define M25_BLOCK_SHIFT                        16
 #define M25_BLOCK                      65536L
@@ -116,9 +116,9 @@ ao_m25_wait_wip(uint8_t cs)
        if (ao_m25_wip & cs) {
                M25_SELECT(cs);
                ao_m25_instruction[0] = M25_RDSR;
        if (ao_m25_wip & cs) {
                M25_SELECT(cs);
                ao_m25_instruction[0] = M25_RDSR;
-               ao_spi_send(ao_m25_instruction, 1);
+               ao_spi_send(ao_m25_instruction, 1, AO_M25_SPI_BUS);
                do {
                do {
-                       ao_spi_recv(ao_m25_instruction, 1);
+                       ao_spi_recv(ao_m25_instruction, 1, AO_M25_SPI_BUS);
                } while (ao_m25_instruction[0] & M25_STATUS_WIP);
                M25_DESELECT(cs);
                ao_m25_wip &= ~cs;
                } while (ao_m25_instruction[0] & M25_STATUS_WIP);
                M25_DESELECT(cs);
                ao_m25_wip &= ~cs;
@@ -135,7 +135,7 @@ ao_m25_write_enable(uint8_t cs)
 {
        M25_SELECT(cs);
        ao_m25_instruction[0] = M25_WREN;
 {
        M25_SELECT(cs);
        ao_m25_instruction[0] = M25_WREN;
-       ao_spi_send(&ao_m25_instruction, 1);
+       ao_spi_send(&ao_m25_instruction, 1, AO_M25_SPI_BUS);
        M25_DESELECT(cs);
        ao_m25_wip |= cs;
 }
        M25_DESELECT(cs);
        ao_m25_wip |= cs;
 }
@@ -150,8 +150,8 @@ ao_m25_read_capacity(uint8_t cs)
        uint8_t capacity;
        M25_SELECT(cs);
        ao_m25_instruction[0] = M25_RDID;
        uint8_t capacity;
        M25_SELECT(cs);
        ao_m25_instruction[0] = M25_RDID;
-       ao_spi_send(ao_m25_instruction, 1);
-       ao_spi_recv(ao_m25_instruction, M25_RDID_LEN);
+       ao_spi_send(ao_m25_instruction, 1, AO_M25_SPI_BUS);
+       ao_spi_recv(ao_m25_instruction, M25_RDID_LEN, AO_M25_SPI_BUS);
        M25_DESELECT(cs);
 
        /* Check to see if the chip is present */
        M25_DESELECT(cs);
 
        /* Check to see if the chip is present */
@@ -183,7 +183,7 @@ ao_m25_set_address(uint32_t pos)
 
        chip = ao_m25_pin[chip];
 #else
 
        chip = ao_m25_pin[chip];
 #else
-       chip = M25_CS_MASK;
+       chip = AO_M25_SPI_CS_MASK;
 #endif
        ao_m25_wait_wip(chip);
 
 #endif
        ao_m25_wait_wip(chip);
 
@@ -210,7 +210,7 @@ ao_m25_scan(void)
 #if M25_MAX_CHIPS > 1
        ao_m25_numchips = 0;
        for (pin = 1; pin != 0; pin <<= 1) {
 #if M25_MAX_CHIPS > 1
        ao_m25_numchips = 0;
        for (pin = 1; pin != 0; pin <<= 1) {
-               if (M25_CS_MASK & pin) {
+               if (AO_M25_SPI_CS_MASK & pin) {
                        size = ao_m25_read_capacity(pin);
                        if (size != 0) {
                                ao_m25_size[ao_m25_numchips] = size;
                        size = ao_m25_read_capacity(pin);
                        if (size != 0) {
                                ao_m25_size[ao_m25_numchips] = size;
@@ -221,7 +221,7 @@ ao_m25_scan(void)
                }
        }
 #else
                }
        }
 #else
-       ao_m25_total = ao_m25_read_capacity(M25_CS_MASK);
+       ao_m25_total = ao_m25_read_capacity(AO_M25_SPI_CS_MASK);
 #endif
        if (!ao_m25_total)
                return 0;
 #endif
        if (!ao_m25_total)
                return 0;
@@ -253,7 +253,7 @@ ao_storage_erase(uint32_t pos) __reentrant
 
        ao_m25_instruction[0] = M25_SE;
        M25_SELECT(cs);
 
        ao_m25_instruction[0] = M25_SE;
        M25_SELECT(cs);
-       ao_spi_send(ao_m25_instruction, 4);
+       ao_spi_send(ao_m25_instruction, 4, AO_M25_SPI_BUS);
        M25_DESELECT(cs);
        ao_m25_wip |= cs;
 
        M25_DESELECT(cs);
        ao_m25_wip |= cs;
 
@@ -280,8 +280,8 @@ ao_storage_device_write(uint32_t pos, __xdata void *d, uint16_t len) __reentrant
 
        ao_m25_instruction[0] = M25_PP;
        M25_SELECT(cs);
 
        ao_m25_instruction[0] = M25_PP;
        M25_SELECT(cs);
-       ao_spi_send(ao_m25_instruction, 4);
-       ao_spi_send(d, len);
+       ao_spi_send(ao_m25_instruction, 4, AO_M25_SPI_BUS);
+       ao_spi_send(d, len, AO_M25_SPI_BUS);
        M25_DESELECT(cs);
 
        ao_mutex_put(&ao_m25_mutex);
        M25_DESELECT(cs);
 
        ao_mutex_put(&ao_m25_mutex);
@@ -306,8 +306,8 @@ ao_storage_device_read(uint32_t pos, __xdata void *d, uint16_t len) __reentrant
        /* No need to use the FAST_READ as we're running at only 8MHz */
        ao_m25_instruction[0] = M25_READ;
        M25_SELECT(cs);
        /* No need to use the FAST_READ as we're running at only 8MHz */
        ao_m25_instruction[0] = M25_READ;
        M25_SELECT(cs);
-       ao_spi_send(ao_m25_instruction, 4);
-       ao_spi_recv(d, len);
+       ao_spi_send(ao_m25_instruction, 4, AO_M25_SPI_BUS);
+       ao_spi_recv(d, len, AO_M25_SPI_BUS);
        M25_DESELECT(cs);
 
        ao_mutex_put(&ao_m25_mutex);
        M25_DESELECT(cs);
 
        ao_mutex_put(&ao_m25_mutex);
@@ -350,14 +350,14 @@ ao_storage_device_info(void) __reentrant
 
        printf ("Available chips:\n");
        for (cs = 1; cs != 0; cs <<= 1) {
 
        printf ("Available chips:\n");
        for (cs = 1; cs != 0; cs <<= 1) {
-               if ((M25_CS_MASK & cs) == 0)
+               if ((AO_M25_SPI_CS_MASK & cs) == 0)
                        continue;
 
                ao_mutex_get(&ao_m25_mutex);
                M25_SELECT(cs);
                ao_m25_instruction[0] = M25_RDID;
                        continue;
 
                ao_mutex_get(&ao_m25_mutex);
                M25_SELECT(cs);
                ao_m25_instruction[0] = M25_RDID;
-               ao_spi_send(ao_m25_instruction, 1);
-               ao_spi_recv(ao_m25_instruction, M25_RDID_LEN);
+               ao_spi_send(ao_m25_instruction, 1, AO_M25_SPI_BUS);
+               ao_spi_recv(ao_m25_instruction, M25_RDID_LEN, AO_M25_SPI_BUS);
                M25_DESELECT(cs);
 
                printf ("Select %02x manf %02x type %02x cap %02x uid %02x\n",
                M25_DESELECT(cs);
 
                printf ("Select %02x manf %02x type %02x cap %02x uid %02x\n",
@@ -373,10 +373,5 @@ ao_storage_device_info(void) __reentrant
 void
 ao_storage_device_init(void)
 {
 void
 ao_storage_device_init(void)
 {
-       /* Set up chip select wires */
-       SPI_CS_PORT |= M25_CS_MASK;     /* raise all CS pins */
-       SPI_CS_DIR |= M25_CS_MASK;      /* set CS pins as outputs */
-#ifdef SPI_CS_SEL
-       SPI_CS_SEL &= ~M25_CS_MASK;     /* set CS pins as GPIO */
-#endif
+       ao_spi_init_cs (AO_M25_SPI_CS_PORT, AO_M25_SPI_CS_MASK);
 }
 }
index 877482724742d2d83845112adfba7ab9e7195f1c..3c0a310dfdc1e5650edd7adf7eebde0a8c40912a 100644 (file)
@@ -155,8 +155,5 @@ void
 ao_ms5607_init(void)
 {
        ao_cmd_register(&ao_ms5607_cmds[0]);
 ao_ms5607_init(void)
 {
        ao_cmd_register(&ao_ms5607_cmds[0]);
-
-       stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_GPIOCEN);
-       stm_gpio_set(&AO_MS5607_CS_GPIO, AO_MS5607_CS, 1);
-       stm_moder_set(&AO_MS5607_CS_GPIO, AO_MS5607_CS, STM_MODER_OUTPUT);
+       ao_spi_init_cs(AO_MS5607_CS_GPIO, (1 << AO_MS5607_CS));
 }
 }
index 5b20a8a5adc842949de82fba58cd2a5cd1ed312c..b0f2a61211fb37c2000bbf43ba0e2f9ceda15157 100644 (file)
@@ -38,7 +38,9 @@ ALTOS_SRC = \
        ao_spi_stm.c \
        ao_ms5607.c \
        ao_adc_stm.c \
        ao_spi_stm.c \
        ao_ms5607.c \
        ao_adc_stm.c \
-       ao_beep_stm.c
+       ao_beep_stm.c \
+       ao_storage.c \
+       ao_m25.c
 
 PRODUCT=MegaMetrum-v0.1
 PRODUCT_DEF=-DMEGAMETRUM
 
 PRODUCT=MegaMetrum-v0.1
 PRODUCT_DEF=-DMEGAMETRUM
index eaab9b50ade2c08772ea116542fe47a0453951e3..77a2bf0a111f72901c1347f9ddb9502dde14a6f3 100644 (file)
@@ -49,6 +49,7 @@ main(void)
        ao_ms5607_init();
        ao_beep_init();
        ao_adc_init();
        ao_ms5607_init();
        ao_beep_init();
        ao_adc_init();
+       ao_storage_init();
        
        ao_cmd_register(&ao_mm_cmds[0]);
        ao_start_scheduler();
        
        ao_cmd_register(&ao_mm_cmds[0]);
        ao_start_scheduler();
index e200a692eb4cb56e6d04ce4ff3d2360050367264..46098d34689d060af88bdb24b6b762ab2d676835 100644 (file)
@@ -182,4 +182,13 @@ struct ao_adc {
 #define AO_MS5607_CS_MASK      (1 << AO_MS5607_CS)
 #define AO_MS5607_SPI_INDEX    (STM_SPI_INDEX(1))
 
 #define AO_MS5607_CS_MASK      (1 << AO_MS5607_CS)
 #define AO_MS5607_SPI_INDEX    (STM_SPI_INDEX(1))
 
+/*
+ * SPI Flash memory
+ */
+
+#define M25_MAX_CHIPS          1
+#define AO_M25_SPI_CS_PORT     stm_gpiod
+#define AO_M25_SPI_CS_MASK     (1 << 3)
+#define AO_M25_SPI_BUS         STM_SPI_INDEX(2)
+
 #endif /* _AO_PINS_H_ */
 #endif /* _AO_PINS_H_ */
index 052abb6591bb126e5a8fed800188726492ed43cd..309937d58180545bad3e309186e7e9a231175516 100644 (file)
@@ -37,6 +37,55 @@ ao_spi_recv(void *block, uint16_t len, uint8_t spi_index);
 void
 ao_spi_init(void);
 
 void
 ao_spi_init(void);
 
+#define ao_spi_get_mask(reg,mask,bus) do {             \
+               ao_spi_get(bus);                        \
+               (reg).bsrr = ((uint32_t) mask) << 16;   \
+       } while (0)
+
+#define ao_spi_put_mask(reg,mask,bus) do {     \
+               (reg).bsrr = mask;              \
+               ao_spi_put(bus);                \
+       } while (0)
+
+#define ao_stm_enable_port(port) do {                                  \
+               if (&(port) == &stm_gpioa)                              \
+                       stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_GPIOAEN); \
+               else if (&(port) == &stm_gpiob)                         \
+                       stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_GPIOBEN); \
+               else if (&(port) == &stm_gpioc)                         \
+                       stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_GPIOCEN); \
+               else if (&(port) == &stm_gpiod)                         \
+                       stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_GPIODEN); \
+               else if (&(port) == &stm_gpioe)                         \
+                       stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_GPIOEEN); \
+       } while (0)
+
+
+#define ao_stm_enable_cs(port,bit) do {                                \
+               stm_gpio_set(&(port), bit, 1);                  \
+               stm_moder_set(&(port), bit, STM_MODER_OUTPUT);  \
+       } while (0)
+
+#define ao_spi_init_cs(port, mask) do {                                \
+               ao_stm_enable_port(port);                       \
+               if (mask & 0x0001) ao_stm_enable_cs(port, 0);   \
+               if (mask & 0x0002) ao_stm_enable_cs(port, 1);   \
+               if (mask & 0x0004) ao_stm_enable_cs(port, 2);   \
+               if (mask & 0x0008) ao_stm_enable_cs(port, 3);   \
+               if (mask & 0x0010) ao_stm_enable_cs(port, 4);   \
+               if (mask & 0x0020) ao_stm_enable_cs(port, 5);   \
+               if (mask & 0x0040) ao_stm_enable_cs(port, 6);   \
+               if (mask & 0x0080) ao_stm_enable_cs(port, 7);   \
+               if (mask & 0x0100) ao_stm_enable_cs(port, 8);   \
+               if (mask & 0x0200) ao_stm_enable_cs(port, 9);   \
+               if (mask & 0x0400) ao_stm_enable_cs(port, 10);  \
+               if (mask & 0x0800) ao_stm_enable_cs(port, 11);  \
+               if (mask & 0x1000) ao_stm_enable_cs(port, 12);  \
+               if (mask & 0x2000) ao_stm_enable_cs(port, 13);  \
+               if (mask & 0x4000) ao_stm_enable_cs(port, 14);  \
+               if (mask & 0x8000) ao_stm_enable_cs(port, 15);  \
+       } while (0)
+
 /* ao_dma_stm.c
  */
 
 /* ao_dma_stm.c
  */
 
index 44a372cc090da03b2836ef248a155a168c5d8374..29b97385a4ae229772c1e84c57499588382001bb 100644 (file)
 #define AO_IGNITER_FIRE_TIME   AO_MS_TO_TICKS(50)
 #define AO_IGNITER_CHARGE_TIME AO_MS_TO_TICKS(2000)
 
 #define AO_IGNITER_FIRE_TIME   AO_MS_TO_TICKS(50)
 #define AO_IGNITER_CHARGE_TIME AO_MS_TO_TICKS(2000)
 
+#define AO_M25_SPI_CS_PORT     SPI_CS_PORT
+#define AO_M25_SPI_CS_MASK     M25_CS_MASK
+
 #endif /* _AO_PINS_H_ */
 #endif /* _AO_PINS_H_ */