parent
							
								
									2d6eeb83ea
								
							
						
					
					
						commit
						812c2fef21
					
				
					 8 changed files with 55 additions and 110 deletions
				
			
		| 
						 | 
				
			
			@ -53,8 +53,30 @@
 | 
			
		|||
    #define IROM __attribute__((section(".irom0.literal"))) const
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define INLINED inline static __attribute__((always_inline)) __attribute__((unused))
 | 
			
		||||
/* Use this macro to place functions into Instruction RAM (IRAM)
 | 
			
		||||
   instead of flash memory (IROM).
 | 
			
		||||
 | 
			
		||||
   This is useful for functions which are called when the flash may
 | 
			
		||||
   not be available (for example during NMI exceptions), or for
 | 
			
		||||
   functions which are called very frequently and need high
 | 
			
		||||
   performance.
 | 
			
		||||
 | 
			
		||||
   Bear in mind IRAM is limited (32KB), compared to up to 1MB of flash.
 | 
			
		||||
*/
 | 
			
		||||
#define IRAM __attribute__((section(".iram1.text")))
 | 
			
		||||
 | 
			
		||||
/* Use this macro to place read-only data into Instruction RAM (IRAM)
 | 
			
		||||
   instead of loaded into rodata which resides in DRAM.
 | 
			
		||||
 | 
			
		||||
   This may be useful to free up data RAM. However all data read from
 | 
			
		||||
   the instruction space must be 32-bit aligned word reads
 | 
			
		||||
   (non-aligned reads will use an interrupt routine to "fix" them and
 | 
			
		||||
   still work, but are very slow..
 | 
			
		||||
*/
 | 
			
		||||
#ifdef	__cplusplus
 | 
			
		||||
    #define IRAM_DATA __attribute__((section(".iram1.rodata")))
 | 
			
		||||
#else
 | 
			
		||||
    #define IRAM_DATA __attribute__((section(".iram1.rodata"))) const
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -23,41 +23,14 @@ typedef enum {
 | 
			
		|||
/* Enable GPIO on the specified pin, and set it to input/output/ with
 | 
			
		||||
 *  pullup as needed
 | 
			
		||||
 */
 | 
			
		||||
INLINED void gpio_enable(const uint8_t gpio_num, const gpio_direction_t direction)
 | 
			
		||||
{
 | 
			
		||||
    uint32_t iomux_flags;
 | 
			
		||||
 | 
			
		||||
    switch(direction) {
 | 
			
		||||
    case GPIO_INPUT:
 | 
			
		||||
        iomux_flags = 0;
 | 
			
		||||
        break;
 | 
			
		||||
    case GPIO_OUTPUT:
 | 
			
		||||
        iomux_flags = IOMUX_PIN_OUTPUT_ENABLE;
 | 
			
		||||
        break;
 | 
			
		||||
    case GPIO_OUT_OPEN_DRAIN:
 | 
			
		||||
        iomux_flags = IOMUX_PIN_OUTPUT_ENABLE;
 | 
			
		||||
        break;
 | 
			
		||||
    case GPIO_INPUT_PULLUP:
 | 
			
		||||
        iomux_flags = IOMUX_PIN_PULLUP;
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
    iomux_set_gpio_function(gpio_num, iomux_flags);
 | 
			
		||||
    if(direction == GPIO_OUT_OPEN_DRAIN)
 | 
			
		||||
        GPIO.CONF[gpio_num] |= GPIO_CONF_OPEN_DRAIN;
 | 
			
		||||
    else
 | 
			
		||||
        GPIO.CONF[gpio_num] &= ~GPIO_CONF_OPEN_DRAIN;
 | 
			
		||||
    if (iomux_flags & IOMUX_PIN_OUTPUT_ENABLE)
 | 
			
		||||
        GPIO.ENABLE_OUT_SET = BIT(gpio_num);
 | 
			
		||||
    else
 | 
			
		||||
        GPIO.ENABLE_OUT_CLEAR = BIT(gpio_num);
 | 
			
		||||
}
 | 
			
		||||
void gpio_enable(const uint8_t gpio_num, const gpio_direction_t direction);
 | 
			
		||||
 | 
			
		||||
/* Disable GPIO on the specified pin, and set it Hi-Z.
 | 
			
		||||
 *
 | 
			
		||||
 * If later muxing this pin to a different function, make sure to set
 | 
			
		||||
 * IOMUX_PIN_OUTPUT_ENABLE if necessary to enable the output buffer.
 | 
			
		||||
 */
 | 
			
		||||
INLINED void gpio_disable(const uint8_t gpio_num)
 | 
			
		||||
static inline void gpio_disable(const uint8_t gpio_num)
 | 
			
		||||
{
 | 
			
		||||
    GPIO.ENABLE_OUT_CLEAR = BIT(gpio_num);
 | 
			
		||||
    *gpio_iomux_reg(gpio_num) &= ~IOMUX_PIN_OUTPUT_ENABLE;
 | 
			
		||||
| 
						 | 
				
			
			@ -67,7 +40,7 @@ INLINED void gpio_disable(const uint8_t gpio_num)
 | 
			
		|||
 *
 | 
			
		||||
 * Only works if pin has been set to GPIO_OUTPUT via gpio_enable()
 | 
			
		||||
 */
 | 
			
		||||
INLINED void gpio_write(const uint8_t gpio_num, const bool set)
 | 
			
		||||
static inline void gpio_write(const uint8_t gpio_num, const bool set)
 | 
			
		||||
{
 | 
			
		||||
    if(set)
 | 
			
		||||
        GPIO.OUT_SET = BIT(gpio_num);
 | 
			
		||||
| 
						 | 
				
			
			@ -79,7 +52,7 @@ INLINED void gpio_write(const uint8_t gpio_num, const bool set)
 | 
			
		|||
 *
 | 
			
		||||
 * Only works if pin has been set to GPIO_OUTPUT via gpio_enable()
 | 
			
		||||
 */
 | 
			
		||||
INLINED void gpio_toggle(const uint8_t gpio_num)
 | 
			
		||||
static inline void gpio_toggle(const uint8_t gpio_num)
 | 
			
		||||
{
 | 
			
		||||
    /* Why implement like this instead of GPIO_OUT_REG ^= xxx?
 | 
			
		||||
       Concurrency. If an interrupt or higher priority task writes to
 | 
			
		||||
| 
						 | 
				
			
			@ -98,7 +71,7 @@ INLINED void gpio_toggle(const uint8_t gpio_num)
 | 
			
		|||
 * If pin is set as an input, this reads the value on the pin.
 | 
			
		||||
 * If pin is set as an output, this reads the last value written to the pin.
 | 
			
		||||
 */
 | 
			
		||||
INLINED bool gpio_read(const uint8_t gpio_num)
 | 
			
		||||
static inline bool gpio_read(const uint8_t gpio_num)
 | 
			
		||||
{
 | 
			
		||||
    return GPIO.IN & BIT(gpio_num);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -109,7 +82,7 @@ extern void gpio_interrupt_handler(void);
 | 
			
		|||
 *
 | 
			
		||||
 * If int_type is not GPIO_INTTYPE_NONE, the gpio_interrupt_handler will be attached and unmasked.
 | 
			
		||||
 */
 | 
			
		||||
INLINED void gpio_set_interrupt(const uint8_t gpio_num, const gpio_inttype_t int_type)
 | 
			
		||||
static inline void gpio_set_interrupt(const uint8_t gpio_num, const gpio_inttype_t int_type)
 | 
			
		||||
{
 | 
			
		||||
    GPIO.CONF[gpio_num] = SET_FIELD(GPIO.CONF[gpio_num], GPIO_CONF_INTTYPE, int_type);
 | 
			
		||||
    if(int_type != GPIO_INTTYPE_NONE) {
 | 
			
		||||
| 
						 | 
				
			
			@ -119,7 +92,7 @@ INLINED void gpio_set_interrupt(const uint8_t gpio_num, const gpio_inttype_t int
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
/* Return the interrupt type set for a pin */
 | 
			
		||||
INLINED gpio_inttype_t gpio_get_interrupt(const uint8_t gpio_num)
 | 
			
		||||
static inline gpio_inttype_t gpio_get_interrupt(const uint8_t gpio_num)
 | 
			
		||||
{
 | 
			
		||||
    return (gpio_inttype_t)FIELD2VAL(GPIO_CONF_INTTYPE, GPIO.CONF[gpio_num]);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -39,7 +39,7 @@ void sdk__xt_tick_timer_init (void);
 | 
			
		|||
void sdk__xt_timer_int(void);
 | 
			
		||||
void sdk__xt_timer_int1(void);
 | 
			
		||||
 | 
			
		||||
INLINED uint32_t _xt_get_intlevel(void)
 | 
			
		||||
static inline uint32_t _xt_get_intlevel(void)
 | 
			
		||||
{
 | 
			
		||||
    uint32_t level;
 | 
			
		||||
    __asm__ volatile("rsr %0, intlevel" : "=a"(level));
 | 
			
		||||
| 
						 | 
				
			
			@ -53,7 +53,7 @@ INLINED uint32_t _xt_get_intlevel(void)
 | 
			
		|||
   portDISABLE_INTERRUPTS/portENABLE_INTERRUPTS for
 | 
			
		||||
   non-FreeRTOS & non-portable code.
 | 
			
		||||
*/
 | 
			
		||||
INLINED uint32_t _xt_disable_interrupts(void)
 | 
			
		||||
static inline uint32_t _xt_disable_interrupts(void)
 | 
			
		||||
{
 | 
			
		||||
    uint32_t old_level;
 | 
			
		||||
    __asm__ volatile ("rsil %0, " XTSTR(XCHAL_EXCM_LEVEL) : "=a" (old_level));
 | 
			
		||||
| 
						 | 
				
			
			@ -61,14 +61,14 @@ INLINED uint32_t _xt_disable_interrupts(void)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
/* Restore PS level. Intended to be used with _xt_disable_interrupts */
 | 
			
		||||
INLINED void _xt_restore_interrupts(uint32_t new_ps)
 | 
			
		||||
static inline void _xt_restore_interrupts(uint32_t new_ps)
 | 
			
		||||
{
 | 
			
		||||
    __asm__ volatile ("wsr %0, ps; rsync" :: "a" (new_ps));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* ESPTODO: the mask/unmask functions aren't thread safe */
 | 
			
		||||
 | 
			
		||||
INLINED void _xt_isr_unmask(uint32_t unmask)
 | 
			
		||||
static inline void _xt_isr_unmask(uint32_t unmask)
 | 
			
		||||
{
 | 
			
		||||
    uint32_t intenable;
 | 
			
		||||
    asm volatile ("rsr %0, intenable" : "=a" (intenable));
 | 
			
		||||
| 
						 | 
				
			
			@ -76,7 +76,7 @@ INLINED void _xt_isr_unmask(uint32_t unmask)
 | 
			
		|||
    asm volatile ("wsr %0, intenable; esync" :: "a" (intenable));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
INLINED void _xt_isr_mask (uint32_t mask)
 | 
			
		||||
static inline void _xt_isr_mask (uint32_t mask)
 | 
			
		||||
{
 | 
			
		||||
    uint32_t intenable;
 | 
			
		||||
    asm volatile ("rsr %0, intenable" : "=a" (intenable));
 | 
			
		||||
| 
						 | 
				
			
			@ -84,14 +84,14 @@ INLINED void _xt_isr_mask (uint32_t mask)
 | 
			
		|||
    asm volatile ("wsr %0, intenable; esync" :: "a" (intenable));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
INLINED uint32_t _xt_read_ints (void)
 | 
			
		||||
static inline uint32_t _xt_read_ints (void)
 | 
			
		||||
{
 | 
			
		||||
    uint32_t interrupt;
 | 
			
		||||
    asm volatile ("rsr %0, interrupt" : "=a" (interrupt));
 | 
			
		||||
    return interrupt;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
INLINED void _xt_clear_ints(uint32_t mask)
 | 
			
		||||
static inline void _xt_clear_ints(uint32_t mask)
 | 
			
		||||
{
 | 
			
		||||
    asm volatile ("wsr %0, intclear; esync" :: "a" (mask));
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -22,7 +22,7 @@ extern "C" {
 | 
			
		|||
 * known at compile time, or return the result from a lookup table if not.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
inline static uint8_t gpio_to_iomux(const uint8_t gpio_number);
 | 
			
		||||
uint8_t IRAM gpio_to_iomux(const uint8_t gpio_number);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Convert an iomux register index to a GPIO pin number.
 | 
			
		||||
| 
						 | 
				
			
			@ -31,7 +31,7 @@ inline static uint8_t gpio_to_iomux(const uint8_t gpio_number);
 | 
			
		|||
 * known at compile time, or return the result from a lookup table if not.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
inline static uint8_t iomux_to_gpio(const uint8_t iomux_num);
 | 
			
		||||
uint8_t IRAM iomux_to_gpio(const uint8_t iomux_num);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Directly get the IOMUX register for a particular gpio number
 | 
			
		||||
| 
						 | 
				
			
			@ -64,10 +64,6 @@ inline static void iomux_set_gpio_function(const uint8_t gpio_number, const uint
 | 
			
		|||
    IOMUX.PIN[reg_idx] = func | flags;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* esp_iomux_private contains implementation parts of the inline functions
 | 
			
		||||
   declared above */
 | 
			
		||||
#include "esp/iomux_private.h"
 | 
			
		||||
 | 
			
		||||
#ifdef	__cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,46 +0,0 @@
 | 
			
		|||
/** esp/iomux_private.h
 | 
			
		||||
 *
 | 
			
		||||
 * Private implementation parts of iomux registers. In headers to
 | 
			
		||||
 * allow compile-time optimisations.
 | 
			
		||||
 *
 | 
			
		||||
 * Part of esp-open-rtos
 | 
			
		||||
 * Copyright (C) 2015 Superhouse Automation Pty Ltd
 | 
			
		||||
 * BSD Licensed as described in the file LICENSE
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/* Mapping from register index to GPIO and from GPIO index to register
 | 
			
		||||
   number. DO NOT USE THESE IN YOUR CODE, call gpio_to_iomux(xxx) or
 | 
			
		||||
   iomux_to_gpio(xxx) instead.
 | 
			
		||||
*/
 | 
			
		||||
#ifndef _IOMUX_PRIVATE
 | 
			
		||||
#define _IOMUX_PRIVATE
 | 
			
		||||
 | 
			
		||||
#include "common_macros.h"
 | 
			
		||||
 | 
			
		||||
#define _IOMUX_TO_GPIO { 12, 13, 14, 15, 3, 1, 6, 7, 8, 9, 10, 11, 0, 2, 4, 5 }
 | 
			
		||||
#define _GPIO_TO_IOMUX { 12, 5, 13, 4, 14, 15, 6, 7, 8, 9, 10, 11, 0, 1, 2, 3 }
 | 
			
		||||
 | 
			
		||||
extern const IROM uint32_t GPIO_TO_IOMUX_MAP[];
 | 
			
		||||
extern const IROM uint32_t IOMUX_TO_GPIO_MAP[];
 | 
			
		||||
 | 
			
		||||
INLINED uint8_t gpio_to_iomux(const uint8_t gpio_number)
 | 
			
		||||
{
 | 
			
		||||
    if(__builtin_constant_p(gpio_number)) {
 | 
			
		||||
        static const uint8_t _regs[] = _GPIO_TO_IOMUX;
 | 
			
		||||
        return _regs[gpio_number];
 | 
			
		||||
    } else {
 | 
			
		||||
        return GPIO_TO_IOMUX_MAP[gpio_number];
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
INLINED uint8_t iomux_to_gpio(const uint8_t iomux_number)
 | 
			
		||||
{
 | 
			
		||||
    if(__builtin_constant_p(iomux_number)) {
 | 
			
		||||
        static const uint8_t _regs[] = _IOMUX_TO_GPIO;
 | 
			
		||||
        return _regs[iomux_number];
 | 
			
		||||
    } else {
 | 
			
		||||
        return IOMUX_TO_GPIO_MAP[iomux_number];
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue