コード例 #1
0
ファイル: adc.c プロジェクト: ishgum/Wacky-Racers
adc_clock_speed_t
adc_clock_speed_kHz_set (adc_t adc, adc_clock_speed_t clock_speed_kHz)
{
    uint32_t clock_speed;
    uint16_t settle_clocks;
    uint16_t sample_clocks;
    static const uint8_t adc_settle_table[] = {3, 5, 9, 17};
    static const uint16_t adc_sample_table[] = 
    {0, 8, 16, 24, 64, 80, 96, 112, 512, 576, 640, 704, 768, 832, 896, 960};

    /* For the SAM7 the max clock speed is 5 MHz for 10 bit and 8 MHz
       for 8 bit.  */

    clock_speed = clock_speed_kHz * 1000;
    adc_clock_divisor_set (adc, ((F_CPU / 2) + clock_speed - 1) / clock_speed);
    clock_speed = (F_CPU / 2) / adc->clock_divisor;

    /* With 24 MHz clock need 4.8 clocks to settle on SAM4S.  This is only
       needed when switching gain or offset, say when converting a
       sequence of channels.  Let's play safe and allocate the maximum
       17 clocks.  */
    BITS_INSERT (adc->MR, 3, 20, 21);

    /* With 24 MHz clock need 288 clocks to start up on SAM4S.  Let's
       allocate 512.  TODO, scan through table to find appropriate
       value.  */
    BITS_INSERT (adc->MR, 8, 16, 19);

    /* With 24 MHz clock need 3.4 clocks to sample on SAM4S.   Let's
       allocate 4.  */
    BITS_INSERT (adc->MR, 3, 24, 27);

    return clock_speed / 1000;
}
コード例 #2
0
ファイル: mcpwm_xc16.c プロジェクト: UCI-CARL/embedlib
/**
 * @details No details.
 */
int mcpwm_set_deadtime(mcpwm_module_t *module,
                       enum mcpwm_deadtime_unit_e unit,
                       unsigned int value)
{
    // Check for valid module
    if( module == NULL || module->base_address == NULL )
    {// Invalid module
        return MCPWM_E_MODULE;
    }

    if( unit == MCPWM_DEADTIME_UNITA )
    {// Set DTA to supplied value
        *(module->base_address + MCPWM_OFFSET_PxDTCON1) = BITS_INSERT(*(module->base_address + MCPWM_OFFSET_PxDTCON1),MCPWM_BITMASK_DTA,value);
    }
    else if( unit == MCPWM_DEADTIME_UNITB )
    {// Set DTB to supplied value
        *(module->base_address + MCPWM_OFFSET_PxDTCON1) = BITS_INSERT(*(module->base_address + MCPWM_OFFSET_PxDTCON1),MCPWM_BITMASK_DTB,value);
    }
    else
    {// Unknown unit
        return MCPWM_E_INPUT;
    }

    return MCPWM_E_NONE;
}
コード例 #3
0
ファイル: mcu.c プロジェクト: ishgum/Wacky-Racers
/** Initialise flash memory controller.  */
static void
mcu_flash_init (void)
{
#if 0
    /* TODO  */
    switch (MCU_FLASH_READ_CYCLES)
    {
    case 1:
        /* Set 0 flash wait states for reading, 1 for writing.  */
        EEFC->MC_FMR = MC_FWS_0FWS;
        break;

    case 2:
        /* Set 1 flash wait state for reading, 2 for writing.  */
        EEFC->MC_FMR = MC_FWS_1FWS;
        break;

    case 3:
        /* Set 2 flash wait states for reading, 3 for writing.  */
        EEFC->MC_FMR = MC_FWS_2FWS;
        break;

    default:
        /* Set 3 flash wait states for reading, 4 for writing.  */
        EEFC->MC_FMR = MC_FWS_3FWS;
        break;
    }

    /* Set number of MCK cycles per microsecond for the Flash
       microsecond cycle number (FMCN) field of the Flash mode
       register (FMR).  */
    BITS_INSERT (EEFC->MC_FMR, (uint16_t) (F_CPU / 1e6), 16, 23);
#endif
}
コード例 #4
0
ファイル: adc.c プロジェクト: ishgum/Wacky-Racers
/* Set the ADC triggering.  */
void
adc_trigger_set (adc_t adc, adc_trigger_t trigger) 
{
    adc->trigger = trigger;

    /* Could also handle FREERUN here where no triggering is
       required.  */

    if (trigger == ADC_TRIGGER_SW)
    {
        BITS_INSERT (adc->MR, 0, 0, 0);
    }
    else
    {
        /* Select trigger.  */
        BITS_INSERT (adc->MR, trigger - ADC_TRIGGER_EXT, 1, 3);

        /* Enable trigger.  */
        BITS_INSERT (adc->MR, 1, 0, 0);
    }
}
コード例 #5
0
ファイル: mcpwm_xc16.c プロジェクト: UCI-CARL/embedlib
/**
 * @details No details.
 */
int mcpwm_enable_pins(mcpwm_module_t *module,
                      unsigned int pins)
{
    // Check for valid module
    if( module == NULL || module->base_address == NULL )
    {// Invalid module
        return MCPWM_E_MODULE;
    }

    *(module->base_address + MCPWM_OFFSET_PWMxCON1) = BITS_INSERT(*(module->base_address + MCPWM_OFFSET_PWMxCON1),0x00FF,pins);

    return MCPWM_E_NONE;
}
コード例 #6
0
ファイル: adc.c プロジェクト: ishgum/Wacky-Racers
/* Set the clock divider (prescaler).  */
static void
adc_clock_divisor_set (adc_t adc, adc_clock_divisor_t clock_divisor) 
{
    /* The SAM4S requires 20 clocks per sample. 

       ADC_CLOCK = (F_CPU / 2) / clock_divisor.  
    */

    if (clock_divisor >= 256)
        clock_divisor = 256;

    BITS_INSERT (adc->MR, clock_divisor - 1, 8, 15);
    adc->clock_divisor = clock_divisor;
}
コード例 #7
0
ファイル: adc.c プロジェクト: ishgum/Wacky-Racers
/** 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);
}