Beispiel #1
0
/**
 * \brief Set callback for given GPIO pin
 *
 * \param [in] pin The pin number
 * \param [in] callback callback function pointer
 * \param [in] irq_level interrupt level
 *
 * \retval true Set successfully
 * \retval false Wrong parameters or maximum number of interrupt
 *                  sources has been exceeding
 */
bool gpio_set_pin_callback(ioport_pin_t pin, gpio_pin_callback_t callback,
		uint8_t irq_level)
{
	int8_t i;
	int8_t irq_line;

	if (gpio_nb_sources >= GPIO_MAX_INTERRUPT_SOURCES) {
		return false;
	}

	/*
	 * Get IRQ line for the given pin.
	 *
	 * \note Grouping interrupt generators into groups of eight, four
	 * different interrupt handlers can be installed for each GPIO port.
	 */
	for (i = 0; i < 4; i++) {
		if (ioport_pin_to_mask(pin) & (GPIO_INT_GROUP_MASK << (i * 8))) {
			break;
		}
	}
	irq_line = GPIO_0_IRQn + ioport_pin_to_port_id(pin) * 4 + i;

	gpio_int_sources[gpio_nb_sources].pin = pin;
	gpio_int_sources[gpio_nb_sources].callback = callback;
	NVIC_ClearPendingIRQ((IRQn_Type)irq_line);
	NVIC_SetPriority((IRQn_Type)irq_line, irq_level);
	NVIC_EnableIRQ((IRQn_Type)irq_line);

	gpio_nb_sources++;

	return true;
}
OSStatus platform_gpio_irq_disable( const platform_gpio_t* gpio )
{
  OSStatus            err           = kNoErr;
  ioport_port_mask_t  mask          = ioport_pin_to_mask   ( gpio->pin );
  ioport_port_t       port          = ioport_pin_to_port_id( gpio->pin );
  volatile Pio*       port_register = arch_ioport_port_to_base( port );
  
  platform_mcu_powersave_disable();
  require_action_quiet( gpio != NULL, exit, err = kParamErr);

  /* Disable interrupt on pin */
  port_register->PIO_IDR = mask;

  /* Disable Cortex-M interrupt vector as well if no pin interrupt is enabled */
  if ( port_register->PIO_IMR == 0 )
  {
    NVIC_DisableIRQ( irq_vectors[port] );
  }

  gpio_irq_data[port][mask].wakeup_pin = false;
  gpio_irq_data[port][mask].arg        = 0;
  gpio_irq_data[port][mask].callback   = NULL;
  
exit:
  platform_mcu_powersave_enable();
  return err;
}
Beispiel #3
0
/**
 * \brief Test physical loop-back with some characters in sunc mode.
 *
 * This function sends a character over USART on loop back to verify that init
 * and sending/receiving works. A jumper is connected on the USART.
 *
 * \param test Current test case.
 */
static void run_loopback_syncmode_test(const struct test_case *test)
{
	uint8_t out_c = 'c';
	uint8_t in_c  = 0;
        port_pin_t sck_pin;
        
        sysclk_enable_module(POWER_RED_REG0, PRUSART0_bm);
        
        usart_set_mode(&CONF_UNIT_USART, USART_CMODE_SYNCHRONOUS_gc);

	sck_pin = IOPORT_CREATE_PIN(PORTE, 2);
	ioport_configure_port_pin(ioport_pin_to_port(sck_pin),
				ioport_pin_to_mask(sck_pin),
				IOPORT_DIR_OUTPUT | IOPORT_INIT_HIGH );
        
        usart_spi_set_baudrate(&CONF_UNIT_USART, CONF_UNIT_BAUDRATE,
			sysclk_get_source_clock_hz());
	usart_tx_enable(&CONF_UNIT_USART);
	usart_rx_enable(&CONF_UNIT_USART);

	usart_putchar(&CONF_UNIT_USART, out_c);
	in_c = usart_getchar(&CONF_UNIT_USART);

	test_assert_true(test, in_c == out_c,
	   "Read character through sync mode is not correct: %d != %d", in_c, out_c);			
}
Beispiel #4
0
/**
 * \brief Initialize USART in SPI master mode.
 *
 * This function initializes the USART module in SPI master mode using the
 * usart_spi_options_t configuration structure and CPU frequency.
 *
 * \param usart The USART module.
 * \param opt The RS232 configuration option.
 */
void usart_init_spi(USART_t *usart, const usart_spi_options_t *opt)
{
	usart->UBRR = 0;

	usart_enable_module_clock(usart);
	usart_set_mode(usart, USART_CMODE_MSPI_gc);
	port_pin_t sck_pin;

#ifdef USARTA0
	if ((uintptr_t)usart == (uintptr_t)&UCSR0A) {
		sck_pin = IOPORT_CREATE_PIN(PORTE, 2);
		ioport_configure_port_pin(ioport_pin_to_port(sck_pin),
				ioport_pin_to_mask(sck_pin),
				IOPORT_DIR_OUTPUT | IOPORT_INIT_HIGH );
	}
#endif
#ifdef USARTA1
	if ((uintptr_t)usart == (uintptr_t)&UCSR1A) {
		sck_pin = IOPORT_CREATE_PIN(PORTD, 5);
		ioport_configure_port_pin(ioport_pin_to_port(sck_pin),
				ioport_pin_to_mask(sck_pin),
				IOPORT_DIR_OUTPUT | IOPORT_INIT_HIGH );
	}
#endif
	if (opt->spimode == 1 || opt->spimode == 3) {
		usart->UCSRnC |= USART_UCPHA_bm;
	} else {
		usart->UCSRnC &= ~USART_UCPHA_bm;
	}
	if (opt->spimode == 2 || opt->spimode == 3) {
		usart->UCSRnC |= USART_UCPOL_bm;
	} else {
		usart->UCSRnC &= ~USART_UCPOL_bm;
	}	
	
	if (opt->data_order) {
		usart->UCSRnC |= USART_DORD_bm;
	} else {
		usart->UCSRnC &= ~USART_DORD_bm;
	}
	
	
	usart_spi_set_baudrate(usart, opt->baudrate,
			sysclk_get_source_clock_hz());
	usart_tx_enable(usart);
	usart_rx_enable(usart);
}
Beispiel #5
0
OSStatus gpio_irq_disable( gpio_port_t gpio_port, gpio_pin_number_t gpio_pin_number )
{
    Pio *p_pio = arch_ioport_port_to_base(gpio_port);
    ioport_port_mask_t ul_mask = ioport_pin_to_mask(CREATE_IOPORT_PIN(gpio_port, gpio_pin_number));

    pio_disable_interrupt(p_pio, ul_mask);
  
  return kGeneralErr;
}
Beispiel #6
0
OSStatus gpio_irq_enable( gpio_port_t gpio_port, gpio_pin_number_t gpio_pin_number, gpio_irq_trigger_t trigger, gpio_irq_handler_t handler, void* arg )
{
    //gpio_irq_data_t *pSource; 
    uint32_t ul_attr;
    if (gs_ul_nb_sources >= MAX_INTERRUPT_SOURCES)
		return 1;
    //Pio *p_pio = (Pio *)ioport_port_to_base(gpio_port);
    Pio *p_pio = arch_ioport_port_to_base(gpio_port);
    //ioport_pin_t pin = CREATE_IOPORT_PIN(gpio_port, gpio_pin_number);
    ioport_port_mask_t ul_mask = ioport_pin_to_mask(CREATE_IOPORT_PIN(gpio_port, gpio_pin_number));

    if ( gpio_irq_management_initted == 0 )
    {
        memset( (void*)gpio_irq_data, 0, sizeof( gpio_irq_data ) );
        gpio_irq_management_initted = 1;
    }

    
    if (trigger == IRQ_TRIGGER_RISING_EDGE ) {
        ul_attr = PIO_IT_RISE_EDGE;     
    } else if (trigger == IRQ_TRIGGER_FALLING_EDGE ) {
        ul_attr = PIO_IT_FALL_EDGE;     
    } else if (trigger == IRQ_TRIGGER_BOTH_EDGES ) {
        ul_attr = PIO_IT_EDGE;     
    }
	//pSource = &(gpio_irq_data[gs_ul_nb_sources]);
    gpio_irq_data[gs_ul_nb_sources].owner_port = gpio_port;
	if ( gpio_port == PORTA) {
        gpio_irq_data[gs_ul_nb_sources].id     = ID_PIOA;
	   // pmc_enable_periph_clk(ID_PIOA);
    } else if (gpio_port == PORTB) {
        gpio_irq_data[gs_ul_nb_sources].id     = ID_PIOB;
	   // pmc_enable_periph_clk(ID_PIOB);
    }
    gpio_irq_data[gs_ul_nb_sources].mask       = ul_mask;
    gpio_irq_data[gs_ul_nb_sources].handler    = handler;
    gpio_irq_data[gs_ul_nb_sources].arg        = arg;
    gs_ul_nb_sources++;
	/* Configure interrupt mode */
	pio_configure_interrupt(p_pio, ul_mask, ul_attr);
	
	if ( gpio_port == PORTA){
        NVIC_EnableIRQ( PIOA_IRQn );
        pio_handler_set_priority(PIOA, PIOA_IRQn, IRQ_PRIORITY_PIO);
    } else if (gpio_port == PORTB) {
        NVIC_EnableIRQ( PIOB_IRQn);
        pio_handler_set_priority(PIOB, PIOB_IRQn, IRQ_PRIORITY_PIO);
    }
    pio_enable_interrupt(p_pio, ul_mask);
    
    return kGeneralErr;
}
Beispiel #7
0
/**
 * Common GPIO handler.
 */
static void gpio_common_handler(uint32_t port_id, uint32_t port_mask)
{
	GpioPort *gpio_port = &(GPIO->GPIO_PORT[port_id]);
	uint32_t i;
	uint32_t int_flags;
	ioport_pin_t pin;

	int_flags = gpio_port->GPIO_IFR;

	for (i = 0; i < gpio_nb_sources; i++) {
		pin = gpio_int_sources[i].pin;
		if ((ioport_pin_to_port_id(pin) == port_id) &&
				(ioport_pin_to_mask(pin) & int_flags)) {
			if (gpio_int_sources[i].callback != NULL) {
				gpio_int_sources[i].callback();
			} else {
				Assert(false); /* Catch unexpected interrupt */
			}
		}
	}

	gpio_port->GPIO_IFRC = (int_flags & port_mask);
}
OSStatus platform_gpio_irq_enable( const platform_gpio_t* gpio, platform_gpio_irq_trigger_t trigger, platform_gpio_irq_callback_t handler, void* arg )
{
  ioport_port_mask_t  mask                = ioport_pin_to_mask( gpio->pin );
  ioport_port_t       port                = ioport_pin_to_port_id( gpio->pin );
  volatile Pio*       port_register       = arch_ioport_port_to_base( port );
  uint8_t             pin_number          = (gpio->pin) & 0x1F;
  uint32_t            temp;
  uint8_t             samg5x_irq_trigger;
  OSStatus            err                 = kNoErr;
    
  platform_mcu_powersave_disable();
  require_action_quiet( gpio != NULL, exit, err = kParamErr);

  NVIC_DisableIRQ( irq_vectors[port] );
  NVIC_ClearPendingIRQ( irq_vectors[port] );

  gpio_irq_data[port][pin_number].wakeup_pin = gpio->is_wakeup_pin;
  gpio_irq_data[port][pin_number].arg        = arg;
  gpio_irq_data[port][pin_number].callback   = handler;

  switch ( trigger )
  {
    case IRQ_TRIGGER_RISING_EDGE:  samg5x_irq_trigger = IOPORT_SENSE_RISING;    break;
    case IRQ_TRIGGER_FALLING_EDGE: samg5x_irq_trigger = IOPORT_SENSE_FALLING;   break;
    case IRQ_TRIGGER_BOTH_EDGES:   samg5x_irq_trigger = IOPORT_SENSE_BOTHEDGES; break;
    default:
      err = kParamErr;
      goto exit;
  }

  if( gpio->is_wakeup_pin == true )
  {
    platform_powersave_enable_wakeup_pin( gpio );
  }

  if ( samg5x_irq_trigger == IOPORT_SENSE_RISING || samg5x_irq_trigger == IOPORT_SENSE_BOTHEDGES )
  {
   port_register->PIO_AIMER  |= mask;
   port_register->PIO_ESR    |= mask;
   port_register->PIO_REHLSR |= mask;
  }

  if ( samg5x_irq_trigger == IOPORT_SENSE_FALLING || samg5x_irq_trigger == IOPORT_SENSE_BOTHEDGES )
  {
    port_register->PIO_AIMER  |= mask;
    port_register->PIO_ESR    |= mask;
    port_register->PIO_FELLSR |= mask;
  }

  /* Read ISR to clear residual interrupt status */
  temp = port_register->PIO_ISR;
  UNUSED_PARAMETER( temp );

  /* Enable interrupt source */
  port_register->PIO_IER |= mask;

  NVIC_EnableIRQ( irq_vectors[port] );
  
exit:
  platform_mcu_powersave_enable();
  return err;
}
Beispiel #9
0
/**
 * \brief Initialize USART in SPI master mode.
 *
 * This function initializes the USART module in SPI master mode using the
 * usart_spi_options_t configuration structure and CPU frequency.
 *
 * \param usart The USART module.
 * \param opt The RS232 configuration option.
 */
void usart_init_spi(USART_t *usart, const usart_spi_options_t *opt)
{
    usart_enable_module_clock(usart);
    usart_set_mode(usart, USART_CMODE_MSPI_gc);
    port_pin_t sck_pin;

    if (opt->spimode == 1 || opt->spimode == 3) {
        //! \todo Fix when UCPHA_bm is added to header file.
        usart->CTRLC |= 0x02;
    } else {
        //! \todo Fix when UCPHA_bm is added to header file.
        usart->CTRLC &= ~0x02;
    }

    // configure Clock polarity using INVEN bit of the correct SCK I/O port
    if (opt->spimode == 2 || opt->spimode == 3) {
#ifdef USARTC0
        if ((uint16_t)usart == (uint16_t)&USARTC0) {
            sck_pin = IOPORT_CREATE_PIN(PORTC, 1);
            ioport_configure_port_pin(ioport_pin_to_port(sck_pin),
                                      ioport_pin_to_mask(sck_pin),
                                      IOPORT_DIR_OUTPUT | IOPORT_INIT_HIGH | IOPORT_INV_ENABLED);
        }
#endif
#ifdef USARTC1
        if ((uint16_t)usart == (uint16_t)&USARTC1) {
            sck_pin = IOPORT_CREATE_PIN(PORTC, 5);
            ioport_configure_port_pin(ioport_pin_to_port(sck_pin),
                                      ioport_pin_to_mask(sck_pin),
                                      IOPORT_DIR_OUTPUT | IOPORT_INIT_HIGH | IOPORT_INV_ENABLED);
        }
#endif
#ifdef USARTD0
        if ((uint16_t)usart == (uint16_t)&USARTD0) {
            sck_pin = IOPORT_CREATE_PIN(PORTD, 1);
            ioport_configure_port_pin(ioport_pin_to_port(sck_pin),
                                      ioport_pin_to_mask(sck_pin),
                                      IOPORT_DIR_OUTPUT | IOPORT_INIT_HIGH | IOPORT_INV_ENABLED);
        }
#endif
#ifdef USARTD1
        if ((uint16_t)usart == (uint16_t)&USARTD1) {
            sck_pin = IOPORT_CREATE_PIN(PORTD, 5);
            ioport_configure_port_pin(ioport_pin_to_port(sck_pin),
                                      ioport_pin_to_mask(sck_pin),
                                      IOPORT_DIR_OUTPUT | IOPORT_INIT_HIGH | IOPORT_INV_ENABLED);
        }
#endif
#ifdef USARTE0
        if ((uint16_t)usart == (uint16_t)&USARTE0) {
            sck_pin = IOPORT_CREATE_PIN(PORTE, 1);
            ioport_configure_port_pin(ioport_pin_to_port(sck_pin),
                                      ioport_pin_to_mask(sck_pin),
                                      IOPORT_DIR_OUTPUT | IOPORT_INIT_HIGH | IOPORT_INV_ENABLED);
        }
#endif
#ifdef USARTE1
        if ((uint16_t)usart == (uint16_t)&USARTE1) {
            sck_pin = IOPORT_CREATE_PIN(PORTE, 5);
            ioport_configure_port_pin(ioport_pin_to_port(sck_pin),
                                      ioport_pin_to_mask(sck_pin),
                                      IOPORT_DIR_OUTPUT | IOPORT_INIT_HIGH | IOPORT_INV_ENABLED);
        }
#endif
#ifdef USARTF0
        if ((uint16_t)usart == (uint16_t)&USARTF0) {
            sck_pin = IOPORT_CREATE_PIN(PORTF, 1);
            ioport_configure_port_pin(ioport_pin_to_port(sck_pin),
                                      ioport_pin_to_mask(sck_pin),
                                      IOPORT_DIR_OUTPUT | IOPORT_INIT_HIGH | IOPORT_INV_ENABLED);
        }
#endif
#ifdef USARTF1
        if ((uint16_t)usart == (uint16_t)&USARTF1) {
            sck_pin = IOPORT_CREATE_PIN(PORTF, 5);
            ioport_configure_port_pin(ioport_pin_to_port(sck_pin),
                                      ioport_pin_to_mask(sck_pin),
                                      IOPORT_DIR_OUTPUT | IOPORT_INIT_HIGH | IOPORT_INV_ENABLED);
        }
#endif
    }

    usart_spi_set_baudrate(usart, opt->baudrate, sysclk_get_per_hz());
    usart_tx_enable(usart);
    usart_rx_enable(usart);
}
Beispiel #10
0
/*! \brief Install a sensor interrupt handler
 *
 * The Sensors Xplained add-on boards route sensor device I/O pins to GPIO
 * pins for the MCU installed on an Xplained platform board.  Some sensor
 * devices can be configured to generate interrupts on these pins to indicate
 * the availability of new sensor data or the occurrence of configurable
 * events related to sensor data thresholds, for example.
 *
 * This routine will enable interrupts on the GPIO pin specified by the
 * \c gpio_pin parameter and call a user-defined callback \c handler when an
 * interrupt is detected.  The \c arg parameter is used to pass the address
 * of user-defined input and output storage for the callback handler.  Calling
 * the routine with the \c handler parameter set to 0 (the NULL pointer) will
 * fail with \c false returned to the caller.
 *
 * \param   gpio_pin    Board-specific GPIO pin interface to the MCU.
 * \param   handler     The address of a driver-defined interrupt handler.
 * \param   arg         An optional address passed to the interrupt handler.
 *
 * \return  bool        true if the call succeeds, else false.
 */
bool sensor_board_irq_connect(uint32_t gpio_pin,
		SENSOR_IRQ_HANDLER handler, void *arg)
{
	bool status = false;

#if XMEGA
	PORT_t *sensor_port;
#endif

	/* Ensure that the caller has specified a function address. */

	if (handler == NULL) {
		return status;
	}

	/* Save the interrupt flag state and disable MCU interrupts. */

	irqflags_t const irq_flags = cpu_irq_save();

	cpu_irq_disable();

	/* Initialize an interrupt for a specified I/O pin. */

	if (SENSOR_BOARD_PIN3 == gpio_pin) {
		sensor_pin3_handler = handler;
		sensor_pin3_arg     = arg;

#if UC3
#  if defined(SENSOR_PIN3_EIC_LINE)
		eic_irq_connect(SENSOR_PIN3_EIC_LINE, SENSOR_PIN3_EIC_PIN,
				SENSOR_PIN3_EIC_FUNC, SENSOR_PIN3_EIC_IRQ,
				eic_pin3_handler);
#  else
		gpio_irq_connect(gpio_pin, SENSOR_PIN3_IRQ);
#  endif
#elif XMEGA
		sensor_port = ioport_pin_to_port(SENSOR_BOARD_PIN3);
		sensor_port->INTCTRL   = PORT_INT0LVL_LO_gc;
		sensor_port->INT0MASK |= ioport_pin_to_mask(SENSOR_BOARD_PIN3);
		/* Some Xplained kits have limited asynchronous sensing on most
		 * pins, which requires them to be sensing on both edges.
		 */
		ioport_set_pin_sense_mode(SENSOR_BOARD_PIN3,
				IOPORT_SENSE_BOTHEDGES);
#endif
		status = true;
	} else if (SENSOR_BOARD_PIN4 == gpio_pin) {
		sensor_pin4_handler = handler;
		sensor_pin4_arg     = arg;

#if UC3
#  if defined(SENSOR_PIN4_EIC_LINE)
		eic_irq_connect(SENSOR_PIN4_EIC_LINE, SENSOR_PIN4_EIC_PIN,
				SENSOR_PIN4_EIC_FUNC, SENSOR_PIN4_EIC_IRQ,
				eic_pin4_handler);
#  else
		gpio_irq_connect(gpio_pin, SENSOR_PIN4_IRQ);
#  endif
#elif XMEGA
		sensor_port = ioport_pin_to_port(SENSOR_BOARD_PIN4);
		sensor_port->INTCTRL   = PORT_INT0LVL_LO_gc;
		sensor_port->INT0MASK |= ioport_pin_to_mask(SENSOR_BOARD_PIN4);
		/* Some Xplained kits have limited asynchronous sensing on most
		 * pins, which requires them to be sensing on both edges.
		 */
		ioport_set_pin_sense_mode(SENSOR_BOARD_PIN4,
				IOPORT_SENSE_BOTHEDGES);
#endif
		status = true;
	} else if (SENSOR_BOARD_PIN5 == gpio_pin) {
		sensor_pin5_handler = handler;
		sensor_pin5_arg     = arg;

#if UC3
#  if defined(SENSOR_PIN5_EIC_LINE)
		eic_irq_connect(SENSOR_PIN5_EIC_LINE, SENSOR_PIN5_EIC_PIN,
				SENSOR_PIN5_EIC_FUNC, SENSOR_PIN5_EIC_IRQ,
				eic_pin5_handler);
#  else
		gpio_irq_connect(gpio_pin, SENSOR_PIN5_IRQ);
#  endif
#elif XMEGA
		sensor_port = ioport_pin_to_port(SENSOR_BOARD_PIN5);
		sensor_port->INTCTRL   = PORT_INT0LVL_LO_gc;
		sensor_port->INT0MASK |= ioport_pin_to_mask(SENSOR_BOARD_PIN5);
		/* Some Xplained kits have limited asynchronous sensing on most
		 * pins, which requires them to be sensing on both edges.
		 */
		ioport_set_pin_sense_mode(SENSOR_BOARD_PIN5,
				IOPORT_SENSE_BOTHEDGES);
#endif
		status = true;
	}

	/* Restore the MCU interrupt flag state. */

	cpu_irq_restore(irq_flags);

	return status;
}