static uint8_t ao_i2c_state[STM_NUM_I2C];
static uint16_t ao_i2c_addr[STM_NUM_I2C];
uint8_t ao_i2c_mutex[STM_NUM_I2C];
+static void (*ao_i2c_callback[STM_NUM_I2C])(uint8_t index);
#define AO_STM_I2C_CR1 ((0 << STM_I2C_CR1_SWRST) | \
(0 << STM_I2C_CR1_ALERT) | \
stm_i2c->dr = dr;
}
-uint8_t
-ao_i2c_start(uint8_t index, uint16_t addr)
+void
+ao_i2c_queue_start(uint8_t index, uint16_t addr)
{
struct stm_i2c *stm_i2c = ao_i2c_stm_info[index].stm_i2c;
uint32_t sr1, sr2;
AO_STM_I2C_CR1 | (1 << STM_I2C_CR1_START));
out_cr2("start", stm_i2c,
AO_STM_I2C_CR2 | (1 << STM_I2C_CR2_ITEVTEN) | (1 << STM_I2C_CR2_ITERREN));
+}
+
+void
+ao_i2c_set_start_callback(uint8_t index, void (*callback)(uint8_t index))
+{
+
+}
+
+uint8_t
+ao_i2c_is_idle(uint8_t index)
+{
+ return ao_i2c_state[index] == I2C_IDLE;
+}
+
+uint8_t
+ao_i2c_start(uint8_t index, uint16_t addr)
+{
+ ao_i2c_queue_start(index, addr);
+
ao_alarm(1);
cli();
- while (ao_i2c_state[index] == I2C_IDLE)
+ while (ao_i2c_is_idle(index))
if (ao_sleep(&ao_i2c_state[index]))
break;
sei();
};
uint8_t ao_spi_mutex[STM_NUM_SPI];
+static void (*ao_spi_callback[STM_NUM_SPI])(int spi_index);
static const struct ao_spi_stm_info ao_spi_stm_info[STM_NUM_SPI] = {
{
static uint8_t spi_dev_null;
-void
-ao_spi_send(void *block, uint16_t len, uint8_t spi_index)
+static void
+ao_spi_setup_send(void *block, uint16_t len, uint8_t spi_index)
{
struct stm_spi *stm_spi = ao_spi_stm_info[spi_index].stm_spi;
uint8_t mosi_dma_index = ao_spi_stm_info[spi_index].mosi_dma_index;
(0 << STM_SPI_CR2_SSOE) |
(1 << STM_SPI_CR2_TXDMAEN) |
(1 << STM_SPI_CR2_RXDMAEN));
+}
+
+static void
+ao_spi_start_send(uint8_t spi_index)
+{
+ uint8_t mosi_dma_index = ao_spi_stm_info[spi_index].mosi_dma_index;
+ uint8_t miso_dma_index = ao_spi_stm_info[spi_index].miso_dma_index;
+
ao_dma_start(miso_dma_index);
ao_dma_start(mosi_dma_index);
+}
+
+static void
+ao_spi_finish_send(uint8_t spi_index)
+{
+ uint8_t mosi_dma_index = ao_spi_stm_info[spi_index].mosi_dma_index;
+ uint8_t miso_dma_index = ao_spi_stm_info[spi_index].miso_dma_index;
+
+ ao_dma_done_transfer(mosi_dma_index);
+ ao_dma_done_transfer(miso_dma_index);
+}
+
+void
+ao_spi_dma_isr(int spi_index)
+{
+ ao_spi_callback[spi_index](spi_index);
+ ao_spi_finish_send(spi_index);
+}
+
+void
+ao_spi_queue_send(void *block, uint16_t len, uint8_t spi_index,
+ void (*callback)(int spi_index))
+{
+ uint8_t miso_dma_index = ao_spi_stm_info[spi_index].miso_dma_index;
+
+ ao_spi_setup_send(block, len, spi_index);
+ ao_spi_callback[spi_index] = callback;
+ ao_dma_set_isr(miso_dma_index, ao_spi_dma_isr, spi_index);
+ ao_spi_start_send(spi_index);
+}
+
+void
+ao_spi_send(void *block, uint16_t len, uint8_t spi_index)
+{
+ uint8_t mosi_dma_index = ao_spi_stm_info[spi_index].mosi_dma_index;
+ uint8_t miso_dma_index = ao_spi_stm_info[spi_index].miso_dma_index;
+
+ ao_spi_setup_send(block, len, spi_index);
+ ao_spi_start_send(spi_index);
ao_arch_critical(
while (!ao_dma_done[miso_dma_index])
ao_sleep(&ao_dma_done[miso_dma_index]);
);
- ao_dma_done_transfer(mosi_dma_index);
- ao_dma_done_transfer(miso_dma_index);
+
+ ao_spi_finish_send(spi_index);
}
void
ao_dma_done_transfer(miso_dma_index);
}
-void
-ao_spi_recv(void *block, uint16_t len, uint8_t spi_index)
+static void
+ao_spi_setup_recv(void *block, uint16_t len, uint8_t spi_index)
{
struct stm_spi *stm_spi = ao_spi_stm_info[spi_index].stm_spi;
uint8_t mosi_dma_index = ao_spi_stm_info[spi_index].mosi_dma_index;
(0 << STM_SPI_CR2_SSOE) |
(1 << STM_SPI_CR2_TXDMAEN) |
(1 << STM_SPI_CR2_RXDMAEN));
+}
+
+static void
+ao_spi_start_recv(uint8_t spi_index)
+{
+ uint8_t mosi_dma_index = ao_spi_stm_info[spi_index].mosi_dma_index;
+ uint8_t miso_dma_index = ao_spi_stm_info[spi_index].miso_dma_index;
ao_dma_start(miso_dma_index);
ao_dma_start(mosi_dma_index);
+}
+
+static void
+ao_spi_done_recv(uint8_t spi_index)
+{
+ uint8_t mosi_dma_index = ao_spi_stm_info[spi_index].mosi_dma_index;
+ uint8_t miso_dma_index = ao_spi_stm_info[spi_index].miso_dma_index;
+ ao_dma_done_transfer(mosi_dma_index);
+ ao_dma_done_transfer(miso_dma_index);
+}
+void
+ao_spi_queue_recv(void *block, uint16_t len, uint8_t spi_index, void (*callback)(int spi_index))
+{
+ uint8_t miso_dma_index = ao_spi_stm_info[spi_index].miso_dma_index;
+ ao_spi_setup_recv(block, len, spi_index);
+ ao_spi_callback[spi_index] = callback;
+ ao_dma_set_isr(miso_dma_index, ao_spi_dma_isr, spi_index);
+ ao_spi_start_recv(spi_index);
+}
+
+void
+ao_spi_recv(void *block, uint16_t len, uint8_t spi_index)
+{
+ uint8_t miso_dma_index = ao_spi_stm_info[spi_index].miso_dma_index;
+ ao_spi_setup_recv(block, len, spi_index);
+ ao_spi_start_recv(spi_index);
/* Wait until the SPI unit is done */
ao_arch_critical(
while (!ao_dma_done[miso_dma_index])
ao_sleep(&ao_dma_done[miso_dma_index]);
);
-
- ao_dma_done_transfer(mosi_dma_index);
- ao_dma_done_transfer(miso_dma_index);
+ ao_spi_done_recv(spi_index);
}
void