void tone(uint8_t pin, uint16_t frequency, uint32_t duration)
{
	uint32_t count, load;
	volatile uint32_t *config;

	if (pin >= CORE_NUM_DIGITAL) return;
	if (duration) {
		count = (frequency * duration / 1000) * 2;
	} else {
		count = 0xFFFFFFFF;
	}
	load = (F_BUS / 2) / frequency;
	config = portConfigRegister(pin);
	__disable_irq();
	if (pin != tone_pin) {
		if (tone_pin < CORE_NUM_DIGITAL) {
			tone_reg[0] = 1; // clear pin
		}
		tone_pin = pin;
		tone_reg = portClearRegister(pin);
		tone_reg[0] = 1; // clear pin
		tone_reg[384] = 1; // output mode;
		*config = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
	}
	tone_toggle_count = count;
	if (PIT_LDVAL3 != load) {
		PIT_TCTRL3 = 0;
		PIT_LDVAL3 = load;
		PIT_TCTRL3 = 3;
	}
	__enable_irq();
}
Exemple #2
0
void tone(uint8_t pin, uint16_t frequency, uint32_t duration)
{
	uint32_t count;
	volatile uint32_t *config;
	float usec;

	if (pin >= CORE_NUM_DIGITAL) return;
	if (duration) {
		count = (frequency * duration / 1000) * 2;
	} else {
		count = 0xFFFFFFFF;
	}
	usec = (float)500000.0 / (float)frequency;
	config = portConfigRegister(pin);

	// TODO: IntervalTimer really needs an API to disable and enable
	// the interrupt on a single timer.
	__disable_irq();
	if (pin == tone_pin) {
		if (frequency == tone_frequency) {
			// same pin, same frequency, so just update the
			// duration.  Users will call repetitively call
			// tone() with the same setting, expecting a
			// continuous output with no glitches or phase
			// changes or jitter at each call.
			tone_toggle_count = count;
		} else {
			// same pin, but a new frequency.
			TONE_CLEAR_PIN; // clear pin
			tone_timer.begin(tone_interrupt, usec);
		}
	} else {
		if (tone_pin < CORE_NUM_DIGITAL) {
			TONE_CLEAR_PIN; // clear pin
		}
		tone_pin = pin;
		tone_reg = portClearRegister(pin);
		#if defined(KINETISL)
		tone_mask = digitalPinToBitMask(pin);
		#endif
		TONE_CLEAR_PIN; // clear pin
		TONE_OUTPUT_PIN; // output mode;
		*config = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
		tone_toggle_count = count;
		tone_timer.begin(tone_interrupt, usec);
	}
	__enable_irq();
}
#define CYCLES_800_T1H  (F_CPU / 1250000) // 0.7us on, .6us off ??
#define CYCLES_800      (F_CPU /  800000)
#define CYCLES_400_T0H  (F_CPU / 2000000)
#define CYCLES_400_T1H  (F_CPU /  833333)
#define CYCLES_400      (F_CPU /  400000)

    
    // TODO: test dithering??
    CRGB scale = CRGB(m_brightness, m_brightness, m_brightness); // corbin, fix m_brightness to not mess w/stuff
    // corbin...figure out how to do the template based on the type
    PixelController<GRB> pixelController(m_pixels, numLEDs, scale, DISABLE_DITHER);

    pixelController.preStepFirstByteDithering();
    
    volatile uint8_t *set = portSetRegister(pin);
    volatile uint8_t *clr = portClearRegister(pin);
    
    // Get access to the clock
    ARM_DEMCR    |= ARM_DEMCR_TRCENA; // what is this set for??
    ARM_DWT_CTRL |= ARM_DWT_CTRL_CYCCNTENA;
    ARM_DWT_CYCCNT = 0;
    
#ifdef NEO_KHZ400
    if((type & NEO_SPDMASK) == NEO_KHZ800) { // 800 KHz bitstream
#endif
        uint32_t cyc = ARM_DWT_CYCCNT + CYCLES_800;
        
        register uint8_t b = pixelController.loadAndScale0();
        while (pixelController.has(1)) {
            pixelController.stepDithering();