altosui: Add config and pyro tabs to graph widget
[fw/altos] / src / stmf0 / ao_arch_funcs.h
index 8b6234c4e995709da15b1df949b1daf4fc7122fb..953a0c00c2a69ad107124a91b337bb04ed05256e 100644 (file)
 
 /* PCLK is set to 48MHz (HCLK 48MHz, HPRE 1, PPRE 1) */
 
-#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_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_24MHz
-
-/* Companion bus wants something no faster than 200kHz */
-
-#define AO_SPI_SPEED_200kHz    AO_SPI_SPEED_187500Hz
+static inline uint32_t
+ao_spi_speed(int index, uint32_t hz)
+{
+       (void) index;
+       if (hz >=24000000) return _AO_SPI_SPEED_24MHz;
+       if (hz >=12000000) return _AO_SPI_SPEED_12MHz;
+       if (hz >= 6000000) return _AO_SPI_SPEED_6MHz;
+       if (hz >= 3000000) return _AO_SPI_SPEED_3MHz;
+       if (hz >= 1500000) return _AO_SPI_SPEED_1500kHz;
+       if (hz >=  750000) return _AO_SPI_SPEED_750kHz;
+       if (hz >=  375000) return _AO_SPI_SPEED_375kHz;
+       return _AO_SPI_SPEED_187500Hz;
+}
 
 #define AO_SPI_CONFIG_1                0x00
 #define AO_SPI_1_CONFIG_PA5_PA6_PA7    AO_SPI_CONFIG_1
 
 #define AO_SPI_INDEX(id)       ((id) & AO_SPI_INDEX_MASK)
 #define AO_SPI_CONFIG(id)      ((id) & AO_SPI_CONFIG_MASK)
+#define AO_SPI_PIN_CONFIG(id)  ((id) & (AO_SPI_INDEX_MASK | AO_SPI_CONFIG_MASK))
+
+#define AO_SPI_CPOL_BIT                4
+#define AO_SPI_CPHA_BIT                5
+#define AO_SPI_CPOL(id)                ((uint32_t) (((id) >> AO_SPI_CPOL_BIT) & 1))
+#define AO_SPI_CPHA(id)                ((uint32_t) (((id) >> AO_SPI_CPHA_BIT) & 1))
+
+#define AO_SPI_MAKE_MODE(pol,pha)      (((pol) << AO_SPI_CPOL_BIT) | ((pha) << AO_SPI_CPHA_BIT))
+#define AO_SPI_MODE_0          AO_SPI_MAKE_MODE(0,0)
+#define AO_SPI_MODE_1          AO_SPI_MAKE_MODE(0,1)
+#define AO_SPI_MODE_2          AO_SPI_MAKE_MODE(1,0)
+#define AO_SPI_MODE_3          AO_SPI_MAKE_MODE(1,1)
 
 uint8_t
 ao_spi_try_get(uint8_t spi_index, uint32_t speed, uint8_t task_id);
@@ -76,6 +96,9 @@ ao_spi_get(uint8_t spi_index, uint32_t speed);
 void
 ao_spi_put(uint8_t spi_index);
 
+void
+ao_spi_put_pins(uint8_t spi_index);
+
 void
 ao_spi_send(const void *block, uint16_t len, uint8_t spi_index);
 
@@ -132,7 +155,7 @@ ao_spi_recv_byte(uint8_t spi_index)
        stm_spi->dr = 0xff;
        while (!(stm_spi->sr & (1 << STM_SPI_SR_RXNE)))
                ;
-       return stm_spi->dr;
+       return (uint8_t) stm_spi->dr;
 }
 
 void
@@ -141,8 +164,6 @@ 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[STM_NUM_SPI];
-
 void
 ao_spi_init(void);
 
@@ -168,13 +189,15 @@ 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_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)
 
+#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
 
 static inline void ao_enable_port(struct stm_gpio *port)
 {
@@ -196,27 +219,27 @@ static inline void ao_enable_port(struct stm_gpio *port)
 static inline void ao_disable_port(struct stm_gpio *port)
 {
        if ((port) == &stm_gpioa) {
-               stm_rcc.ahbenr &= ~(1 << STM_RCC_AHBENR_IOPAEN);
+               stm_rcc.ahbenr &= ~(1UL << STM_RCC_AHBENR_IOPAEN);
                ao_power_unregister(&ao_power_gpioa);
        } else if ((port) == &stm_gpiob) {
-               stm_rcc.ahbenr &= ~(1 << STM_RCC_AHBENR_IOPBEN);
+               stm_rcc.ahbenr &= ~(1UL << STM_RCC_AHBENR_IOPBEN);
                ao_power_unregister(&ao_power_gpiob);
        } else if ((port) == &stm_gpioc) {
-               stm_rcc.ahbenr &= ~(1 << STM_RCC_AHBENR_IOPCEN);
+               stm_rcc.ahbenr &= ~(1UL << STM_RCC_AHBENR_IOPCEN);
                ao_power_unregister(&ao_power_gpioc);
        } else if ((port) == &stm_gpiof) {
-               stm_rcc.ahbenr &= ~(1 << STM_RCC_AHBENR_IOPFEN);
+               stm_rcc.ahbenr &= ~(1UL << STM_RCC_AHBENR_IOPFEN);
                ao_power_unregister(&ao_power_gpiof);
        }
 }
 
-#define ao_gpio_set(port, bit, pin, v) stm_gpio_set(port, bit, v)
+#define ao_gpio_set(port, bit, v) stm_gpio_set(port, bit, v)
 
-#define ao_gpio_get(port, bit, pin) stm_gpio_get(port, bit)
+#define ao_gpio_get(port, bit) stm_gpio_get(port, bit)
 
-#define ao_enable_output(port,bit,pin,v) do {                  \
+#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)
 
@@ -236,7 +259,7 @@ static inline void ao_disable_port(struct stm_gpio *port)
        } while (0)
 
 #define ao_enable_cs(port,bit) do {                            \
-               ao_enable_output(port, bit, pin, 1);            \
+               ao_enable_output(port, bit, 1);         \
        } while (0)
 
 #define ao_spi_init_cs(port, mask) do {                                \
@@ -310,11 +333,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
@@ -347,15 +402,14 @@ ao_arch_irqrestore(uint32_t primask) {
 }
 
 static inline void
-ao_arch_memory_barrier() {
+ao_arch_memory_barrier(void) {
        asm volatile("" ::: "memory");
 }
 
 #if HAS_TASK
 static inline void
-ao_arch_init_stack(struct ao_task *task, void *start)
+ao_arch_init_stack(struct ao_task *task, uint32_t *sp, void *start)
 {
-       uint32_t        *sp = (uint32_t *) (task->stack + AO_STACK_SIZE);
        uint32_t        a = (uint32_t) start;
        int             i;
 
@@ -373,7 +427,7 @@ ao_arch_init_stack(struct ao_task *task, void *start)
        /* PRIMASK with interrupts enabled */
        ARM_PUSH32(sp, 0);
 
-       task->sp = sp;
+       task->sp32 = sp;
 }
 
 static inline void ao_arch_save_regs(void) {
@@ -392,17 +446,14 @@ static inline void ao_arch_save_regs(void) {
 static inline void ao_arch_save_stack(void) {
        uint32_t        *sp;
        asm("mov %0,sp" : "=&r" (sp) );
-       ao_cur_task->sp = (sp);
-       if ((uint8_t *) sp < &ao_cur_task->stack[0])
+       ao_cur_task->sp32 = (sp);
+       if (sp < &ao_cur_task->stack32[0])
                ao_panic (AO_PANIC_STACK);
 }
 
 static inline void ao_arch_restore_stack(void) {
-       uint32_t        sp;
-       sp = (uint32_t) ao_cur_task->sp;
-
        /* Switch stacks */
-       asm("mov sp, %0" : : "r" (sp) );
+       asm("mov sp, %0" : : "r" (ao_cur_task->sp32) );
 
        /* Restore PRIMASK */
        asm("pop {r0}");
@@ -416,6 +467,34 @@ static inline void ao_arch_restore_stack(void) {
        asm("pop {r0-r7,pc}\n");
 }
 
+static inline void ao_sleep_mode(void) {
+
+       /*
+         WFI (Wait for Interrupt) or WFE (Wait for Event) while:
+          – Set SLEEPDEEP in Cortex ® -M0 System Control register
+          – Set PDDS bit in Power Control register (PWR_CR)
+          – Clear WUF bit in Power Control/Status register (PWR_CSR)
+       */
+
+       ao_arch_block_interrupts();
+
+       /* Enable power interface clock */
+       stm_rcc.apb1enr |= (1 << STM_RCC_APB1ENR_PWREN);
+       ao_arch_nop();
+       stm_scb.scr |= (1 << STM_SCB_SCR_SLEEPDEEP);
+       ao_arch_nop();
+       stm_pwr.cr |= (1 << STM_PWR_CR_PDDS) | (1 << STM_PWR_CR_LPDS);
+       ao_arch_nop();
+       stm_pwr.cr |= (1 << STM_PWR_CR_CWUF);
+       ao_arch_nop();
+       ao_arch_nop();
+       ao_arch_nop();
+       ao_arch_nop();
+       ao_arch_nop();
+       asm("wfi");
+       ao_arch_nop();
+}
+
 #ifndef HAS_SAMPLE_PROFILE
 #define HAS_SAMPLE_PROFILE 0
 #endif
@@ -456,14 +535,22 @@ static inline void ao_arch_start_scheduler(void) {
 /* ao_usb_stm.c */
 
 #if AO_USB_DIRECTIO
-uint16_t *
-ao_usb_alloc(void);
+uint8_t
+ao_usb_alloc(uint16_t *buffers[2]);
 
-void
-ao_usb_write(uint16_t *buffer, uint16_t len);
+uint8_t
+ao_usb_alloc2(uint16_t *buffers[2]);
 
-void
-ao_usb_write2(uint16_t *buffer, uint16_t len);
+uint8_t
+ao_usb_write(uint16_t len);
+
+uint8_t
+ao_usb_write2(uint16_t len);
 #endif /* AO_USB_DIRECTIO */
 
+void start(void);
+
+void
+ao_debug_out(char c);
+
 #endif /* _AO_ARCH_FUNCS_H_ */