Ejemplo n.º 1
0
/** \brief End of Conversion interrupt handler.
 *
 * This function starts an SPI transfer with the ADC in order to retrieve the
 * conversion result, using the SPI driver library's
 * SPI_MasterInterruptTransceivePacket().
 *
 * \note This function should be called from the ISR registered to trigger on
 * the falling edge of EOC, using INT0 of the port associated with the ADC, as
 * described in this file's documentation.
 *
 * \note Due to an unknown bug, care must be taken that this function is
 * <em>never</em> called while there is an ongoing SPI communication with the
 * ADC.
 *
 * \param[in] adc The ADC which has signalled EOC */
void ADC_EOC_interrupt_handler(ADC_ext_t *adc) {
   uint8_t status;

   /* due to an unknown bug, this is not being set properly by the SPI library.
    * This fix is a hack, and relies on the fact that this function will only be
    * called while there is not an ongoing transfer. */
   adc->SPI_master->dataPacket->complete = true;

   /* initiate a data transfer to get the conversion result */
   do {
      status = SPI_MasterInterruptTransceivePacket(adc->SPI_master,
                                                   adc->data_packet);
   } while (status != SPI_OK);
}
Ejemplo n.º 2
0
/*! \brief Test function.
 *
 *  This function tests the SPI master and slave drivers in interrupt-driven
 *  operation, with a master (on port C) communicating with a slave (on port D).
 *
 *  Hardware setup:
 *
 *    - Connect PC4 to PD4 (SS)
 *    - Connect PC5 to PD5 (MOSI)
 *    - Connect PC6 to PD6 (MISO)
 *    - Connect PC7 to PD7 (SCK)
 *
 *  The driver is tested by transmitting data from the master to the slave.
 *  The slave increments the received data and sends it back. The master reads
 *  the data from the slave and verifies that it equals the data sent + 1.
 *
 *  The first data transaction is initiated by the main routine. When a
 *  transaction has finished, an interrupt will be triggered which will start
 *  new transactions until all bytes have been transceived.
 *
 *  The variable, 'success', will be non-zero when the function reaches the
 *  infinite for-loop if the test was successful.
 *
 *  \note This example uses multilevel interrupts. For more information on how
 *        to use the interrupt controller, refer to application note AVR1305.
 */
int main( void )
{
	/* Init SS pin as output with wired AND and pull-up. */
	PORTC.DIRSET = PIN4_bm;
	PORTC.PIN4CTRL = PORT_OPC_WIREDANDPULL_gc;

	/* Set SS output to high. (No slave addressed). */
	PORTC.OUTSET = PIN4_bm;

	/* Initialize SPI master on port C. */
	SPI_MasterInit(&spiMasterC,
	               &SPIC,
	               &PORTC,
				   false,
	               SPI_MODE_0_gc,
	               SPI_INTLVL_LO_gc,
	               false,
	               SPI_PRESCALER_DIV4_gc);

	/* Initialize SPI slave on port D. */
	SPI_SlaveInit(&spiSlaveD,
	              &SPID,
	              &PORTD,
	              false,
	              SPI_MODE_0_gc,
	              SPI_INTLVL_MED_gc);

	/* Enable low and medium level interrupts in the interrupt controller. */
	PMIC.CTRL |= PMIC_MEDLVLEN_bm | PMIC_LOLVLEN_bm;
	sei();

	/* Create data packet (SS to slave by PC4) */
	SPI_MasterCreateDataPacket(&dataPacket,
	                           sendData,
	                           receivedData,
	                           NUM_BYTES + 1,
	                           &PORTC,
	                           PIN4_bm);

	/* Transmit and receive first data byte. */
	uint8_t status;
	do {
		status = SPI_MasterInterruptTransceivePacket(&spiMasterC, &dataPacket);
	} while (status != SPI_OK);

	/* Wait for transmission to complete. */
	while (dataPacket.complete == false) {

	}

	/* Check that correct data was received. Assume success at first. */
	success = true;
	for (uint8_t i = 0; i < NUM_BYTES; i++) {
		if (receivedData[i + 1] != (uint8_t)(sendData[i] + 1)) {
			success = false;
		}
	}
	while(true) {
		nop();
	}
}