summaryrefslogtreecommitdiffstats
path: root/firmware/microblaze/lib/spi.c
diff options
context:
space:
mode:
authorNick Foster <nick@nerdnetworks.org>2010-08-11 11:49:48 -0700
committerNick Foster <nick@nerdnetworks.org>2010-08-16 17:29:40 -0700
commit5b5f8901f5dfa179af3718a8a31001206a886ed3 (patch)
tree24eb9f08af195b81b4719e942a02b122305c4d1a /firmware/microblaze/lib/spi.c
parentc23a4c4334960b4c136e5cdb5b09556ea0d7c9a8 (diff)
downloaduhd-5b5f8901f5dfa179af3718a8a31001206a886ed3.tar.gz
uhd-5b5f8901f5dfa179af3718a8a31001206a886ed3.tar.bz2
uhd-5b5f8901f5dfa179af3718a8a31001206a886ed3.zip
first stab at irq'ed spi
Diffstat (limited to 'firmware/microblaze/lib/spi.c')
-rw-r--r--firmware/microblaze/lib/spi.c41
1 files changed, 41 insertions, 0 deletions
diff --git a/firmware/microblaze/lib/spi.c b/firmware/microblaze/lib/spi.c
index bef808e57..4371b9b8a 100644
--- a/firmware/microblaze/lib/spi.c
+++ b/firmware/microblaze/lib/spi.c
@@ -17,6 +17,9 @@
#include "spi.h"
#include "memory_map.h"
+#include "nonstdio.h"
+
+void (*volatile spi_callback)(void); //SPI callback when xfer complete.
void
spi_init(void)
@@ -59,3 +62,41 @@ spi_transact(bool readback, int slave, uint32_t data, int length, uint32_t flags
else
return 0;
}
+
+void spi_register_callback(void (*volatile callback)(void)) {
+ spi_callback = callback;
+}
+
+void spi_irq_handler(void) {
+ printf("SPI IRQ handler\n");
+ if(spi_callback) spi_callback(); //we could just use the PIC to register the user's callback, but this provides the ability to do other things later
+}
+
+uint32_t spi_get_data(void) {
+ return spi_regs->txrx0;
+}
+
+bool
+spi_async_transact(int slave, uint32_t data, int length, uint32_t flags, void (*volatile callback)(void)) {
+ flags &= (SPI_CTRL_TXNEG | SPI_CTRL_RXNEG);
+ int ctrl = SPI_CTRL_ASS | (SPI_CTRL_CHAR_LEN_MASK & length) | flags;
+
+ if(spi_regs->ctrl & SPI_CTRL_GO_BSY) return false; //we don't wait on busy, we just return failure.
+
+ // Tell it which SPI slave device to access
+ spi_regs->ss = slave & 0xffff;
+
+ // Data we will send
+ spi_regs->txrx0 = data;
+
+ // Run it -- write once and rewrite with GO set
+ spi_regs->ctrl = ctrl;
+ spi_regs->ctrl = ctrl | SPI_CTRL_GO_BSY;
+
+ spi_regs->ctrl |= SPI_CTRL_IE; //we do these here so that we don't have to start the PIC before the SPI sets up the clocks on startup
+ pic_register_handler(IRQ_SPI, spi_irq_handler);
+
+ spi_register_callback(callback);
+
+ return true;
+}