Working SPI communication with 23LC2014.
authorethereal <ethereal@ethv.net>
Fri, 14 Mar 2014 03:42:51 +0000 (21:42 -0600)
committerethereal <ethereal@ethv.net>
Fri, 14 Mar 2014 03:42:51 +0000 (21:42 -0600)
vm/src/debug.c
vm/src/debug.h
vm/src/pio.c
vm/src/pio.h
vm/src/registers.h
vm/src/spi.c
vm/src/startup.c

index d1ce84c..3a742a9 100644 (file)
@@ -5,3 +5,94 @@ void debug_init(void) {
     uart_init();
     DEBUG("VM starting");
 }
+
+static void debug_format_int(int value);
+static void debug_format_hex(uint32_t value);
+static void debug_format_string(const char *value);
+
+void debug_helper(const char *string, ...) {
+    va_list v;
+
+    va_start(v, string);
+
+    const char *nl = "\n\r";
+
+    int i = 0;
+    while(string[i] != 0) {
+        if(string[i] == '\n') {
+            uart_send((uint8_t *)nl, 2);
+            i ++;
+            continue;
+        }
+        else if(string[i] != '%') {
+            uart_send((uint8_t *)&string[i++], 1);
+            continue;
+        }
+
+        if(string[i+1] == 0) break;
+        else if(string[i+1] == 'i') {
+            int i = va_arg(v, int);
+
+            debug_format_int(i);
+        }
+        else if(string[i+1] == 'p' || string[i+1] == 'x') {
+            uint32_t address = va_arg(v, uint32_t);
+
+            debug_format_hex(address);
+        }
+        else if(string[i+1] == 's') {
+            const char *str = va_arg(v, const char *);
+
+            debug_format_string(str);
+        }
+        i += 2;
+    }
+
+    va_end(v);
+
+    uart_send((uint8_t *)nl, 2);
+}
+
+static void debug_format_int(int value) {
+    /*
+    int size = 0;
+    if(value < 0) buffer[size++] = '-';
+    if(value == 0) buffer[size++] = '0';
+
+    while(value > 0) {
+        buffer[size++] = '0' + (value%10);
+        value /= 10;
+    }
+    //memrev(buffer, size);
+    return size;
+    */
+}
+
+static void debug_format_hex(uint32_t value) {
+    const char *hex = "0123456789abcdef";
+
+    char buffer[12];
+
+    char *bufp = buffer + 11;
+
+    int count = 0;
+    for(int j = 0; j < 8; j ++) {
+        *bufp = hex[value & 0xf];
+        bufp --;
+        count ++;
+
+        value >>= 4;
+        if(value == 0) break;
+    }
+    /**bufp = 'x';
+    bufp --;
+    *bufp = '0';*/
+
+    uart_send((uint8_t *)bufp+1, count);
+}
+
+static void debug_format_string(const char *value) {
+    int len = 0;
+    while(value[len]) len++;
+    uart_send((uint8_t *)value, len);
+}
index 2ab88d3..f3c1fd9 100644 (file)
@@ -1,10 +1,12 @@
 #ifndef DEBUG_H
 #define DEBUG_H
 
-#define DEBUG_HELPER(msg) uart_send((uint8_t *)msg, sizeof(msg))
+#include <stdarg.h>
 
-#define DEBUG(msg) DEBUG_HELPER(msg "\n\r")
+#define DEBUG(...) debug_helper(__VA_ARGS__);
 
 void debug_init(void);
 
+void debug_helper(const char *string, ...);
+
 #endif
index b89e0ef..bc206e0 100644 (file)
@@ -28,3 +28,7 @@ void pio_set_per(int bank, int id, int to) {
         register_write(PIO_PDR + off, (1U<<id));
     }
 }
+
+void pio_set_pur(int bank, int id, int to) {
+    
+}
index bfe6a48..d29ae54 100644 (file)
@@ -10,4 +10,8 @@ void pio_init(void);
 #define PIO_PER_D 4
 void pio_set_per(int bank, int id, int to);
 
+#define PIO_PUR_OFF 0
+#define PIO_PUR_ON 1
+void pio_set_pur(int bank, int id, int to);
+
 #endif
index 9959ea4..c2217b8 100644 (file)
@@ -26,6 +26,9 @@
 #define PIO_PDR     0x400e0e04
 #define PIO_OER     0x400e0e10
 #define PIO_ODR     0x400e0e14
+#define PIO_PUDR    0x400e0e60
+#define PIO_PUER    0x400e0e64
+#define PIO_PUSR    0x400e0e68
 #define PIO_ABCDSR1 0x400e0e70
 #define PIO_ABCDSR2 0x400e0e74
 
 #define SPI_CSR1    0x40008034
 #define SPI_CSR2    0x40008038
 #define SPI_CSR3    0x4000803c
+#define SPI_RPR     0x40008100
+#define SPI_RCR     0x40008104
+#define SPI_TPR     0x40008108
+#define SPI_TCR     0x4000810c
+#define SPI_RNPR    0x40008110
+#define SPI_RNCR    0x40008114
+#define SPI_TNPR    0x40008118
+#define SPI_TNCR    0x4000811c
+#define SPI_PTCR    0x40008120
+#define SPI_PTSR    0x40008124
 
 void register_write(uint32_t which, uint32_t value);
 uint32_t register_read(uint32_t which);
index 13fdba4..6796a93 100644 (file)
@@ -18,16 +18,25 @@ void spi_init(void) {
     pio_set_per(0, 12, PIO_PER_A);
     pio_set_per(0, 13, PIO_PER_A);
     pio_set_per(0, 14, PIO_PER_A);
+    
+    pio_set_pur(0, 11, PIO_PUR_OFF);
+    pio_set_pur(0, 12, PIO_PUR_OFF);
+    pio_set_pur(0, 13, PIO_PUR_OFF);
+    pio_set_pur(0, 14, PIO_PUR_OFF);
 
-    /* enable SPI */
-    register_write(SPI_CR, 1);
-
-    /* set master mode, fixed-peripheral mode, no decoder, local loopback (testing) */
+    /* set master mode, fixed-peripheral mode, no decoder, no fault detection */
     register_write(SPI_MR, (1<<0) | (1<<4));
 
     /* configure slave 0 */
-    /* CSNAAT, SPCK = MCK/2 */
-    register_write(SPI_CSR0, (1<<2) | (255<<8));
+    /* !CSAAT, CSNAAT, SPCK = MCK/2 */
+    //register_write(SPI_CSR0, (1<<2) | (2<<8));
+    register_write(SPI_CSR0, (1<<1) | (255<<8));
+    register_write(SPI_CSR1, (1<<1) | (255<<8));
+    register_write(SPI_CSR2, (1<<1) | (255<<8));
+    register_write(SPI_CSR3, (1<<1) | (255<<8));
+
+    /* enable SPI */
+    register_write(SPI_CR, 1);
 }
 
 static void spi_wait_tdre(void) {
@@ -38,8 +47,8 @@ static void spi_wait_rdrf(void) {
     while(!(register_read(SPI_SR) & 1)) {}
 }
 
+#if 0
 void spi_test(void) {
-    while(1) {
     uint8_t val[] = {0x03, 0x0, 0x0, 0x0, 0x55, 0x0};
     uint8_t ret[5];
     DEBUG("about to send");
@@ -72,4 +81,178 @@ void spi_test(void) {
         v >>= 8;
     }
     DEBUG(".");
-} }
+}
+#endif
+
+#if 0
+void spi_test(void) {
+    DEBUG("Status register: 0x%x", register_read(SPI_PTSR));
+    uint8_t tx_buffer[128];
+    uint8_t recv_buffer[128];
+
+    tx_buffer[1] = 0;
+    tx_buffer[2] = 0;
+    tx_buffer[3] = 0;
+    tx_buffer[4] = 0;
+
+    //for(int i = 0; i < 8; i ++) recv_buffer[i] = 0xaa;
+
+    for(int i = 0; i < 256; i ++) {
+        tx_buffer[i] = i;
+
+        register_write(SPI_RPR, (uint32_t)recv_buffer);
+        register_write(SPI_RCR, 5);
+
+        register_write(SPI_TPR, (uint32_t)tx_buffer);
+        register_write(SPI_TCR, 5);
+
+        DEBUG("initializing PDC transfers . . .");
+        DEBUG("SPI_RPR: 0x%x (recv_buffer: %p)", register_read(SPI_RPR), recv_buffer);
+        DEBUG("SPI_RCR: 0x%x", register_read(SPI_RCR));
+        /* begin in/out PDC transfers */
+        register_write(SPI_PTCR, (1<<0) | (1<<8));
+        DEBUG("SPI_PTSR: 0x%x", register_read(SPI_PTSR));
+
+        DEBUG("SPI_RCR: 0x%x", register_read(SPI_RCR));
+        DEBUG("SPI_SR: 0x%x", register_read(SPI_SR));
+
+        /* wait for read to finish */
+        while((register_read(SPI_SR) & (1<<4)) == 0) {
+            for(int ii = 0; ii < 3000000; ii ++) {}
+            DEBUG("SPI_RPR: 0x%x", register_read(SPI_RPR));
+            DEBUG("SPI_RCR: 0x%x", register_read(SPI_RCR));
+            DEBUG("SPI_SR: 0x%x", register_read(SPI_SR));
+        }
+        // disable PDC requests
+        register_write(SPI_PTCR, (1<<1) | (1<<9));
+
+        DEBUG("SPI_RCR: 0x%x", register_read(SPI_RCR));
+        
+        DEBUG(" -- finished!");
+        DEBUG("result: %x %x %x %x", recv_buffer[0], recv_buffer[1],
+            recv_buffer[2], recv_buffer[3]);
+        for(int j = 0; j < 5; j ++) if(recv_buffer[j] != 0xff) {
+            DEBUG("i: %x recv_buffer[%i] != 0xff!", i, j);
+            break;
+        }
+    }
+    DEBUG("SPI_PTSR: 0x%x", register_read(SPI_PTSR));
+}
+#endif
+
+void spi_test(void) {
+    DEBUG("Status register: 0x%x", register_read(SPI_PTSR));
+    uint8_t tx_buffer[8];
+    uint8_t rx_buffer[8];
+
+    for(int i = 0; i < 8; i ++) rx_buffer[i] = 0xa5;
+
+    tx_buffer[0] = 0x02;
+    tx_buffer[1] = 0;
+    tx_buffer[2] = 0;
+    tx_buffer[3] = 0;
+    tx_buffer[4] = 0xcc;
+    tx_buffer[5] = 0xcd;
+    tx_buffer[6] = 0xce;
+    tx_buffer[7] = 0xcf;
+
+    register_write(SPI_TPR, (uint32_t)tx_buffer);
+    register_write(SPI_TCR, 8);
+
+    register_write(SPI_RPR, (uint32_t)rx_buffer);
+    register_write(SPI_RCR, 8);
+
+    /* begin in/out PDC transfers */
+    register_write(SPI_PTCR, (1<<0) | (1<<8));
+
+    /* wait for read to finish */
+    while((register_read(SPI_SR) & (1<<4)) == 0) {}
+    // disable PDC requests
+    register_write(SPI_PTCR, (1<<1) | (1<<9));
+
+    for(int i = 0; i < 5; i ++) if(rx_buffer[i] != 0xff) DEBUG("non-ff!");
+
+    for(int i = 0; i < 8; i ++) rx_buffer[i] = 0xa5;
+
+    tx_buffer[0] = 0x03;
+    tx_buffer[1] = 0;
+    tx_buffer[2] = 0;
+    tx_buffer[3] = 0;
+    tx_buffer[4] = 0;
+    tx_buffer[5] = 0;
+    tx_buffer[6] = 0;
+    tx_buffer[7] = 0;
+
+    register_write(SPI_TPR, (uint32_t)tx_buffer);
+    register_write(SPI_TCR, 8);
+
+    register_write(SPI_RPR, (uint32_t)rx_buffer);
+    register_write(SPI_RCR, 8);
+
+    /* begin in/out PDC transfers */
+    register_write(SPI_PTCR, (1<<0) | (1<<8));
+
+    /* wait for read to finish */
+    while((register_read(SPI_SR) & (1<<4)) == 0) {}
+    // disable PDC requests
+    register_write(SPI_PTCR, (1<<1) | (1<<9));
+    /*for(int i = 0; i < 5; i ++) if(rx_buffer[i] != 0xff) DEBUG("non-ff! value: %x", rx_buffer[i]);*/
+
+    for(int i = 0; i < 8; i ++) {
+        DEBUG("rx_buffer[%x] = %x", i, rx_buffer[i]);
+    }
+}
+
+#if 0
+void spi_test(void) {
+    uint8_t tx_buffer[8];
+    uint8_t rx_buffer[8];
+
+    tx_buffer[0] = 0x02;
+    tx_buffer[1] = 0;
+    tx_buffer[2] = 0;
+    tx_buffer[3] = 0;
+    tx_buffer[4] = 0xcc;
+    tx_buffer[5] = 0xcd;
+    tx_buffer[6] = 0xce;
+    tx_buffer[7] = 0xcf;
+
+    for(int i = 0; i < 8; i ++) {
+        while((register_read(SPI_SR) & (1<<9)) == 0) {}
+        register_write(SPI_TDR, tx_buffer[i]);
+        if(i == 7) register_write(SPI_CR, 1<<24);
+        while((register_read(SPI_SR) & (1<<1)) == 0) {}
+        while((register_read(SPI_SR) & (1<<0)) == 0) {}
+        rx_buffer[i] = register_read(SPI_RDR) & 0xff;
+    }
+
+    DEBUG("write command sent. rx_buffer:");
+    for(int i = 0; i < 8; i ++) {
+        DEBUG("rx_buffer[%x] = %x", i, rx_buffer[i]);
+    }
+
+    tx_buffer[0] = 0x03;
+    tx_buffer[1] = 0;
+    tx_buffer[2] = 0;
+    tx_buffer[3] = 0;
+    tx_buffer[4] = 0x0;
+    tx_buffer[5] = 0x0;
+    tx_buffer[6] = 0x0;
+    tx_buffer[7] = 0x0;
+
+    for(int i = 0; i < 8; i ++) {
+        while((register_read(SPI_SR) & (1<<9)) == 0) {}
+        register_write(SPI_TDR, tx_buffer[i]);
+        if(i == 7) register_write(SPI_CR, 1<<24);
+        while((register_read(SPI_SR) & (1<<1)) == 0) {}
+        while((register_read(SPI_SR) & (1<<0)) == 0) {}
+        rx_buffer[i] = register_read(SPI_RDR) & 0xff;
+    }
+
+    DEBUG("read command sent. rx_buffer:");
+    for(int i = 0; i < 8; i ++) {
+        DEBUG("rx_buffer[%x] = %x", i, rx_buffer[i]);
+    }
+}
+#endif
+
index e18b560..a814c0e 100644 (file)
@@ -109,6 +109,8 @@ static void startup_reset_handler(void) {
     *(uint32_t *)(0x400e0e10) = 0x8;
     *(uint32_t *)(0x400e0e30) = 0x8;
 
+    while(1) {}
+
     uint8_t v = 'A';
     while(1) {
         //uart_send(&v, 1);