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; }
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; }
/** 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); }