From: Philip Withnall <philip@tecnocode.co.uk>
Date: Sat, 1 Dec 2012 10:00:20 +0000 (+0000)
Subject: spi: Clear SPIF when writing to SPDR
X-Git-Tag: v1.2~46
X-Git-Url: https://git.htl-mechatronik.at/public/?a=commitdiff_plain;h=a7d538ddb31a6cc7f0511c4d4a15d1ff5e42871b;p=sx%2Fsimavr.git

spi: Clear SPIF when writing to SPDR

The manual says the SPIF bit is cleared when accessing (i.e. reading _or_
writing) the SPDR register after an interrupt is raised. By clearing SPIF
on a write to SPDR, the following code starts to work:

   SPDR = 0xff; loop_until_bit_is_set (SPSR, SPIF);
   SPDR = 0x00; loop_until_bit_is_set (SPSR, SPIF);

(where the bytes are arbitrarily chosen). This didn’t work before as the
SPIF bit wasn’t cleared by the second write to SPDR, so the second loop
turned into a no-op. This caused the write timer for the first byte to be
overwritten by the write timer for the second. Consequently, the first byte
never got transmitted.

Signed-off-by: Michel Pollet <buserror@gmail.com>
---

diff --git a/simavr/sim/avr_spi.c b/simavr/sim/avr_spi.c
index ecac48d..e97d824 100644
--- a/simavr/sim/avr_spi.c
+++ b/simavr/sim/avr_spi.c
@@ -51,7 +51,9 @@ static void avr_spi_write(struct avr_t * avr, avr_io_addr_t addr, uint8_t v, voi
 	avr_spi_t * p = (avr_spi_t *)param;
 
 	if (addr == p->r_spdr) {
-	//	printf("avr_spi_write = %02x\n", v);
+		/* Clear the SPIF bit. See ATmega164/324/644 manual, Section 18.5.2. */
+		avr_regbit_clear(avr, p->spi.raised);
+
 		avr_core_watch_write(avr, addr, v);
 		avr_cycle_timer_register_usec(avr, 100, avr_spi_raise, p); // should be speed dependent
 	}