Ejemplo n.º 1
0
uint8_t IrTransceiver_Transmit(uint16_t *buffer, uint8_t length)
{
	data_transmitted = 0;
	if (timesCounter == 0) return IR_NO_DATA;
	timesIndex = 1;
	IR_COMPARE_REG = IR_COUNT_REG + times[0];
#if (IR_RX_ACTIVE_LOW == 1)
	PORTC &= ~(1<<PC5);
#else
	PORTC |= (1<<PC5);
#endif
	IR_UNMASK_COMPARE();
	
	while (!data_transmitted);
	
	return IR_OK;
}
int IrTransceiver_Transmit(uint8_t channel, uint16_t *buffer, uint8_t start, uint8_t length, uint16_t modfreqkHz)
{
	if (modfreqkHz == 0) {
		/* Invalid frequency. */
		return -1;
	}

	if (length == 0) {
		/* No data. */
		return -2;
	}

	if (drvIrTxChannel[channel].timeoutEnable == TRUE) {
		/* Channel busy. */
		return -3;
	}

	/* New modulation frequency. */
	if (modfreqkHz != drvIrTxModFreqkHz) {
		/* Check that no transmissions are ongoing. */
		for (uint8_t i = 0; i < IR_SUPPORTED_NUM_CHANNELS; i++) {
			/* Channel is waiting for an overflow. */
			if (drvIrTxChannel[i].timeoutEnable == TRUE) {
				/* Transmission active. */
				return -4;
			}
		}
	}

	/* Update modulation frequency. */
	drvIrTxModFreqkHz = modfreqkHz;

	/* Start new transmission. */
	drvIrTxChannel[channel].timeoutEnable = TRUE;
	drvIrTxChannel[channel].txbuf = buffer;
	drvIrTxChannel[channel].txlen = start + length;

	/* first value will be loaded directly to timer below, therefore index is set to 1 here */
	drvIrTxChannel[channel].txindex = 1 + start;
	drvIrTxChannel[channel].timeout = IR_COUNT_REG + drvIrTxChannel[channel].txbuf[start];

	/* go through all channels and find the one that have the next overflow */
	uint8_t nextChannel = 0;
	uint16_t timeRemaining = 0xffff;
	uint16_t timeNow = IR_COMPARE_REG;
	for (uint8_t i = 0; i < IR_SUPPORTED_NUM_CHANNELS; i++)
	{
		/* channel is not waiting for an overflow */
		if (drvIrTxChannel[i].timeoutEnable == FALSE) continue;

		if (drvIrTxChannel[i].timeout - timeNow < timeRemaining)	// || (timeout - time > 0xffff-IR_MAX_PULSE_WIDTH)
		{
			timeRemaining = drvIrTxChannel[i].timeout - timeNow;
			nextChannel = i;
		}
	}

	/* set compare value to the channel that have the next overflow */
	IR_COMPARE_REG = drvIrTxChannel[nextChannel].timeout;

	/* set up modulation frequency */
	IR_MODULATION_REG = (((F_CPU / 2000) / drvIrTxModFreqkHz) - 1);

	/* Start send on pin */
	IR_OUTP_HIGH();

	/* enable overflow interrupt */
	IR_UNMASK_COMPARE();
	
	return 1;
}