Added support for Silicon Lab's c8051 MCUs.
authoralexeybb <alexeybb@12e2690d-a6be-4b82-a7b7-67c4a43b65c8>
Thu, 17 Nov 2011 02:47:33 +0000 (02:47 +0000)
committeralexeybb <alexeybb@12e2690d-a6be-4b82-a7b7-67c4a43b65c8>
Thu, 17 Nov 2011 02:47:33 +0000 (02:47 +0000)
git-svn-id: https://svn.code.sf.net/p/goodfet/code/trunk@1064 12e2690d-a6be-4b82-a7b7-67c4a43b65c8

client/GoodFETSLC2.py [new file with mode: 0644]
client/Makefile
client/goodfet.slc2 [new file with mode: 0644]
firmware/apps/slc2/slc2.c [new file with mode: 0644]
firmware/config.mk
firmware/include/slc2.h [new file with mode: 0644]

diff --git a/client/GoodFETSLC2.py b/client/GoodFETSLC2.py
new file mode 100644 (file)
index 0000000..dac5067
--- /dev/null
@@ -0,0 +1,40 @@
+#!/usr/bin/env python\r
+# GoodFET Client Library\r
+\r
+import sys;\r
+import binascii;\r
+\r
+from GoodFET import GoodFET;\r
+\r
+class GoodFETSLC2(GoodFET):\r
+       """GoodFET variant for the Silicon lab C2 protocol"""\r
+       APP=0x06;\r
+       \r
+       def setup(self):\r
+               """Setup the SLC2 protocol"""\r
+               self.writecmd(0x06, 0x10, 0);\r
+\r
+       def reset(self):\r
+               self.writecmd(0x06, 0x84, 0);\r
+               \r
+       def peekblock(self, addr, len):\r
+               """Grab block from FLASH at address addr"""\r
+               dat= [addr&0xFF, (addr&0xFF00)>>8];\r
+               self.writecmd(0x06, 0x02, 2, dat);\r
+               return self.data;\r
+               \r
+       def pokeblock(self, addr, len, data):\r
+               d = [len, data];\r
+               self.writecmd(0x06, 0x03, len, d);\r
+               \r
+       def getdevid(self):\r
+               return self.writecmd(0x06, 0x80, 0, []);\r
+       \r
+       def getrevid(self):\r
+               return self.writecmd(0x06, 0x81, 0, []);\r
+               \r
+       def page_erase(self, addr):\r
+               self.writecmd(0x06, 0x82, 1, addr);\r
+       \r
+       def device_erase(self):\r
+               self.writecmd(0x06, 0x83, 0, []);\r
index c2241b6..d0b4c5f 100644 (file)
@@ -67,6 +67,10 @@ py2exe:
        sed s/PYTHONCONSOLE/goodfet.spi25c/ <p2e.txt >setup.py
        python setup.py py2exe
        mv dist/goodfet.exe dist/gfspi25.exe
        sed s/PYTHONCONSOLE/goodfet.spi25c/ <p2e.txt >setup.py
        python setup.py py2exe
        mv dist/goodfet.exe dist/gfspi25.exe
+#Silicon Labs C2
+       sed s/PYTHONCONSOLE/goodfet.slc2/ <p2e.txt >setup.py
+       python setup.py py2exe
+       mv dist/goodfet.exe dist/gfslc2.exe
 
 #Goodfet.  This must be last.
        sed s/PYTHONCONSOLE/goodfet/ <p2e.txt >setup.py
 
 #Goodfet.  This must be last.
        sed s/PYTHONCONSOLE/goodfet/ <p2e.txt >setup.py
diff --git a/client/goodfet.slc2 b/client/goodfet.slc2
new file mode 100644 (file)
index 0000000..d76aa45
--- /dev/null
@@ -0,0 +1,36 @@
+#!/usr/bin/env python\r
+\r
+# GoodFET - Silicon Lab C2\r
+\r
+import sys;\r
+import binascii;\r
+import array;\r
+import pdb;\r
+import time;\r
+\r
+from GoodFETSLC2 import GoodFETSLC2;\r
+from intelhex import IntelHex;\r
+\r
+\r
+\r
+#Initialize FET and set baud rate\r
+#pdb.set_trace();\r
+client=GoodFETSLC2();\r
+client.serInit();\r
+\r
+if(sys.argv[1]=="devid"):\r
+    client.setup();\r
+    data = client.getrevid();\r
+    #pdb.set_trace();\r
+    print "dumping contents of 8051 FLASH in dump.txt";\r
+    file = open("dump.bin", mode='wb')\r
+    address = 0;\r
+    while address < 65535:\r
+       data = client.peekblock(address,2);\r
+       address+= 2;\r
+       for j in data:\r
+           print j;\r
+            file.write(j);\r
+    file.close();\r
+\r
+\r
diff --git a/firmware/apps/slc2/slc2.c b/firmware/apps/slc2/slc2.c
new file mode 100644 (file)
index 0000000..66b2fdd
--- /dev/null
@@ -0,0 +1,520 @@
+/*! \file slc2.c
+   \author Alexey Borisenko <abori021@uottawa.ca>
+   \brief Silicon Labs C2 Debug interface
+ */
+
+#include "command.h"
+
+#ifdef __MSPGCC__
+#include <msp430.h>
+#else
+#include <signal.h>
+#include <io.h>
+#include <iomacros.h>
+#endif
+
+#include "slc2.h"
+
+#include "platform.h"
+
+
+//-----------------------------------------------------------------------------------
+// Global VARIABLES
+//-----------------------------------------------------------------------------------
+unsigned char NUM_BYTES;
+unsigned int FLASH_ADDR;
+unsigned char *C2_PTR;
+
+//! Handles a monitor command.
+void slc2_handle_fn( uint8_t const app,
+                     uint8_t const verb,
+                     uint32_t const len);
+
+// define the spi app's app_t
+app_t const slc2_app = {
+
+       /* app number */
+       SLC2,
+
+       /* handle fn */
+       slc2_handle_fn,
+
+       /* name */
+       "Silicon Labs C2",
+
+       /* desc */
+       "\tThis app handles Silicon Lab's C2 debugging protocol.\n"
+};
+
+//-----------------------------------------------------------------------------------
+// FLASH Programming Routines (High Level)
+//-----------------------------------------------------------------------------------
+//
+// These high-level routines perform the FLASH Programming Interface (FPI)
+// command sequences.
+//-----------------------------------------------------------------------------------
+// C2_Init()
+//-----------------------------------------------------------------------------------
+// - Initializes the C2 Interface for FLASH programming
+//
+void C2_Init()
+{
+       C2CKOUTPUT;
+       C2D_DriverOff;
+       C2_Reset(); // Reset the target device
+       delay_us(2); // Delay for at least 2us
+       C2_WriteAR(FPCTL); // Target the C2 FLASH Programming
+// Control register (FPCTL) for C2 Data
+// register accesses
+       C2_WriteDR(0x02); // Write the first key code to enable
+// C2 FLASH programming
+       C2_WriteDR(0x01); // Write the second key code to enable
+// C2 FLASH programming
+       delay_us(20000); // Delay for at least 20ms to ensure the
+// target is ready for C2 FLASH programming
+}
+//-----------------------------------------------------------------------------------
+// C2_GetDevID()
+//-----------------------------------------------------------------------------------
+// - Reads the target Devcie ID register and Revision ID register
+//
+unsigned char C2_GetDevID()
+{
+       C2_WriteAR(DEVICEID); // Select DeviceID regsiter for C2 Data
+// register accesses
+       return C2_ReadDR(); // Read and return the DeviceID register
+}
+
+//-----------------------------------------------------------------------------------
+// C2_GetDevID()
+//-----------------------------------------------------------------------------------
+// - Reads the target Devcie ID register and Revision ID register
+//
+unsigned char C2_GetRevID()
+{
+       C2_WriteAR(REVID); // Select DeviceID regsiter for C2 Data
+// register accesses
+       return C2_ReadDR(); // Read and return the DeviceID register
+}
+
+//-----------------------------------------------------------------------------------
+// C2_BlockRead()
+//-----------------------------------------------------------------------------------
+// - Reads a block of FLASH memory starting at <FLASH_ADDR>
+// - The size of the block is defined by <NUM_BYTES>
+// - Stores the read data at the location targeted by the pointer <C2_PTR>
+// - Assumes that FLASH accesses via C2 have been enabled prior to the function call
+// - Function call returns a ‘1’ if successful; returns a ‘0’ if unsuccessful
+//
+char C2_BlockRead()
+{
+       unsigned char i; // Counter
+       unsigned char status; // FPI status information holder
+       C2_WriteAR(FPDAT); // Select the FLASH Programming Data register
+// for C2 Data register accesses
+       C2_WriteDR(BLOCK_READ); // Send FLASH block read command
+       Poll_InBusy; // Wait for input acknowledge
+// Check status before starting FLASH access sequence
+       Poll_OutReady; // Wait for status information
+       status = C2_ReadDR(); // Read FLASH programming interface status
+       if (status != COMMAND_OK)
+               return 0;  // Exit and indicate error
+       C2_WriteDR(FLASH_ADDR >> 8); // Send address high byte to FPDAT
+       Poll_InBusy; // Wait for input acknowledge
+       C2_WriteDR(FLASH_ADDR & 0x00FF); // Send address low byte to FPDAT
+       Poll_InBusy; // Wait for input acknowledge
+       C2_WriteDR(NUM_BYTES); // Send block size
+       Poll_InBusy; // Wait for input acknowledge
+// Check status before reading FLASH block
+       Poll_OutReady; // Wait for status information
+       status = C2_ReadDR(); // Read FLASH programming interface status
+       if (status != COMMAND_OK)
+               return 0;  // Exit and indicate error
+// Read FLASH block
+       for (i=0; i<NUM_BYTES; i++)
+       {
+               Poll_OutReady; // Wait for data ready indicator
+               *C2_PTR++ = C2_ReadDR(); // Read data from the FPDAT register
+       }
+       return 1; // Exit and indicate success
+}
+//-----------------------------------------------------------------------------------
+// C2_BlockWrite()
+//-----------------------------------------------------------------------------------
+// - Writes a block of FLASH memory starting at <FLASH_ADDR>
+// - The size of the block is defined by <NUM_BYTES>
+// - Writes the block stored at the location targetted by <C2_PTR>
+// - Assumes that FLASH accesses via C2 have been enabled prior to the function call
+// - Function call returns a ‘1’ if successful; returns a ‘0’ if unsuccessful
+//
+char C2_BlockWrite()
+{
+       unsigned char i; // Counter
+       unsigned char status; // FPI status information holder
+       C2_WriteAR(FPDAT); // Select the FLASH Programming Data register
+// for C2 Data register accesses
+       C2_WriteDR(BLOCK_WRITE); // Send FLASH block write command
+       Poll_InBusy; // Wait for input acknowledge
+// Check status before starting FLASH access sequence
+       Poll_OutReady; // Wait for status information
+       status = C2_ReadDR(); // Read FLASH programming interface status
+       if (status != COMMAND_OK)
+               return 0;  // Exit and indicate error
+       C2_WriteDR(FLASH_ADDR >> 8); // Send address high byte to FPDAT
+       Poll_InBusy; // Wait for input acknowledge
+       C2_WriteDR(FLASH_ADDR & 0x00FF); // Send address low byte to FPDAT
+       Poll_InBusy; // Wait for input acknowledge
+       C2_WriteDR(NUM_BYTES); // Send block size
+       Poll_InBusy; // Wait for input acknolwedge
+
+// Check status before starting FLASH access sequence
+       Poll_OutReady; // Wait for status information
+       status = C2_ReadDR(); // Read FLASH programming interface status
+       if (status != COMMAND_OK)
+               return 0;  // Exit and indicate error
+       C2_WriteDR(FLASH_ADDR >> 8); // Send address high byte to FPDAT
+       Poll_InBusy; // Wait for input acknowledge
+       C2_WriteDR(FLASH_ADDR & 0x00FF); // Send address low byte to FPDAT
+       Poll_InBusy; // Wait for input acknowledge
+       C2_WriteDR(NUM_BYTES); // Send block size
+       Poll_InBusy; // Wait for input acknolwedge
+// Check status before writing FLASH block
+       Poll_OutReady; // Wait for status information
+       status = C2_ReadDR(); // Read FLASH programming interface status
+       if (status != COMMAND_OK)
+               return 0;  // Exit and indicate error
+// Write FLASH block
+       for (i=0; i<NUM_BYTES; i++)
+       {
+               C2_WriteDR(*C2_PTR++); // Write data to the FPDAT register
+               Poll_InBusy; // Wait for input acknowledge
+       }
+       Poll_OutReady; // Wait for last FLASH write to complete
+       return 1; // Exit and indicate success
+}
+//-----------------------------------------------------------------------------------
+// C2_PageErase()
+//-----------------------------------------------------------------------------------
+// - Erases a 512-byte FLASH page
+// - Targets the FLASH page containing the address <FLASH_ADDR>
+// - Assumes that FLASH accesses via C2 have been enabled prior to the function call
+// - Function call returns a ‘1’ if successful; returns a ‘0’ if unsuccessful
+//
+char C2_PageErase()
+{
+       unsigned char page; // Target FLASH page
+       unsigned char status; // FPI status information holder
+
+       page = (unsigned char)(FLASH_ADDR >> 9);
+// <page> is the 512-byte sector containing
+// the target <FLASH_ADDR>.
+       if (page >= NUM_PAGES - 1) // Check that target page is within range
+// (NUM_PAGES minus 1 for reserved area)
+               return 0;  // Indicate error if out of range
+       C2_WriteAR(FPDAT); // Select the FLASH Programming Data register
+// for C2 Data register accesses
+       C2_WriteDR(PAGE_ERASE); // Send FLASH page erase command
+       Poll_InBusy; // Wait for input acknowledge
+// Check status before starting FLASH access sequence
+       Poll_OutReady; // Wait for status information
+       status = C2_ReadDR(); // Read FLASH programming interface status
+       if (status != COMMAND_OK)
+               return 0;  // Exit and indicate error
+       C2_WriteDR(page); // Send FLASH page number
+       Poll_InBusy; // Wait for input acknowledge
+       Poll_OutReady; // Wait for ready indicator
+       status = C2_ReadDR(); // Read FLASH programming interface status
+       if (status != COMMAND_OK)
+               return 0;  // Exit and indicate error
+       C2_WriteDR(0x00); // Dummy write to initiate erase
+       Poll_InBusy; // Wait for input acknowledge
+       Poll_OutReady; // Wait for erase operation to complete
+       return 1; // Exit and indicate success
+}
+//-----------------------------------------------------------------------------------
+// C2_Device_Erase()
+//-----------------------------------------------------------------------------------
+// - Erases the entire FLASH memory space
+// - Assumes that FLASH accesses via C2 have been enabled prior to the function call
+// - Function call returns a ‘1’ if successful; returns a ‘0’ if unsuccessful
+//
+char C2_DeviceErase()
+{
+       unsigned char status; // FPI status information holder
+       C2_WriteAR(FPDAT); // Select the FLASH Programming Data register
+// for C2 Data register accesses
+       C2_WriteDR(DEVICE_ERASE); // Send Device Erase command
+       Poll_InBusy; // Wait for input acknowledge
+// Check status before starting FLASH access sequence
+       Poll_OutReady; // Wait for status information
+       status = C2_ReadDR(); // Read FLASH programming interface status
+       if (status != COMMAND_OK)
+               return 0;  // Exit and indicate error
+// Send a three-byte arming sequence to enable the device erase. If the sequence
+// is not received correctly, the command will be ignored.
+// Sequence: 0xDE, 0xAD, 0xA5.
+
+       C2_WriteDR(0xDE); // Arming sequence command 1
+       Poll_InBusy; // Wait for input acknowledge
+       C2_WriteDR(0xAD); // Arming sequence command 2
+       Poll_InBusy; // Wait for input acknowledge
+       C2_WriteDR(0xA5); // Arming sequence command 3
+       Poll_InBusy; // Wait for input acknowledge
+       Poll_OutReady; // Wait for erase operation to complete
+       return 1; // Exit and indicate success
+}
+//-----------------------------------------------------------------------------------
+// Primitive C2 Command Routines
+//-----------------------------------------------------------------------------------
+//
+// These routines perform the low-level C2 commands:
+// 1. Address Read
+// 2. Address Write
+// 3. Data Read
+// 4. Data Write
+// 5. Device Reset
+//-----------------------------------------------------------------------------------
+// C2_ReadAR()
+//-----------------------------------------------------------------------------------
+// - Performs a C2 Address register read
+// - Returns the 8-bit register content
+//
+unsigned char C2_ReadAR()
+{
+       unsigned char i; // Bit counter
+       unsigned char addr; // Address register read content
+// START field
+       StrobeC2CK; // Strobe C2CK with C2D driver disabled
+// INS field (10b, LSB first)
+       CLRC2D;
+       C2D_DriverOn; // Enable C2D driver (output)
+       StrobeC2CK;
+       SETC2D;
+       StrobeC2CK;
+       C2D_DriverOff; // Disable C2D driver (input)
+// ADDRESS field
+       addr = 0;
+       for (i=0; i<8; i++) // Shift in 8 bit ADDRESS field
+       { // LSB-first
+               addr >>= 1;
+               StrobeC2CK;
+               if (READC2D)
+                       addr |= 0x80;
+       }
+// STOP field
+       StrobeC2CK; // Strobe C2CK with C2D driver disabled
+
+       return addr; // Return Address register read value
+}
+//-----------------------------------------------------------------------------------
+// C2_WriteAR()
+//-----------------------------------------------------------------------------------
+// - Performs a C2 Address register write (writes the <addr> input
+// to Address register)
+//
+void C2_WriteAR(unsigned char addr)
+{
+       unsigned char i; // Bit counter
+// START field
+       StrobeC2CK; // Strobe C2CK with C2D driver disabled
+// INS field (11b, LSB first)
+       SETC2D;
+       C2D_DriverOn; // Enable C2D driver (output)
+       StrobeC2CK;
+       SETC2D;
+       StrobeC2CK;
+// ADDRESS field
+       for(i=0; i<8; i++) // Shift out 8-bit ADDRESS field
+       {
+               if(addr & 0x01)
+                       SETC2D;
+               else
+                       CLRC2D;
+               StrobeC2CK;
+               addr >>= 1;
+       }
+// STOP field
+       C2D_DriverOff; // Disable C2D driver
+       StrobeC2CK; // Strobe C2CK with C2D driver disabled
+       return;
+}
+//-----------------------------------------------------------------------------------
+// C2_ReadDR()
+//-----------------------------------------------------------------------------------
+// - Performs a C2 Data register read
+// - Returns the 8-bit register content
+//
+unsigned char C2_ReadDR()
+{
+       unsigned char i; // Bit counter
+       unsigned char dat; // Data register read content
+// START field
+       StrobeC2CK; // Strobe C2CK with C2D driver disabled
+// INS field (00b, LSB first)
+       CLRC2D;
+       C2D_DriverOn; // Enable C2D driver (output)
+       StrobeC2CK;
+       CLRC2D;
+       StrobeC2CK;
+
+// LENGTH field (00b -> 1 byte)
+       CLRC2D;
+       StrobeC2CK;
+       CLRC2D;
+       StrobeC2CK;
+// WAIT field
+       C2D_DriverOff; // Disable C2D driver for input
+       do
+       {
+               StrobeC2CK;
+       }
+       while (!READC2D); // Strobe C2CK until target transmits a ‘1’
+// DATA field
+       dat = 0;
+       for (i=0; i<8; i++) // Shift in 8-bit DATA field
+       { // LSB-first
+               dat >>= 1;
+               StrobeC2CK;
+               if (READC2D)
+                       dat |= 0x80;
+       }
+// STOP field
+       StrobeC2CK; // Strobe C2CK with C2D driver disabled
+       return dat;
+}
+
+//-----------------------------------------------------------------------------------
+// C2_WriteDR()
+//-----------------------------------------------------------------------------------
+// - Performs a C2 Data register write (writes <dat> input to data register)
+//
+void C2_WriteDR(unsigned char dat)
+{
+       unsigned char i; // Bit counter
+// START field
+       StrobeC2CK; // Strobe C2CK with C2D driver disabled
+// INS field (01b, LSB first)
+       SETC2D;
+       C2D_DriverOn; // Enable C2D driver
+       StrobeC2CK;
+       CLRC2D;
+       StrobeC2CK;
+// LENGTH field (00b -> 1 byte)
+       CLRC2D;
+       StrobeC2CK;
+       CLRC2D;
+       StrobeC2CK;
+// DATA field
+       for (i=0; i<8; i++) // Shift out 8-bit DATA field
+       { // LSB-first
+               if(dat & 0x01)
+                       SETC2D;
+               else
+                       CLRC2D;
+               StrobeC2CK;
+               dat >>= 1;
+       }
+// WAIT field
+       C2D_DriverOff; // Disable C2D driver for input
+       do
+       {
+               StrobeC2CK; // Strobe C2CK until target transmits a ‘1’
+       }
+       while (!READC2D);
+// STOP field
+       StrobeC2CK; // Strobe C2CK with C2D driver disabled
+       return;
+}
+
+//-----------------------------------------------------------------------------------
+// C2_Reset()
+//-----------------------------------------------------------------------------------
+// - Performs a target device reset by pulling the C2CK pin low for >20us
+//
+void C2_Reset()
+{
+       CLRC2CK; // Put target device in reset state by pulling
+       delay_us(20); // C2CK low for >20us
+       SETC2CK; // Release target device from reset
+}
+
+
+
+//! Handles a monitor command.
+void slc2_handle_fn( uint8_t const app,
+                     uint8_t const verb,
+                     uint32_t const len)
+{
+       prep_timer();
+       unsigned char dev_id = 0;
+       unsigned char rev_id = 0;
+       switch(verb)
+       {
+       case PEEK:
+               //C2_Reset();
+               //C2_Init();
+               NUM_BYTES = 2;
+               FLASH_ADDR = (cmddata[1] << 8) + cmddata[0];
+               C2_PTR = cmddata; //cmddata + 2;
+               //slc2_init();////
+               if(C2_BlockRead()) {
+                       txdata(app, verb, 2);
+               }else{
+                       txdata(app, NOK, 0);
+               }
+               break;
+
+       case POKE:
+               NUM_BYTES = len;
+               FLASH_ADDR = (cmddata[1] << 8) + cmddata[0];
+               C2_PTR = cmddata + 2;
+               if(C2_BlockWrite()) {
+                       txhead(app, OK, 0);
+               }else{
+                       txhead(app, NOK, 0);
+               }
+               break;
+
+       case SETUP:
+               C2_Reset();
+               C2_Init();
+               txdata(app,verb,0);
+               break;
+
+       case GETDEVID:
+               dev_id =  C2_GetDevID();
+               cmddata[0] = dev_id;
+               txdata(app, verb, 1);
+               break;
+
+       case GETREVID:
+               rev_id =  C2_GetRevID();
+               cmddata[0] = rev_id;
+               txdata(app, verb, 1);
+               break;
+
+       case PERASE:
+               FLASH_ADDR = (cmddata[1] << 8) + cmddata[0];
+               if(C2_PageErase()) {
+                       txhead(app, OK, 0);
+               }else{
+                       txhead(app, NOK, 0);
+               }
+               break;
+
+       case DERASE:
+               if(C2_DeviceErase()) {
+                       txhead(app, OK, 0);
+               }else{
+                       txhead(app, NOK, 0);
+               }
+               break;
+       case VRESET:
+               C2_Reset();
+               txdata(app,verb,0);
+               break;
+       default:
+               txdata(app, NOK, 0);
+               break;
+       }
+}
index 0660f25..196e1d8 100644 (file)
@@ -62,7 +62,7 @@ $(error Please define board, as explained in the README)
 endif
 platform := $(board)
 
 endif
 platform := $(board)
 
-AVAILABLE_APPS = monitor spi jtag sbw jtag430 jtag430x2 i2c jtagarm7 ejtag jtagxscale openocd chipcon avr pic adc nrf ccspi glitch smartcard ps2 
+AVAILABLE_APPS = monitor spi jtag sbw jtag430 jtag430x2 i2c jtagarm7 ejtag jtagxscale openocd chipcon avr pic adc nrf ccspi glitch smartcard ps2 slc2 
 
 CONFIG_sbw         = y
 
 
 CONFIG_sbw         = y
 
@@ -87,6 +87,7 @@ CONFIG_ccspi      ?= y
 CONFIG_glitch     ?= n
 CONFIG_smartcard  ?= n
 CONFIG_ps2        ?= n
 CONFIG_glitch     ?= n
 CONFIG_smartcard  ?= n
 CONFIG_ps2        ?= n
+CONFIG_slc2       ?= n
 
 #The CONFIG_foo vars are only interpreted if $(config) is unset.
 ifeq ($(config),undef)
 
 #The CONFIG_foo vars are only interpreted if $(config) is unset.
 ifeq ($(config),undef)
diff --git a/firmware/include/slc2.h b/firmware/include/slc2.h
new file mode 100644 (file)
index 0000000..8cded5c
--- /dev/null
@@ -0,0 +1,92 @@
+/*! \file slc2.h
+  \author Alexey Borisenko <abori021@uottawa.ca>
+  \brief Definitions for Silicon Lab C2 debugging application
+  NOTE: FPDAT register address can be different, based on the device
+  Current address is meant for the 8051f34x
+*/
+
+#ifndef SLC2_H
+#define SLC2_H
+
+#include "app.h"
+
+#define SLC2 0x06
+
+//Pins and I/O
+#define C2CK BIT7
+#define C2D BIT6
+
+#define SETC2CK P3OUT |= C2CK
+#define CLRC2CK P3OUT &= ~C2CK
+#define SETC2D P3OUT |= C2D
+#define CLRC2D P3OUT &= ~C2D
+
+#define READC2D (P3IN&C2D?1:0)
+
+#define C2CKOUTPUT P3DIR|=C2CK
+#define C2D_DriverOff P3DIR&=~C2D
+#define C2D_DriverOn P3DIR|=C2D
+
+#define DATA_READ  0x00
+#define ADDR_READ  0x02
+#define DATA_WRITE 0x01
+#define ADDR_WRITE 0x03
+
+// FLASH information
+#define FLASH_SIZE 65536 // FLASH size in bytes
+#define NUM_PAGES FLASH_SIZE/512 // Number of 512-byte FLASH pages
+
+// C2 status return codes
+#define INVALID_COMMAND 0x00
+#define COMMAND_FAILED 0x02
+#define COMMAND_OK 0x0D
+
+// C2 interface commands
+#define GET_VERSION 0x01
+#define BLOCK_READ 0x06
+#define BLOCK_WRITE 0x07
+#define PAGE_ERASE 0x08
+#define DEVICE_ERASE 0x03
+
+// C2 Registers
+#define FPDAT 0xAD
+#define FPCTL 0x02
+#define DEVICEID 0x00
+#define REVID 0x01
+
+// Program MACROS
+#define Poll_OutReady while(!(C2_ReadAR()&0x01))
+#define Poll_InBusy while((C2_ReadAR()&0x02))
+#define StrobeC2CK CLRC2CK; SETC2CK
+
+// C2 verbs
+#define GETDEVID 0x80
+#define GETREVID 0x81
+#define PERASE 0x82
+#define DERASE 0x83
+#define VRESET 0x84
+
+void slc2_handle_fn( uint8_t const app,
+                                       uint8_t const verb,
+                                       uint32_t const len);
+
+extern app_t const slc2_app;
+
+// FLASH programming functions
+void C2_Init();
+unsigned char C2_GetDevID(void);
+char C2_BlockRead(void);
+char C2_BlockWrite(void);
+char C2_PageErase(void);
+char C2_DeviceErase(void);
+// Primitive C2 functions
+void C2_Reset(void);
+void C2_WriteAR(unsigned char);
+unsigned char C2_ReadAR(void);
+void C2_WriteDR(unsigned char);
+unsigned char C2_ReadDR(void);
+unsigned char C2_ReadDeviceID(void);
+unsigned char C2_ReadRevID(void);
+
+
+#endif