altos: Eliminate 'pin' field from GPIO functions
[fw/altos] / src / stmf0 / ao_arch_funcs.h
index a5c6764b17b57b6151ffd8cee123364c34098257..70f273d3ba46ce081ca8326113c16582668ca627 100644 (file)
@@ -3,7 +3,8 @@
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
  *
  * This program is distributed in the hope that it will be useful, but
  * WITHOUT ANY WARRANTY; without even the implied warranty of
 #ifndef _AO_ARCH_FUNCS_H_
 #define _AO_ARCH_FUNCS_H_
 
+#include <ao_power.h>
+
 /* ao_spi_stm.c
  */
 
-/* PCLK is set to 16MHz (HCLK 32MHz, APB prescaler 2) */
+/* PCLK is set to 48MHz (HCLK 48MHz, HPRE 1, PPRE 1) */
 
-#define AO_SPI_SPEED_8MHz      STM_SPI_CR1_BR_PCLK_2
-#define AO_SPI_SPEED_4MHz      STM_SPI_CR1_BR_PCLK_4
-#define AO_SPI_SPEED_2MHz      STM_SPI_CR1_BR_PCLK_8
-#define AO_SPI_SPEED_1MHz      STM_SPI_CR1_BR_PCLK_16
-#define AO_SPI_SPEED_500kHz    STM_SPI_CR1_BR_PCLK_32
-#define AO_SPI_SPEED_250kHz    STM_SPI_CR1_BR_PCLK_64
-#define AO_SPI_SPEED_125kHz    STM_SPI_CR1_BR_PCLK_128
-#define AO_SPI_SPEED_62500Hz   STM_SPI_CR1_BR_PCLK_256
+#define AO_SPI_SPEED_24MHz     STM_SPI_CR1_BR_PCLK_2
+#define AO_SPI_SPEED_12MHz     STM_SPI_CR1_BR_PCLK_4
+#define AO_SPI_SPEED_6MHz      STM_SPI_CR1_BR_PCLK_8
+#define AO_SPI_SPEED_3MHz      STM_SPI_CR1_BR_PCLK_16
+#define AO_SPI_SPEED_1500kHz   STM_SPI_CR1_BR_PCLK_32
+#define AO_SPI_SPEED_750kHz    STM_SPI_CR1_BR_PCLK_64
+#define AO_SPI_SPEED_375kHz    STM_SPI_CR1_BR_PCLK_128
+#define AO_SPI_SPEED_187500Hz  STM_SPI_CR1_BR_PCLK_256
 
-#define AO_SPI_SPEED_FAST      AO_SPI_SPEED_8MHz
+#define AO_SPI_SPEED_FAST      AO_SPI_SPEED_24MHz
 
 /* Companion bus wants something no faster than 200kHz */
 
-#define AO_SPI_SPEED_200kHz    AO_SPI_SPEED_125kHz
+#define AO_SPI_SPEED_200kHz    AO_SPI_SPEED_187500Hz
 
 #define AO_SPI_CONFIG_1                0x00
 #define AO_SPI_1_CONFIG_PA5_PA6_PA7    AO_SPI_CONFIG_1
@@ -80,7 +83,57 @@ void
 ao_spi_send_fixed(uint8_t value, uint16_t len, uint8_t spi_index);
 
 void
-ao_spi_send_sync(void *block, uint16_t len, uint8_t spi_index);
+ao_spi_send_sync(const void *block, uint16_t len, uint8_t spi_index);
+
+void
+ao_spi_start_bytes(uint8_t spi_index);
+
+void
+ao_spi_stop_bytes(uint8_t spi_index);
+
+static inline void
+ao_spi_send_byte(uint8_t byte, uint8_t spi_index)
+{
+       struct stm_spi  *stm_spi;
+
+       switch (AO_SPI_INDEX(spi_index)) {
+       case 0:
+               stm_spi = &stm_spi1;
+               break;
+       case 1:
+               stm_spi = &stm_spi2;
+               break;
+       }
+
+       while (!(stm_spi->sr & (1 << STM_SPI_SR_TXE)))
+               ;
+       stm_spi->dr = byte;
+       while (!(stm_spi->sr & (1 << STM_SPI_SR_RXNE)))
+               ;
+       (void) stm_spi->dr;
+}
+
+static inline uint8_t
+ao_spi_recv_byte(uint8_t spi_index)
+{
+       struct stm_spi  *stm_spi;
+
+       switch (AO_SPI_INDEX(spi_index)) {
+       case 0:
+               stm_spi = &stm_spi1;
+               break;
+       case 1:
+               stm_spi = &stm_spi2;
+               break;
+       }
+
+       while (!(stm_spi->sr & (1 << STM_SPI_SR_TXE)))
+               ;
+       stm_spi->dr = 0xff;
+       while (!(stm_spi->sr & (1 << STM_SPI_SR_RXNE)))
+               ;
+       return stm_spi->dr;
+}
 
 void
 ao_spi_recv(void *block, uint16_t len, uint8_t spi_index);
@@ -115,38 +168,57 @@ ao_spi_try_get_mask(struct stm_gpio *reg, uint16_t mask, uint8_t bus, uint32_t s
                ao_spi_put(bus);                \
        } while (0)
 
-#define ao_spi_get_bit(reg,bit,pin,bus,speed) ao_spi_get_mask(reg,(1<<bit),bus,speed)
-#define ao_spi_put_bit(reg,bit,pin,bus) ao_spi_put_mask(reg,(1<<bit),bus)
-
-#define ao_enable_port(port) do {                                      \
-               if ((port) == &stm_gpioa)                               \
-                       stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_IOPAEN); \
-               else if ((port) == &stm_gpiob)                          \
-                       stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_IOPBEN); \
-               else if ((port) == &stm_gpioc)                          \
-                       stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_IOPCEN); \
-               else if ((port) == &stm_gpiof)                          \
-                       stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_IOPFEN); \
-       } while (0)
+#define ao_spi_get_bit(reg,bit,bus,speed) ao_spi_get_mask(reg,(1<<bit),bus,speed)
+#define ao_spi_put_bit(reg,bit,bus) ao_spi_put_mask(reg,(1<<bit),bus)
 
-#define ao_disable_port(port) do {                                     \
-               if ((port) == &stm_gpioa)                               \
-                       stm_rcc.ahbenr &= ~(1 << STM_RCC_AHBENR_IOPAEN); \
-               else if ((port) == &stm_gpiob)                          \
-                       stm_rcc.ahbenr &= ~(1 << STM_RCC_AHBENR_IOPBEN); \
-               else if ((port) == &stm_gpioc)                          \
-                       stm_rcc.ahbenr &= ~(1 << STM_RCC_AHBENR_IOPCEN); \
-               else if ((port) == &stm_gpiof)                          \
-                       stm_rcc.ahbenr &= ~(1 << STM_RCC_AHBENR_IOPFEN); \
-       } while (0)
+#if AO_POWER_MANAGEMENT
+extern struct ao_power ao_power_gpioa;
+extern struct ao_power ao_power_gpiob;
+extern struct ao_power ao_power_gpioc;
+extern struct ao_power ao_power_gpiof;
+#endif
 
-#define ao_gpio_set(port, bit, pin, v) stm_gpio_set(port, bit, v)
+static inline void ao_enable_port(struct stm_gpio *port)
+{
+       if ((port) == &stm_gpioa) {
+               stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_IOPAEN);
+               ao_power_register(&ao_power_gpioa);
+       } else if ((port) == &stm_gpiob) {
+               stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_IOPBEN);
+               ao_power_register(&ao_power_gpiob);
+       } else if ((port) == &stm_gpioc) {
+               stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_IOPCEN);
+               ao_power_register(&ao_power_gpioc);
+       } else if ((port) == &stm_gpiof) {
+               stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_IOPFEN);
+               ao_power_register(&ao_power_gpiof);
+       }
+}
+
+static inline void ao_disable_port(struct stm_gpio *port)
+{
+       if ((port) == &stm_gpioa) {
+               stm_rcc.ahbenr &= ~(1 << STM_RCC_AHBENR_IOPAEN);
+               ao_power_unregister(&ao_power_gpioa);
+       } else if ((port) == &stm_gpiob) {
+               stm_rcc.ahbenr &= ~(1 << STM_RCC_AHBENR_IOPBEN);
+               ao_power_unregister(&ao_power_gpiob);
+       } else if ((port) == &stm_gpioc) {
+               stm_rcc.ahbenr &= ~(1 << STM_RCC_AHBENR_IOPCEN);
+               ao_power_unregister(&ao_power_gpioc);
+       } else if ((port) == &stm_gpiof) {
+               stm_rcc.ahbenr &= ~(1 << STM_RCC_AHBENR_IOPFEN);
+               ao_power_unregister(&ao_power_gpiof);
+       }
+}
 
-#define ao_gpio_get(port, bit, pin) stm_gpio_get(port, bit)
+#define ao_gpio_set(port, bit, v) stm_gpio_set(port, bit, v)
 
-#define ao_enable_output(port,bit,pin,v) do {                  \
+#define ao_gpio_get(port, bit) stm_gpio_get(port, bit)
+
+#define ao_enable_output(port,bit,v) do {                      \
                ao_enable_port(port);                           \
-               ao_gpio_set(port, bit, pin, v);                 \
+               ao_gpio_set(port, bit, v);                      \
                stm_moder_set(port, bit, STM_MODER_OUTPUT);\
        } while (0)
 
@@ -166,8 +238,7 @@ ao_spi_try_get_mask(struct stm_gpio *reg, uint16_t mask, uint8_t bus, uint32_t s
        } while (0)
 
 #define ao_enable_cs(port,bit) do {                            \
-               stm_gpio_set((port), bit, 1);                   \
-               stm_moder_set((port), bit, STM_MODER_OUTPUT);   \
+               ao_enable_output(port, bit, 1);         \
        } while (0)
 
 #define ao_spi_init_cs(port, mask) do {                                \
@@ -241,11 +312,43 @@ void
 ao_i2c_init(void);
 
 /* ao_serial_stm.c */
+
+#if USE_SERIAL_1_FLOW && USE_SERIAL_1_SW_FLOW || USE_SERIAL_2_FLOW && USE_SERIAL_2_SW_FLOW
+#define HAS_SERIAL_SW_FLOW     1
+#else
+#define HAS_SERIAL_SW_FLOW     0
+#endif
+
+#if USE_SERIAL_2_FLOW && !USE_SERIAL_2_SW_FLOW
+#define USE_SERIAL_2_HW_FLOW   1
+#endif
+
+#if USE_SERIAL_1_FLOW && !USE_SERIAL_1_SW_FLOW
+#define USE_SERIAL_1_HW_FLOW   1
+#endif
+
+#if USE_SERIAL_1_HW_FLOW || USE_SERIAL_2_HW_FLOW
+#define HAS_SERIAL_HW_FLOW     1
+#else
+#define HAS_SERIAL_HW_FLOW     0
+#endif
+
 struct ao_stm_usart {
        struct ao_fifo          rx_fifo;
        struct ao_fifo          tx_fifo;
        struct stm_usart        *reg;
-       uint8_t                 tx_started;
+       uint8_t                 tx_running;
+       uint8_t                 draining;
+#if HAS_SERIAL_SW_FLOW
+       /* RTS - 0 if we have FIFO space, 1 if not
+        * CTS - 0 if we can send, 0 if not
+        */
+       struct stm_gpio         *gpio_rts;
+       struct stm_gpio         *gpio_cts;
+       uint8_t                 pin_rts;
+       uint8_t                 pin_cts;
+       uint8_t                 rts;
+#endif
 };
 
 #if HAS_SERIAL_1
@@ -286,7 +389,7 @@ ao_arch_memory_barrier() {
 static inline void
 ao_arch_init_stack(struct ao_task *task, void *start)
 {
-       uint32_t        *sp = (uint32_t *) (task->stack + AO_STACK_SIZE);
+       uint32_t        *sp = (uint32_t *) ((void *) task->stack + AO_STACK_SIZE);
        uint32_t        a = (uint32_t) start;
        int             i;
 
@@ -384,4 +487,20 @@ static inline void ao_arch_start_scheduler(void) {
                ao_arch_irqrestore(__mask);             \
        } while (0)
 
+/* ao_usb_stm.c */
+
+#if AO_USB_DIRECTIO
+uint8_t
+ao_usb_alloc(uint16_t *buffers[2]);
+
+uint8_t
+ao_usb_alloc2(uint16_t *buffers[2]);
+
+uint8_t
+ao_usb_write(uint16_t len);
+
+uint8_t
+ao_usb_write2(uint16_t len);
+#endif /* AO_USB_DIRECTIO */
+
 #endif /* _AO_ARCH_FUNCS_H_ */