Ejemplo n.º 1
0
tc_t 
tc_init (const tc_cfg_t *cfg)
{
    tc_t tc;
    const pinmap_t *pin;
    unsigned int i;

    pin = 0;
    for (i = 0; i < TC_PINS_NUM; i++)
    {
        pin = &tc_pins[i]; 
        if (pin->pio == cfg->pio)
            break;
    }
    if (i >= TC_PINS_NUM)
        return 0;

    tc = &tc_devices[pin->channel];

    switch (pin->channel)
    {
    case TC_CHANNEL_0:
        tc->base = TC0_BASE;
        irq_config (ID_TC0, 7, tc_handler0);
        break;

    case TC_CHANNEL_1:
        tc->base = TC1_BASE;
        irq_config (ID_TC1, 7, tc_handler1);
        break;

    case TC_CHANNEL_2:
        tc->base = TC2_BASE;
        irq_config (ID_TC2, 7, tc_handler2);
        break;
    }

    /* Enable TCx peripheral clock.  */
    mcu_pmc_enable (ID_TC0 + pin->channel);
    
    tc_config_set (tc, cfg);

    tc->overflows = 0;

    irq_enable (ID_TC0 + TC_CHANNEL (tc));

    return tc;
}
Ejemplo n.º 2
0
int
usart0_init (uint16_t baud_divisor)
{
    /* Disable interrupts.  */
    USART0->US_IDR = ~0;

    /* Enable RxD0 and TxD0 pins and disable pullups.  */
    pio_config_set (TXD0_PIO, TXD0_PERIPH);
    pio_config_set (RXD0_PIO, RXD0_PERIPH);

#ifdef USART0_USE_HANDSHAKING
    pio_config_set (RTS0_PIO, RTS0_PERIPH);
    pio_config_set (CTS0_PIO, CTS0_PERIPH);
#endif
    
    /* Enable USART0 clock.  */
    mcu_pmc_enable (ID_USART0);
    
    /* Reset and disable receiver and transmitter.  */
    USART0->US_CR = US_CR_RSTRX | US_CR_RSTTX          
        | US_CR_RXDIS | US_CR_TXDIS;           

    /* Set normal mode, clock = MCK, 8-bit data, no parity, 1 stop
       bit.  Note, the OVER bit is set to 0 so the baud rate
       calculation is further divided by 16.  The UCLCKS field is 0 so
       the MCK is used as the clock source.  */
    USART0->US_MR = USART0_MODE
        | US_MR_CHRL_8_BIT | US_MR_PAR_NO | US_MR_NBSTOP_1_BIT;

    usart0_baud_divisor_set (baud_divisor);

    /* Enable receiver and transmitter.  */
    USART0->US_CR = US_CR_RXEN | US_CR_TXEN; 
    
    return 1;
}
Ejemplo n.º 3
0
/** Initalises the ADC registers for polling operation.  */
adc_t
adc_init (const adc_cfg_t *cfg)
{
    adc_sample_t dummy;
    adc_dev_t *adc;
    const adc_cfg_t adc_default_cfg =
        {
            .bits = 10,
            .channel = 0,
            .clock_speed_kHz = 1000
        };
    
    if (adc_devices_num >= ADC_DEVICES_NUM)
        return 0;

    if (adc_devices_num == 0)
    {
        /* The clock only needs to be enabled when sampling.  The clock is
           automatically started for the SAM7.  */
        mcu_pmc_enable (ID_ADC);
        
        adc_reset ();
    }

    adc = adc_devices + adc_devices_num;
    adc_devices_num++;
    
    adc->MR = 0;
    /* The transfer field must have a value of 2.  */
    BITS_INSERT (adc->MR, 2, 28, 29);

    if (!cfg)
        cfg = &adc_default_cfg;

    adc_config_set (adc, cfg);

    /* Note, the ADC is not configured until adc_config is called.  */
    adc_config (adc);

#if 0
    /* I'm not sure why a dummy read is required; it is probably a
       quirk of the SAM7.  This will require a software trigger... */
    adc_read (adc, &dummy, sizeof (dummy));
#endif

    return adc;
}


/** Returns true if a conversion has finished.  */
bool
adc_ready_p (adc_t adc)
{
    return (ADC->ADC_ISR & ADC_ISR_DRDY) != 0;
}


/** Blocking read.  This will hang if a trigger is not supplied
    (except for software triggering mode).  */
int8_t
adc_read (adc_t adc, void *buffer, uint16_t size)
{
    uint16_t i;
    uint16_t samples;
    adc_sample_t *data;

    adc_config (adc);

    samples = size / sizeof (adc_sample_t);
    data = buffer;

    for (i = 0; i < samples; i++)
    {
        /* When the ADC peripheral gets a trigger, it converts all the
           enabled channels consecutively in numerical order.  */

        if (adc->trigger == ADC_TRIGGER_SW)
            adc_conversion_start (adc);

        /* Should have timeout, especially for external trigger.  */
        while (!adc_ready_p (adc))
            continue;

        data[i] = ADC->ADC_LCDR;
    }

    /* Disable channel.  */
    ADC->ADC_CHDR = ~0;

    return samples * sizeof (adc_sample_t);
}