X-Git-Url: https://git.gag.com/?p=fw%2Faltos;a=blobdiff_plain;f=src%2Fstm%2Fao_arch_funcs.h;h=087e00d91da77d13075a80fa98c9234884a04a02;hp=d17793076f38ca177e60f66082288c607044d1b5;hb=7348cc4736c9a94f9ad299edd78199b544d0e95a;hpb=760b1f02c178c600226f39b5e66d8cbadbf4a29b diff --git a/src/stm/ao_arch_funcs.h b/src/stm/ao_arch_funcs.h index d1779307..087e00d9 100644 --- a/src/stm/ao_arch_funcs.h +++ b/src/stm/ao_arch_funcs.h @@ -64,6 +64,9 @@ #define AO_SPI_INDEX(id) ((id) & AO_SPI_INDEX_MASK) #define AO_SPI_CONFIG(id) ((id) & AO_SPI_CONFIG_MASK) +uint8_t +ao_spi_try_get(uint8_t spi_index, uint32_t speed, uint8_t task_id); + void ao_spi_get(uint8_t spi_index, uint32_t speed); @@ -71,11 +74,42 @@ void ao_spi_put(uint8_t spi_index); void -ao_spi_send(void *block, uint16_t len, uint8_t spi_index); +ao_spi_send(const void *block, uint16_t len, uint8_t spi_index); 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); + +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; + } + + stm_spi->cr2 = ((0 << STM_SPI_CR2_TXEIE) | + (0 << STM_SPI_CR2_RXNEIE) | + (0 << STM_SPI_CR2_ERRIE) | + (0 << STM_SPI_CR2_SSOE) | + (0 << STM_SPI_CR2_TXDMAEN) | + (0 << STM_SPI_CR2_RXDMAEN)); + + /* Clear RXNE */ + (void) stm_spi->dr; + + while (!(stm_spi->sr & (1 << STM_SPI_SR_TXE))); + stm_spi->dr = byte; +} + void ao_spi_recv(void *block, uint16_t len, uint8_t spi_index); @@ -87,13 +121,25 @@ extern uint16_t ao_spi_speed[STM_NUM_SPI]; void ao_spi_init(void); +#define ao_spi_set_cs(reg,mask) ((reg)->bsrr = ((uint32_t) (mask)) << 16) +#define ao_spi_clr_cs(reg,mask) ((reg)->bsrr = (mask)) + #define ao_spi_get_mask(reg,mask,bus, speed) do { \ ao_spi_get(bus, speed); \ - (reg)->bsrr = ((uint32_t) mask) << 16; \ + ao_spi_set_cs(reg,mask); \ } while (0) +static inline uint8_t +ao_spi_try_get_mask(struct stm_gpio *reg, uint16_t mask, uint8_t bus, uint32_t speed, uint8_t task_id) +{ + if (!ao_spi_try_get(bus, speed, task_id)) + return 0; + ao_spi_set_cs(reg, mask); + return 1; +} + #define ao_spi_put_mask(reg,mask,bus) do { \ - (reg)->bsrr = mask; \ + ao_spi_clr_cs(reg,mask); \ ao_spi_put(bus); \ } while (0) @@ -113,6 +159,19 @@ ao_spi_init(void); stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_GPIOEEN); \ } while (0) +#define ao_disable_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_gpio_set(port, bit, pin, v) stm_gpio_set(port, bit, v) @@ -124,9 +183,7 @@ ao_spi_init(void); stm_moder_set(port, bit, STM_MODER_OUTPUT);\ } while (0) -#define ao_enable_input(port,bit,mode) do { \ - ao_enable_port(port); \ - stm_moder_set(port, bit, STM_MODER_INPUT); \ +#define ao_gpio_set_mode(port,bit,mode) do { \ if (mode == AO_EXTI_MODE_PULL_UP) \ stm_pupdr_set(port, bit, STM_PUPDR_PULL_UP); \ else if (mode == AO_EXTI_MODE_PULL_DOWN) \ @@ -134,6 +191,12 @@ ao_spi_init(void); else \ stm_pupdr_set(port, bit, STM_PUPDR_NONE); \ } while (0) + +#define ao_enable_input(port,bit,mode) do { \ + ao_enable_port(port); \ + stm_moder_set(port, bit, STM_MODER_INPUT); \ + ao_gpio_set_mode(port, bit, mode); \ + } while (0) #define ao_enable_cs(port,bit) do { \ stm_gpio_set((port), bit, 1); \ @@ -232,6 +295,8 @@ extern struct ao_stm_usart ao_stm_usart3; #define ARM_PUSH32(stack, val) (*(--(stack)) = (val)) +typedef uint32_t ao_arch_irq_t; + static inline uint32_t ao_arch_irqsave(void) { uint32_t primask; @@ -250,6 +315,7 @@ ao_arch_memory_barrier() { asm volatile("" ::: "memory"); } +#if HAS_TASK static inline void ao_arch_init_stack(struct ao_task *task, void *start) { @@ -297,6 +363,13 @@ static inline void ao_arch_save_stack(void) { static inline void ao_arch_restore_stack(void) { uint32_t sp; + uint32_t control; + + asm("mrs %0,control" : "=&r" (control)); + control |= (1 << 1); + asm("msr control,%0" : : "r" (control)); + asm("isb"); + sp = (uint32_t) ao_cur_task->sp; /* Switch stacks */ @@ -308,7 +381,7 @@ static inline void ao_arch_restore_stack(void) { /* Restore APSR */ asm("pop {r0}"); - asm("msr apsr,r0"); + asm("msr apsr_nczvq,r0"); /* Restore general registers */ asm("pop {r0-r12,lr}\n"); @@ -317,18 +390,64 @@ static inline void ao_arch_restore_stack(void) { asm("bx lr"); } -#define ao_arch_isr_stack() +#ifndef HAS_SAMPLE_PROFILE +#define HAS_SAMPLE_PROFILE 0 +#endif -#define ao_arch_wait_interrupt() do { \ - asm(".global ao_idle_loc\n\twfi\nao_idle_loc:"); \ - ao_arch_release_interrupts(); \ - ao_arch_block_interrupts(); \ - } while (0) +#if DEBUG +#define HAS_ARCH_VALIDATE_CUR_STACK 1 -#define ao_arch_critical(b) do { \ - ao_arch_block_interrupts(); \ - do { b } while (0); \ +static inline void +ao_validate_cur_stack(void) +{ + uint8_t *psp; + + asm("mrs %0,psp" : "=&r" (psp)); + if (ao_cur_task && + psp <= ao_cur_task->stack && + psp >= ao_cur_task->stack - 256) + ao_panic(AO_PANIC_STACK); +} +#endif + +#if !HAS_SAMPLE_PROFILE +#define HAS_ARCH_START_SCHEDULER 1 + +static inline void ao_arch_start_scheduler(void) { + uint32_t sp; + uint32_t control; + + asm("mrs %0,msp" : "=&r" (sp)); + asm("msr psp,%0" : : "r" (sp)); + asm("mrs %0,control" : "=&r" (control)); + control |= (1 << 1); + asm("msr control,%0" : : "r" (control)); + asm("isb"); +} +#endif + +static inline void ao_arch_isr_stack(void) { + uint32_t control; + + asm("mrs %0,control" : "=&r" (control)); + control &= ~(1 << 1); + asm("msr control,%0" : : "r" (control)); + asm("isb"); +} + +#endif + +#define ao_arch_wait_interrupt() do { \ + asm("\twfi\n"); \ ao_arch_release_interrupts(); \ + asm(".global ao_idle_loc\nao_idle_loc:"); \ + ao_arch_block_interrupts(); \ + } while (0) + +#define ao_arch_critical(b) do { \ + uint32_t __mask = ao_arch_irqsave(); \ + do { b } while (0); \ + ao_arch_irqrestore(__mask); \ } while (0) #endif /* _AO_ARCH_FUNCS_H_ */