summaryrefslogtreecommitdiffstats
path: root/firmware/microblaze/lib/spi.c
diff options
context:
space:
mode:
authorNick Foster <nick@nerdnetworks.org>2010-08-11 13:42:03 -0700
committerNick Foster <nick@nerdnetworks.org>2010-08-16 17:29:40 -0700
commitecc971c613d4a7dfe31bc142f99bfdba898d91eb (patch)
tree9eb42726e99b8885e5a1fcb82c1731439db48439 /firmware/microblaze/lib/spi.c
parent20d1f96f9594e299f8aef78cc70a587d1d87e289 (diff)
downloaduhd-ecc971c613d4a7dfe31bc142f99bfdba898d91eb.tar.gz
uhd-ecc971c613d4a7dfe31bc142f99bfdba898d91eb.tar.bz2
uhd-ecc971c613d4a7dfe31bc142f99bfdba898d91eb.zip
IRQ-based SPI works. Don't try to do multiple transactions without waiting for results first. In fact, don't try to do
an I2C transaction while an SPI transaction is pending.
Diffstat (limited to 'firmware/microblaze/lib/spi.c')
-rw-r--r--firmware/microblaze/lib/spi.c23
1 files changed, 14 insertions, 9 deletions
diff --git a/firmware/microblaze/lib/spi.c b/firmware/microblaze/lib/spi.c
index 33fcce05f..2a41a1bfa 100644
--- a/firmware/microblaze/lib/spi.c
+++ b/firmware/microblaze/lib/spi.c
@@ -22,6 +22,8 @@
void (*volatile spi_callback)(void); //SPI callback when xfer complete.
+static void spi_irq_handler(unsigned irq);
+
void
spi_init(void)
{
@@ -68,8 +70,10 @@ void spi_register_callback(void (*volatile callback)(void)) {
spi_callback = callback;
}
-void spi_irq_handler(void) {
- printf("SPI IRQ handler\n");
+static void spi_irq_handler(unsigned irq) {
+// printf("SPI IRQ handler\n");
+// uint32_t wat = spi_regs->ctrl; //read a register just to clear the interrupt
+ //spi_regs->ctrl &= ~SPI_CTRL_IE;
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
}
@@ -80,9 +84,12 @@ uint32_t spi_get_data(void) {
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;
+ int ctrl = SPI_CTRL_ASS | SPI_CTRL_IE | (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.
+ if(spi_regs->ctrl & SPI_CTRL_GO_BSY) {
+ printf("Async SPI busy!\n");
+ return false; //we don't wait on busy, we just return failure. we count on the host to not set up another transaction before the last one finishes.
+ }
// Tell it which SPI slave device to access
spi_regs->ss = slave & 0xffff;
@@ -90,14 +97,12 @@ spi_async_transact(int slave, uint32_t data, int length, uint32_t flags, void (*
// Data we will send
spi_regs->txrx0 = data;
+ spi_register_callback(callback);
+ pic_register_handler(IRQ_SPI, spi_irq_handler);
+
// 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;
}