This program implements a slave SPI in software for testing the SPI interface of protocoltool.

Dependencies:   mbed

Fork of 8255_emulator by Jacques Pelletier

Revision:
3:422d80770413
Parent:
2:0cc974f03339
Child:
4:241cd0193031
--- a/main.cpp	Sun Oct 27 04:39:17 2013 +0000
+++ b/main.cpp	Sun Oct 27 20:29:59 2013 +0000
@@ -11,11 +11,6 @@
 
 /* This is for testing since it uses the serial port at 9600 bauds to connect to a PC */
 
-#define PAR_INVERT_OBF_SIGNAL
-
-#define PAR_8255_SEND_MASK      0x80
-#define PAR_8255_RECV_MASK      0x40
-
 /*
   8255          Parallel    Pin     Bit
   PC7   /OBF    ->  /ACK        10      6
@@ -26,30 +21,28 @@
 15 nError       -> p9       not used
 13 Select       -> p10      not used
 12 PE           -> p11      not used
-11 Busy         -> p12      IBF
-10 nAck         -> p13      /OBF
+11 Busy         -> p12      MISO
+10 nAck         -> p13      not used
 
- 1 nStrobe      -> p14      /STB
-14 nAutoFeed    -> p15      not used
+ 1 nStrobe      -> p14      MOSI
+14 nAutoFeed    -> p15      SCLK
 16 nInit        -> p16      not used
-17 nSelectIn    -> p17      /ACK
+17 nSelectIn    -> p17      not used
 */
 
-DigitalOut IBF(p12); // IBF
-DigitalOut nOBF(p13); // /OBF
-
-InterruptIn nSTB(p14);
-InterruptIn nACK(p17);
+DigitalOut MISO(p12);
+DigitalIn MOSI(p14);
+InterruptIn SCLK(p15);
 
 /*
-D0 p30  p0.4
-D1 p29  p0.5
-D2 p8   p0.6
-D3 p7   p0.7
-D4 p6   p0.8
-D5 p5   p0.9
-D6 p28  p0.10
-D7 p27  p0.11
+CE0 p30  p0.4
+CE1 p29  p0.5
+CE2 p8   p0.6
+CE3 p7   p0.7
+CE4 p6   p0.8
+CE5 p5   p0.9
+CE6 p28  p0.10
+CE7 p27  p0.11
 */
 BusInOut PtrData(p30,p29,p8,p7,p6,p5,p28,p27);
 
@@ -60,69 +53,135 @@
 
 Serial pc(USBTX, USBRX); // tx, rx
 
-unsigned char rx_data;
+unsigned char rx_data, tx_data;
 
-// Peripheral should check that there is no output pending from the 8255 to the peripheral before writing to the 8255
+bool msb_first = true;
+bool edge_falling = false; // false: CPOL = 0, CPHA = 0; true: CPOL = 1, CPHA = 1
+bool byte_ready;
+int bit_count;
 
-// When /STB is falling
-void perif2mbed(void)
+void shift_bit(void)
 {
-    // read byte from peripheral
-    rx_data = PtrData;
-    IBF = 1;
+    if (msb_first)
+    {
+        rx_data = (rx_data << 1) | MOSI;
+        MISO = (tx_data & 0x80) >> 7;
+        tx_data <<= 1;
+    }
+    else
+    {
+        rx_data = (rx_data >> 1) | (MOSI << 7);
+        MISO = tx_data & 1;
+        tx_data >>= 1;
+    }
+    bit_count++;
+    if (bit_count == 8)
+    {
+        byte_ready = true;
+        bit_count = 0;
+    }
 }
 
-// When /ACK is rising
-void mbed2perif(void)
+void sclk_fall(void)
 {
-    nOBF = 1;
-    PtrData.input();
+    if (edge_falling && (PtrData == 0xfe))
+    {
+        shift_bit();
+    }
 }
 
-void write_byte(unsigned char out)
+void sclk_rise(void)
 {
-    // wait for /OBF = 1 and no read cycle in progress for politeness
-    while ((nOBF == 0) || (IBF == 1));
-
-    PtrData = out;
-    PtrData.output();
-    nOBF = 0;
-}
-
-unsigned char read_byte(void)
-{
-    while (IBF == 0);
-    IBF = 0;
-    return rx_data;
+   if (!edge_falling && (PtrData == 0xfe))
+   {
+        shift_bit();
+   }
 }
 
 int main()
 {
-    PtrData.input();
-
-    /* 9600 baud serial port */
-    pc.printf("8255 emulator on mbed\r\n\n");
-    
-    IBF = 0;
-    nOBF = 1;
-    nSTB.fall(&perif2mbed);
-    nACK.rise(&mbed2perif);
+unsigned char key;
+bool configure_end = true;
 
     PtrData.input();
 
+    /* 9600 baud serial port */
+    pc.printf("SPI tester on mbed\r\n\n");
+    
+    MISO = 0;
+    SCLK.fall(&sclk_fall);
+    SCLK.rise(&sclk_rise);
+    SCLK.mode(PullUp);
+    SCLK.enable_irq();
+    
+    byte_ready = false;
+    bit_count = 0;
+    
+    pc.printf("Actual configuration\r\n\n");
+    pc.printf("MSB first\r\n");
+    pc.printf("Rising edge clock\r\n\n");
+
+    pc.printf("Configure\r\n\n");
+    pc.printf("M: MSB first\r\n");
+    pc.printf("L: LSB first\r\n");
+    pc.printf("F: Falling edge clock\r\n");
+    pc.printf("R: Rising edge clock\r\n");
+    pc.printf("G: Go\r\n\n");
+
+    do
+    {
+        key = pc.getc();    
+    
+        switch (key)
+        {
+            case 'M':
+            case 'm':
+                msb_first = true;
+                pc.printf("MSB first\r\n");
+                break;
+
+            case 'L':
+            case 'l':
+                msb_first = false;
+                pc.printf("LSB first\r\n");
+                break;
+                
+            case 'F':
+            case 'f':
+                edge_falling = true;
+                pc.printf("Falling edge clock\r\n");
+                break;
+
+            case 'R':
+            case 'r':
+                edge_falling = true;
+                pc.printf("Rising edge clock\r\n");
+                break;
+                
+            case 'G':
+            case 'g':
+                configure_end = true;
+                break;
+                
+            default:
+            ;                        
+        }
+    } while (!configure_end);
+    
+    pc.printf("Configure end, begin test\r\n\n");
+
     while(1)
     {
-        // bytes from peripherals to 8255
-        if (IBF == 1)
+        if (pc.readable())
         {
-            IBF = 0;
-            pc.putc(rx_data);
+            tx_data = pc.getc();
         }
         else
         {
-            if (pc.readable())
+            if (byte_ready)
             {
-                write_byte(pc.getc());
+                pc.putc(rx_data);
+                byte_ready = false;
             }
         }  
     }