altos/stmf0: Add casts to reduce -Wconversion warnings. Use AO_TICK_TYPE
[fw/altos] / src / stmf0 / ao_arch_funcs.h
index 01d51f90c17970b68140eaeef2b5342a7284de1d..8a173b57e5be79e928bebb5acf6ffb0bc1fa3d72 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(uint32_t hz)
+{
+       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);
@@ -132,7 +151,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 +160,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 +185,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 +215,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 +255,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 {                                \
@@ -379,15 +398,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 *) ((void *) task->stack + AO_STACK_SIZE);
        uint32_t        a = (uint32_t) start;
        int             i;
 
@@ -405,7 +423,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) {
@@ -424,17 +442,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}");
@@ -448,6 +463,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
@@ -488,14 +531,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_ */