/* 
 * dsppseq.c  -- opcode sequences for accomplishing various 
 *            -- programming tasks in STDP mode
 *            -- for dspicprg utility 
 *
 * homer reid -- 1/2005
 */

#include "dsppseq.h"

/***************************************************/
/* Opcode sequences to be written into the dsPIC   */
/* for various programming tasks. Taken from dsPIC */
/* programming manual.                             */
/* The STDPSeq() routine reads these  sequences    */
/* and processes each element according to its MSB */
/* (fourth byte from right), as follows:           */
/*                                                 */
/* MSB=0: simple SIX command with opcode given by  */
/*        the three LSBs.                          */
/* MSB=1: execute a REGOUT command and store the   */
/*        result in the next slot in InBuf.        */
/* MSB=2: pause for number of nanoseconds given by */
/*        the three LSBs.                          */
/* MSB=3: Start of loop. Loop N times (where N is  */
/*        given by the two LSBs) over the          */
/*        instructions between here and the        */
/*        end-of-loop instruction.                 */
/* MSB=4: end-of-loop instruction (see MSB=3).     */
/* MSB=5,6,7:                                      */
/*        fill in the central 16 bits of the LSBs  */
/*        and execute as a SIX instruction.        */
/*        The value to fill in for the central 16  */
/*        bits depends on the MSB:                 */
/*        MSB=5: use next two bytes from OutBuf.   */
/*        MSB=6: use lowest 16 bits of Address.    */
/*        MSB=7: use highest 8 bits of Address.    */
/* MSB=9: End of sequence.                         */
/***************************************************/

/*--------------------------------------------------*/
/*  Bulk erase (Table 11.4) ------------------------*/
/*--------------------------------------------------*/
DWORD BulkEraseSeq[]=
 { 0x000000, 0x000000, 0x040100, 0x000000,       /* step 1 */
   0x2407FA, 0x883B0A,                           /* step 2 */
   0x200558, 0x883B38, 0x200AA9, 0x883B39,       /* step 3 */
   0xA8E761, 0x000000, 0x000000,                 /* step 4 */
   OC_PAUSE + 2000000,
   0xA9E761, 0x000000, 0x000000,
   0x040100, 0x0,                                /* reset PC */
   OC_TERMINATE
 };

/*--------------------------------------------------*/
/*  Read application ID (Table 11.14) --------------*/
/*--------------------------------------------------*/
DWORD ReadAppIDSeq[]=
 {0x0, 0x0, 0x040100, 0x0,                       /* step 1 */
  0x200800, 0x880190, 0x205FE0, 0x207841,        /* step 2 */
  0xBA0890, 0x0, 0x0,
  OC_REGOUT, 0x0,                                /* step 3 */
  0x040100, 0x0,                                 /* reset PC */
  OC_TERMINATE
 };

/*--------------------------------------------------*/
/*  Read configuration memory (Table 11.12) --------*/
/*--------------------------------------------------*/
DWORD ReadCfgSeq[]=
 { 0x000000, 0x000000, 0x040100, 0x000000,       /* step 1 */
   0x200F80, 0x880190, 0xEB0300, 0xEB0380,       /* step 2 */
   OC_LOOPSTART + 7,                             /* repeat next 9 instructions 7 times */
   0xBA0BB6, 0x000000, 0x000000, 0x883C20, 0x0,  /* step 3  (beware typo in manual) */
   OC_REGOUT, 0x0,                               /* step 4 */
   0x040100, 0x0,                                /* step 5 */
   OC_LOOPEND, OC_TERMINATE
 };

/*--------------------------------------------------*/
/*  Write configuration memory (table 11-8) --------*/
/*--------------------------------------------------*/
DWORD WriteCFGSeq[]=
 { 0x000000, 0x000000, 0x040100, 0x000000,       /* step 1 */
   OC_FILLADRSL + 0x200007,                      /* step 2 */
   0x24008A, 0x883B0A,                           /* step 3 */
   0x200F80, 0x880190,                           /* step 4 */
   OC_FILLDATA + 0x200000,                       /* step 5 */
   0xEB0300, 0xBB1B96, 0x0, 0x0,                 /* step 6 */
   0x200558, 0x883B38, 0x200AA9, 0x883B39,       /* step 7 */
   0xA8E761, 0x0, 0x0,                           /* step 8 */
   OC_PAUSE + 2000000,
   0xA9E761, 0x0, 0x0,
   0x040100, 0x0,                                /* step 9 */
   OC_TERMINATE
 };

/*--------------------------------------------------*/
/*  Read data memory (Table 11.13) -----------------*/
/*--------------------------------------------------*/
DWORD ReadDataSeq[]=
 { 0x000000, 0x000000, 0x040100, 0x000000,       /* step 1 */
   0x2007F0, 0x880190, OC_FILLADRSL + 0x200006,  /* step 2 */
   0xEB0380,                                     /* step 3 */
   0xBA1BB6, 0x0, 0x0,
   0xBA1BB6, 0x0, 0x0,
   0xBA1BB6, 0x0, 0x0,
   0xBA1BB6, 0x0, 0x0,
   0x883C20, 0x0, OC_REGOUT, 0x0,                /* step 4 */
   0x883C21, 0x0, OC_REGOUT, 0x0,
   0x883C22, 0x0, OC_REGOUT, 0x0,
   0x883C23, 0x0, OC_REGOUT, 0x0,
   0x040100, 0x0,                                /* step 5 */
   OC_TERMINATE
 };

/*--------------------------------------------------*/
/*  Write data memory (Table 11.10) ----------------*/
/*--------------------------------------------------*/
DWORD WriteDataSeq[]=
 { 0x000000, 0x000000, 0x040100, 0x000000,       /* step 1 */
   0x24005A, 0x883B0A,                           /* step 2 */
   0x2007F0, 0x880190, OC_FILLADRSL+0x200007,    /* step 3 */
   OC_LOOPSTART + 4,
   OC_FILLDATA + 0x200000,                       /* step 4 */
   OC_FILLDATA + 0x200001,
   OC_FILLDATA + 0x200002,
   OC_FILLDATA + 0x200003,
   0xEB0300, 0x0,                                /* step 5 */
   0xBB1BB6, 0x0, 0x0,
   0xBB1BB6, 0x0, 0x0,
   0xBB1BB6, 0x0, 0x0,
   0xBB1BB6, 0x0, 0x0,
   OC_LOOPEND,
   0x200558, 0x883B38, 0x200AA9, 0x883B39,       /* step 7 */
   0xA8E761, 0x0, 0x0,                           /* step 8 */
   OC_PAUSE + 2000000,
   0xA9E761, 0x0, 0x0,
   0x040100, 0x0,                                /* step 9 */
   OC_TERMINATE
 };

/*--------------------------------------------------*/
/*  Read code memory (Table 11.11) -----------------*/
/*--------------------------------------------------*/
DWORD ReadCodeSeq[]=
 { 0x000000, 0x000000, 0x040100, 0x000000,       /* step 1 */
   OC_FILLADRSH + 0x200000,                      /* step 2 */
   0x880190,
   OC_FILLADRSL + 0x200006,
   0xEB0380,                                     /* step 3 */
   0xBA1B96, 0x0, 0x0, 0xBADBB6, 0x0, 0x0,
   0xBADBD6, 0x0, 0x0, 0xBA1BB6, 0x0, 0x0,
   0xBA1B96, 0x0, 0x0, 0xBADBB6, 0x0, 0x0,
   0xBADBD6, 0x0, 0x0, 0xBA0BB6, 0x0, 0x0,
   0x883C20, 0x0, OC_REGOUT, 0x0,                /* step 4 */
   0x883C21, 0x0, OC_REGOUT, 0x0,
   0x883C22, 0x0, OC_REGOUT, 0x0,
   0x883C23, 0x0, OC_REGOUT, 0x0,
   0x883C24, 0x0, OC_REGOUT, 0x0,
   0x883C25, 0x0, OC_REGOUT, 0x0,
   0x040100, 0x0,                                /* step 5 */
   OC_TERMINATE
 };

/*--------------------------------------------------*/
/*  Write code memory (Table 11.8) -----------------*/
/*--------------------------------------------------*/
DWORD WriteCodeSeq[]=
 { 0x000000, 0x000000, 0x040100, 0x000000,       /* step 1 */
   0x24001A, 0x883B0A,                           /* step 2 */
   OC_FILLADRSH + 0x200000,                      /* step 3 */
   0x880190,
   OC_FILLADRSL + 0x200007,
   OC_LOOPSTART + 8,
   OC_FILLDATA + 0x200000,                       /* step 4 */
   OC_FILLDATA + 0x200001,
   OC_FILLDATA + 0x200002,
   OC_FILLDATA + 0x200003,
   OC_FILLDATA + 0x200004,
   OC_FILLDATA + 0x200005,
   0xEB0300, 0x0,                                /* step 5 */
   0xBB0BB6, 0x0, 0x0, 0xBBDBB6, 0x0, 0x0,
   0xBBEBB6, 0x0, 0x0, 0xBB1BB6, 0x0, 0x0,
   0xBB0BB6, 0x0, 0x0, 0xBBDBB6, 0x0, 0x0,
   0xBBEBB6, 0x0, 0x0, 0xBB1BB6, 0x0, 0x0,
   OC_LOOPEND,                                  /* step 6 */
   0x200558, 0x883B38, 0x200AA9, 0x883B39,       /* step 7 */
   0xA8E761, 0x0, 0x0, 0x0, 0x0,                /* step 8 */
   OC_PAUSE + 2000000,
   0xA9E761, 0x0, 0x0, 0x0, 0x0,
   0x040100, 0x0,                               /* step 9 */
   OC_TERMINATE
 };

/***************************************************/
/* Table of opcode sequences ***********************/
/***************************************************/
DWORD *STDPSeqList[]=
 {
   BulkEraseSeq,        /* #define STDP_BULKERASE 0 */
   ReadAppIDSeq,        /* #define STDP_READAPPID 1 */
   ReadCfgSeq,          /* #define STDP_READCFG   2 */
   WriteCFGSeq,         /* #define STDP_WRITECFG  3 */
   ReadDataSeq,         /* #define STDP_READDATA  4 */
   WriteDataSeq,        /* #define STDP_WRITEDATA 5 */
   ReadCodeSeq,         /* #define STDP_READCODE  6 */
   WriteCodeSeq,        /* #define STDP_WRITECODE 7 */
 };