This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

F2802x SPI vectors Rx instead of Tx

Hi All,

Im trying to get the SPI peripheral working on my slaved F28027 (with another F28027 as master).

Currently the master sends a string to the slave while the slave outputs dummy data (all 0x0).

The slave then asserts a GPIO SRQ line when it has a response ready, the master has this SRQ line as an external interrupt input and when raised the ISR starts putting dummy data out on the MOSI line and reading data. When the slave has finished sending one char it *should* vector to the ISR for SPITXINTA and put another char into the SPITXBUF ready for transmission when it recieves the next dummy cahr from the master, yet with my current code it instead vectors to the ISR for SPIRXINTA whic relly screws things up to say the least! :0

why would the RX interrupt occur when the TX one is expected?? In fact the PIEIER flag for the SPITXINT never seems to be raised, why??

Here is my current code:

static void interrupt spiSlaveRx_isr (void) {
	/* Receives data on a slave unit from a master unit. */
	IER &= 0x86;					/* Elevate I2C, PWM and TZ groups (groups 8, 3 & 2) priority. */
	EINT;							/* Enable PIE interrupts. */
					/* Read the data from the SPI receive buffer and push the lower byte to the library input buffer */
	int16_t buf = SpiaRegs.SPIRXBUF & 0x00FF;
	if (!isSRQActive()) {		/* Check SRQ is not asserted as otherwise the received data is just dummy data */
		SpiaRegs.SPITXBUF = 0;		/* Load some dummy data for any following received byte. */
		pushInput(context, buf);	/* Push the char to the iBuff. */
	}
	DINT;							/* Disable PIE interrupts. */
	PieCtrlRegs.PIEACK.bit.ACK6 = 1;/* Acknowledge the interrupt in PIE */
}

static void interrupt spiSlaveTx_isr (void) {
	/* SPI transmission interrupt, indicating the SPI is ready for more data. */
	IER &= 0x86;					/* Elevate I2C, PWM and TZ groups (groups 8, 3 & 2) priority. */
	EINT;							/* Enable PIE interrupts. */
	char buf = 0;
	if (context->msgTerminatorSent)
		releaseSRQ();
	else {
		while (SpiaRegs.SPISTS.bit.BUFFULL_FLAG) {}
		buf = SpiaRegs.SPIRXBUF;
		if (!popOutput(context, &buf)) {
			SpiaRegs.SPITXBUF = buf << 8;
			buf = SpiaRegs.SPIRXBUF;
		} else
			releaseSRQ();
	}
	DINT;							/* Disable PIE interrupts. */
	PieCtrlRegs.PIEACK.bit.ACK6 = 1;/* Acknowledge the interrupt in PIE. */
}

int16_t spiSlaveTx (void) {
	char buf = 0;
	while (SpiaRegs.SPISTS.bit.BUFFULL_FLAG) {}	/* Wait for the transmit buffer to be ready. */
	buf = SpiaRegs.SPIRXBUF; 			/* Clear out any junk data in the buffer. */

	if (!popOutput(context, &buf)) {	/* Pop a byte from the output queue. */
		assertSRQ(); 					/* Make sure the outgoing SRQ is asserted. */
		SpiaRegs.SPITXBUF = buf << 8;	/* Move the byte to the transmit buffer (left justified). */
		buf = SpiaRegs.SPIRXBUF;		/* Read any dummy data from receive buffer to clear interrupt flag. */
		PieCtrlRegs.PIEACK.bit.ACK6 = 1;/* Make sure the acknowledge flag in the PIE is clear. */
	}
	return 0;
}

int16_t spiInit(spiMode mode, uint32_t baud, transPol cPol, spiCPha cPha) {
	float spiBrr = (float)baud;
	uint16_t temp = 7;				/* Init the config control reg (SPICCR) value. Reset on, 8-bit char length. */
	temp |= ((uint16_t) cPol) << 6;	/* Add the clock polarity setting to the SPICCR value. */
	SpiaRegs.SPICCR.all = temp;		/* Save the SPICCR value to the register. */

	temp = 0x02;					/* Init the operation control reg (SPICTL) value. Enable TALK. */
	if (mode == spiSlave)
		temp |= 0x01;				/* Enable the interrupts if this is the slave. */
	else
		temp |= 0x04;				/* Set the SPI peripheral mode to master if this is a master. */
	temp |= ((uint16_t) cPha) << 3;	/* Add the clock phase setting to the SPICTL value. */
	temp |= ((uint16_t) mode) << 2;	/* Add the mode setting to the SPICTL value. */
	SpiaRegs.SPICTL.all = temp;		/* Save the SPICTL value to the register. */

									/* Use the requested baud rate and LSPCLK frequency to calculate the
									 * SPI bit rate control value.
									 * Baud rate = (LSPCLK / [SPIBRR + 1]).
									 */
	spiBrr = (LOSPCLK_FREQ_SET / spiBrr) - 1;

	if ((spiBrr < 4) || (spiBrr > 127))	/* Ensure SPIBRR value is within bounds */
			return INVALID_VALUE;

	SpiaRegs.SPIBRR = (uint16_t) spiBrr;/* Save the |SPIBRR| value to the register. */
	SpiaRegs.SPIPRI.all = 0x00;		/* Set free-run and 4-wire mode. */

	if (mode == spiSlave) {
		releaseSRQ();				/* Make sure outgoing SRQ output is LOW. */
		EALLOW;
		PieVectTable.SPIRXINTA = &spiSlaveRx_isr;	/* Set ISR for SPI receive interrupt. */
		PieVectTable.SPITXINTA = &spiSlaveTx_isr;	/* Set ISR for SPI transmit interrupt. */
		EDIS;
		PieCtrlRegs.PIECTRL.bit.ENPIE  = 1;	/* Ensure the PIE block is enabled. */
		PieCtrlRegs.PIEIER6.bit.INTx1  = 1;	/* Enable PIE group 6, INT 1, SPIRXINTA. */
		PieCtrlRegs.PIEIER6.bit.INTx2  = 1;	/* Enable PIE group 6, INT 2, SPITXINTA. */
		IER  |= M_INT6;						/* Enable group 6 in IER */
	}
	SpiaRegs.SPITXBUF = 0;
	SpiaRegs.SPIRXBUF = 0;
	SpiaRegs.SPIDAT = 0;
	SpiaRegs.SPICCR.bit.SPISWRESET = 1;		/* Relinquish SPI from reset. */
	return 0;
}

int16_t spiMasterTx (context) {
	uint16_t i = 0;
	while (context->buffer[i]) {
		while (SpiaRegs.SPISTS.bit.BUFFULL_FLAG) {}	/* Wait until the transmit buffer is ready. */
							/* Move the next byte to be transmitted into the transmit buffer (left justified). */
		SpiaRegs.SPITXBUF = ((uint16_t) (context->slave->buffer[i])) << 8;
		context->buffer[i++] = 0;
	}
	if (context->validatedQuery) {	/* Check if the command to the slave is a query. */
		expectingSRQ = true;			/* Notify the SRQ ISR that a SRQ is expected. */

	} else {
		while (SpiaRegs.SPISTS.bit.BUFFULL_FLAG) {}	/* Wait until the last transmit is done. */
		context->finished = true;		/* Let library know the slave tx is finished. */
	}
	return 0;
}

int16_t spiMasterRx (context) {
	char buf = 0;
	while (!context->finished) {	/* Keep looking for response data until library detects the end of the MESSAGE. */
		buf = SpiaRegs.SPIRXBUF;	/* Clear junk data. */
		SpiaRegs.SPITXBUF = 0x0000;	/* Push dummy data out. */
		while (!SpiaRegs.SPISTS.bit.INT_FLAG) {}/* Wait for a data byte to be received. */
		buf = (char) SpiaRegs.SPIRXBUF & 0x00FF;/* Align and mask away any spurious data. */
		responseFromSlave(context, buf);	/* Pass the char to the library. */
	}
	return 0;
}

Thanks