/* * Copyright © 2013 Keith Packard * * 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. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ #ifndef _AO_ARCH_FUNCS_H_ #define _AO_ARCH_FUNCS_H_ #define ao_spi_get_bit(reg,bit,pin,bus,speed) ao_spi_get_mask(reg,(1<stack + AO_STACK_SIZE); uint32_t a = (uint32_t) start; int i; /* Return address (goes into LR) */ ARM_PUSH32(sp, a); /* Clear register values r0-r7 */ i = 8; while (i--) ARM_PUSH32(sp, 0); /* APSR */ ARM_PUSH32(sp, 0); /* PRIMASK with interrupts enabled */ ARM_PUSH32(sp, 0); task->sp = sp; } static inline void ao_arch_save_regs(void) { /* Save general registers */ asm("push {r0-r7,lr}\n"); /* Save APSR */ asm("mrs r0,apsr"); asm("push {r0}"); /* Save PRIMASK */ asm("mrs r0,primask"); asm("push {r0}"); } 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_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) ); /* Restore PRIMASK */ asm("pop {r0}"); asm("msr primask,r0"); /* Restore APSR */ asm("pop {r0}"); asm("msr apsr_nczvq,r0"); /* Restore general registers and return */ asm("pop {r0-r7,pc}\n"); } #define ao_arch_isr_stack() #endif /* HAS_TASK */ #define ao_arch_wait_interrupt() do { \ asm("\twfi\n"); \ ao_arch_release_interrupts(); \ asm(".global ao_idle_loc\n\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) /* * SPI */ #define ao_spi_set_cs(port,mask) (lpc_gpio.clr[port] = (mask)) #define ao_spi_clr_cs(port,mask) (lpc_gpio.set[port] = (mask)) #define ao_spi_get_mask(port,mask,bus,speed) do { \ ao_spi_get(bus, speed); \ ao_spi_set_cs(port, mask); \ } while (0) #define ao_spi_put_mask(reg,mask,bus) do { \ ao_spi_clr_cs(reg,mask); \ ao_spi_put(bus); \ } while (0) #define ao_spi_get_bit(reg,bit,pin,bus,speed) ao_spi_get_mask(reg,(1<