This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TMS320F28069M: Debugger stucking at ILLEGAL ISR

Part Number: TMS320F28069M
/**
 * SPI DMA transfer to a SSD1306 OLED display
 *
 * The example transfers 8 bits of data internally with the Digital LoopBack(DLB)
 * with the McBSP module in SPI Master mode with 8 bit DMA support.
 *
 * The waveforms are observable on the following McBSP pins:
 *
 * SSD1306 McBSP    GPIO      Pin       Signal
 * -------------------------------------------------
 * RESET         -> GPIO23 -> Pin#49
 * D/C           -> GPIO44 -> Pin#18
 * SCLK -> MCLKX -> GPIO22 -> Pin#08 -> SPICLK
 * MOSI -> MDX   -> GPIO20 -> Pin#45 -> SPISIMO
 *
 * By default for the McBSP examples, the McBSP sample rate generator (SRG)
 * input clock frequency is LSPCLK 80E6/4.
 */

#include "DSP28x_Project.h"

#define LCDWIDTH                    128                 /* Cols 0 - 127                     */
#define LCDHEIGHT                   64                  /* Rows 0 - 63                      */
#define LAST_PAGE                   7                   /* Page end address                 */

#define LCD_PIXELS                  (LCDWIDTH * LCDHEIGHT)
#define LCD_BYTES                   (LCD_PIXELS / 8)
#define LAST_COL                    (LCDWIDTH)
#define LAST_ROW                    (LCDHEIGHT)

#pragma DATA_SECTION(rdata, "DMARAML5")                 /* buffer in DMA L5 SRAM            */
Uint16 rdata[1024];                                     /* Received Data                    */
#pragma DATA_SECTION(sdata, "DMARAML5")                 /* buffer in DMA L5 SRAM            */
Uint16 sdata[128];                                      /* Send Data                        */

#define SETLOWCOLUMN                0x00
#define EXTERNALVCC                 0x01
#define SWITCHCAPVCC                0x02
#define SETHIGHCOLUMN               0x10
#define MEMORYMODE                  0x20
#define COLUMNADDR                  0x21
#define PAGEADDR                    0x22

#define SCROLL_ENABLE               0x2F
#define SCROLL_DISABLE              0x2E
#define SCROLL_SET_VERT_AREA        0xA3
#define SCROLL_RIGHT_HORIZ          0x26
#define SCROLL_LEFT_HORIZONTAL      0x27
#define SCROLL_VERT_RIGHT_HORIZ     0x29
#define SCROLL_VERT_LEFT_HORIZ      0x2A

#define SETSTARTLINE                0x40
#define SETCONTRAST                 0x81
#define CHARGEPUMP                  0x8D
#define SEGREMAP                    0xA0
#define SETSEGMENTREMAP             0xA1
#define DISPLAYALLON_RESUME         0xA4
#define DISPLAYALLON                0xA5
#define NORMALDISPLAY               0xA6
#define INVERTDISPLAY               0xA7
#define SETMULTIPLEX                0xA8
#define DISPLAYOFF                  0xAE
#define DISPLAYON                   0xAF
#define COMSCANINC                  0xC0
#define COMSCANDEC                  0xC8
#define SETDISPLAYOFFSET            0xD3
#define SETDISPLAYCLOCKDIV          0xD5
#define SETPRECHARGE                0xD9
#define SETCOMPINS                  0xDA
#define SETVCOMDETECT               0xDB

#pragma DATA_SECTION(init, "DMARAML5");                 /* dmatab in DMA L5 SRAM            */
Uint16 init[] = {
        0xae,                                           /* DISPLAYOFF                       */
        0xd5,                                           /* SETDISPLAYCLOCKDIV to 0x80       */
        0x80,
        0xa8,                                           /* SETMULTIPLEX                     */
        LCDHEIGHT - 1,
        0xd3,                                           /* SETDISPLAYOFFSET to 0x00         */
        0x00,
        0x40,                                           /* line #0 | SETSTARTLINE           */
        0x8d,                                           /* CHARGEPUMP setup                 */
        0x14,
        0x20,                                           /* MEMORYMODE addressing            */
        0x00,
        0xa0 | 0x1,                                     /* SEGREMAP                         */
        0xc8,                                           /* COMSCANDEC                       */
        0xda,                                           /* SETCOMPINS                       */
        0x12,
        0x81,                                           /* SETCONTRAST to 0xef              */
        0xcf,
        0xd9,                                           /* SETPRECHARGE period              */
        0xf1,
        0xdb,                                           /* SETVCOMDETECT level              */
        0x40,
        0xa4,                                           /* DISPLAYALLON_RESUME              */
        0xa6,                                           /* NORMALDISPLAY                    */
        0x2e,                                           /* SCROLL_DISABLE                   */
        0xaf,                                           /* DISPLAYON                        */
};

#define BLACK                       0
#define WHITE                       1
#define INVERSE                     2

typedef int int16_t;
typedef int int8_t;
typedef Uint8 uint8_t;
typedef unsigned int uint16_t;
typedef unsigned char uchar;

volatile enum dmaio_state {
    IO_COMPLETE     = 0,
    IO_PENDING      = 1,
} io_state;

#define ssd1306_swap(a, b)          { int16_t t = a; a = b; b = t; }

#pragma DATA_SECTION(fb, "DMARAML5")                    /* buffer in DMA L5 SRAM            */
Uint16 fb[1024];

/**
 *  MCBSP_INIT_DELAY determines the amount of CPU cycles in the 2 sample rate
 *  generator (SRG) cycles required for the Mcbsp initialization routine.
 *  MCBSP_CLKG_DELAY determines the amount of CPU cycles in the 2 clock
 *  generator (CLKG) cycles required for the Mcbsp initialization routine.
 */
#define CPU_SPD             80E6
#define MCBSP_SRG_FREQ      CPU_SPD / 2                 /* SRG input = LSPCLK (SYSCLKOUT/2) */
#define MCBSP_DELAY         2*(CPU_SPD/MCBSP_SRG_FREQ)  /* CPU cycles in 2 SRG init delay   */

void delay_loop(void)
{
    long i;

    for (i = 0; i < MCBSP_DELAY; i++) { }               /* must be at least 2 SRG cycles    */
}

void error(void)
{
    __asm("     ESTOP0");                               /* STOP on Error                    */
    for (;;);
}

void init_mcbspa_gpio(void)
{
    EALLOW;
    GpioCtrlRegs.GPAMUX2.bit.GPIO20 = 2;                /* GPIO20=MDXA, data tx, MOSI       */
    GpioCtrlRegs.GPAMUX2.bit.GPIO22 = 2;                /* GPIO22=CLKXA, clk tx, SCL        */
    GpioCtrlRegs.GPAQSEL2.bit.GPIO22 = 3;               /* Asynch input GPIO22 (MCLKXA)     */
    EDIS;
}

void dma_xfer(Uint16 *src, Uint16 len)
{
    io_state = IO_PENDING;                              /* dont allow concurrent transfers  */

    EALLOW;
    DmaRegs.DMACTRL.bit.HARDRESET = 1;
    __asm(" NOP");                                      /* Only 1 NOP needed per design     */

    /**
     * Channel 1, McBSPA Transmit
     */
    DmaRegs.CH1.MODE.bit.CHINTE = 0;

    DmaRegs.CH1.BURST_SIZE.all = 0;                     /* 1 word/burst                     */
    DmaRegs.CH1.SRC_BURST_STEP = 0;                     /* no effect with 1 word/burst      */
    DmaRegs.CH1.DST_BURST_STEP = 0;                     /* no effect with 1 word/burst      */

    DmaRegs.CH1.TRANSFER_SIZE = len;                    /* Interrupt after len              */
    DmaRegs.CH1.SRC_TRANSFER_STEP = 1;                  /* Increment address on every word  */
    DmaRegs.CH1.DST_TRANSFER_STEP = 0;                  /* Don't change detination          */

    DmaRegs.CH1.SRC_ADDR_SHADOW = (Uint32) src;                     /* Source is buffer     */
    DmaRegs.CH1.SRC_BEG_ADDR_SHADOW = (Uint32) src;                 /* Only for wrap fn     */
    DmaRegs.CH1.DST_ADDR_SHADOW = (Uint32) &McbspaRegs.DXR1.all;    /* Dest. is McBSPA DXR  */
    DmaRegs.CH1.DST_BEG_ADDR_SHADOW = (Uint32) &McbspaRegs.DXR1.all;/* Only for wrap fn     */

    DmaRegs.CH1.CONTROL.bit.PERINTCLR = 1;              /* Clear interrupt event flag       */
    DmaRegs.CH1.CONTROL.bit.ERRCLR = 1;                 /* Clear sync error flag            */

    DmaRegs.CH1.DST_WRAP_SIZE = 0xffff;                 /* Max len, no destination wrap     */
    DmaRegs.CH1.SRC_WRAP_SIZE = 0xffff;                 /* Max len, no source wrap          */

    DmaRegs.CH1.MODE.bit.CHINTE = 1;                    /* Enable channel interrupt         */
    DmaRegs.CH1.MODE.bit.CHINTMODE = 1;                 /* Interrupt at end of transfer     */
    DmaRegs.CH1.MODE.bit.PERINTE = 1;                   /* Enable peripheral interrupt      */
    DmaRegs.CH1.MODE.bit.PERINTSEL = DMA_MXEVTA;        /* McBSPA peripheral, MXSYNCA int   */

    DmaRegs.CH1.CONTROL.bit.PERINTCLR = 1;              /* Clear spurious interrupt flags   */

    /**
     * Channel 2, McBSPA Receive
     * We do really need to read, if we don't read the next SPI frame fails
     * Save reception buffer size by reading the burst into the same buffer
     */
    DmaRegs.CH2.MODE.bit.CHINTE = 0;

    DmaRegs.CH2.BURST_SIZE.all = 0;                     /* 1 word/burst                     */
    DmaRegs.CH2.SRC_BURST_STEP = 0;                     /* no effect with 1 word/burst      */
    DmaRegs.CH2.DST_BURST_STEP = 0;                     /* no effect with 1 word/burst      */

    DmaRegs.CH2.TRANSFER_SIZE = len;                    /* Interrupt after len              */
    DmaRegs.CH2.SRC_TRANSFER_STEP = 0;                  /* Don't move source address        */
    DmaRegs.CH2.DST_TRANSFER_STEP = 1;                  /* Don't move desination address    */

    DmaRegs.CH2.SRC_ADDR_SHADOW = (Uint32) &McbspaRegs.DRR1.all;    /* Source is McBSPA DRR */
    DmaRegs.CH2.SRC_BEG_ADDR_SHADOW = (Uint32) &McbspaRegs.DRR1.all;/* Only for wrap fn     */
    DmaRegs.CH2.DST_ADDR_SHADOW = (Uint32) &rdata[0];               /* Dest. is Buffer      */
    DmaRegs.CH2.DST_BEG_ADDR_SHADOW = (Uint32) &rdata[0];           /* Only for wrap fn     */

    DmaRegs.CH2.CONTROL.bit.PERINTCLR = 1;              /* Clear interrupt event flag       */
    DmaRegs.CH2.CONTROL.bit.ERRCLR = 1;                 /* Clear sync error flag            */

    DmaRegs.CH2.DST_WRAP_SIZE = 0xFFFF;                 /* Max len, no destination wrap     */
    DmaRegs.CH2.SRC_WRAP_SIZE = 0xFFFF;                 /* Max len, no source wrap          */

    DmaRegs.CH2.MODE.bit.CHINTE = 1;                    /* Enable channel interrupt         */
    DmaRegs.CH2.MODE.bit.CHINTMODE = 1;                 /* Interrupt at end of transfer     */
    DmaRegs.CH2.MODE.bit.PERINTE = 1;                   /* Enable peripheral interrupt      */
    DmaRegs.CH2.MODE.bit.PERINTSEL = DMA_MREVTA;        /* McBSPA peripheral, MRSYNCA int   */

    DmaRegs.CH2.CONTROL.bit.PERINTCLR = 1;              /* Clear spurious interrupt flags   */

    /* start DMA    */
    DmaRegs.CH1.CONTROL.bit.RUN = 1;                    /* Start McBSPA DMA Transmission    */
    DmaRegs.CH2.CONTROL.bit.RUN = 1;                    /* Start McBSPA DMA Reception       */

    EDIS;

    /* init SPI peripheral  */
    McbspaRegs.SPCR2.all = 0x0000;                      /* Reset FS gen, SRG & Tx           */
    McbspaRegs.SPCR1.all = 0x0000;                      /* Reset Rx, Right justify, DLB dis */

    McbspaRegs.PCR.all = 0x0F08;                        /* (CLKXM=CLKRM=FSXM=FSRM=1,FSXP=1) */
    McbspaRegs.SPCR1.bit.DLB = 1;
    McbspaRegs.MFFINT.all = 0x0;                        /* Disable all interrupts           */

    McbspaRegs.SPCR1.bit.CLKSTP = 3;                    /* clock schema with CLKXP/CLKRP    */
    McbspaRegs.PCR.bit.CLKXP = 0;                       /* CPOL=0,CPHA=1,rise edge,no delay */
    McbspaRegs.PCR.bit.CLKRP = 0;                       /* if CLKSTP=2, then CPHA=0         */

    McbspaRegs.RCR2.bit.RDATDLY = 01;                   /* FSX setup time 1 = master mode   */
    McbspaRegs.XCR2.bit.XDATDLY = 01;                   /* FSX setup time 1 = master mode   */

    McbspaRegs.RCR1.bit.RWDLEN1 = 0;                    /* 5=32-bit word                    */
    McbspaRegs.XCR1.bit.XWDLEN1 = 0;                    /* 5=32-bit word                    */

    McbspaRegs.SRGR2.all = 0x2000;                      /* CLKSM=1, FPER=1 CLKG periods     */
    McbspaRegs.SRGR1.all = 0x000f;                      /* Frame Width=1, CLKGDV=16; 0x0f   */

    McbspaRegs.SPCR2.bit.GRST = 1;                      /* Enable the sample rate generator */
    delay_loop();                                       /* Wait at least 2 SRG clock cycles */
    McbspaRegs.SPCR2.bit.XRST = 1;                      /* Release TX from Reset            */
    McbspaRegs.SPCR1.bit.RRST = 1;                      /* Release RX from Reset            */
    McbspaRegs.SPCR2.bit.FRST = 1;                      /* Frame Sync Generator reset       */
}

void ssd1306_reset(void)
{
    GpioDataRegs.GPACLEAR.bit.GPIO23 = 1;               /* RESET = 0                        */
    DELAY_US(10000);                                    /* wait 10ms                        */
    GpioDataRegs.GPASET.bit.GPIO23 = 1;                 /* RESET = 1                        */
    DELAY_US(50000);                                    /* wait 50mS                        */
}

void ssd1306_init(void)
{
    GpioDataRegs.GPBCLEAR.bit.GPIO44 = 1;               /* D/C default LOW (CMD MODE)       */
    dma_xfer(init, sizeof(init));                       /* SSD1306 Initialition             */
}

void setup_lcd_pins(void)
{
    EALLOW;
    GpioCtrlRegs.GPAPUD.bit.GPIO23 = 1;                 /* disable pullup for RESET         */
    GpioCtrlRegs.GPBPUD.bit.GPIO44 = 1;                 /* disable pullup for D/C           */

    GpioCtrlRegs.GPAMUX2.bit.GPIO23 = 0;                /* setup GPIO::RESET                */
    GpioCtrlRegs.GPBMUX1.bit.GPIO44 = 0;                /* setup GPIO::D/C                  */

    GpioCtrlRegs.GPADIR.bit.GPIO23 = 1;                 /* setup Output::Reset              */
    GpioCtrlRegs.GPBDIR.bit.GPIO44 = 1;                 /* setup Output::D/C                */
    EDIS;

    GpioDataRegs.GPASET.bit.GPIO22 = 1;                 /* RESET default HIGH (Release)     */
}

void lcd_fb_put(void)
{
    while (io_state != IO_COMPLETE);                    /* wait for dma completion          */
    GpioDataRegs.GPBSET.bit.GPIO44 = 1;                 /* D/C default HIGH (DATA MODE)     */
    dma_xfer(fb, sizeof(fb));                           /* SSD1306 Graphic data             */
}

void fb_clear(void)
{
    Uint8 i;

    while (io_state != IO_COMPLETE);                    /* wait for dma completion          */

    for (i = 0; i < (LCDWIDTH * LCDHEIGHT / 8); i++)
        fb[i] = 0x00;
}

/**
 * Set window region for CGRAM access
 * void lcd_set_window(uint16_t c_start,
 *                     uint16_t p_start,
 *                     uint16_t c_stop,
 *                     uint16_t p_stop)
 *
 * @uint16_t c_start    : COLUMN start address
 * @uint16_t p_start    : PAGE start address
 * @uint16_t c_stop     : COLUMN end address
 * @uint16_t p_stop     : PAGE end address
 */
void lcd_set_window(uint16_t c_start,
                    uint16_t p_start,
                    uint16_t c_stop,
                    uint16_t p_stop)
{
    sdata[0] = COLUMNADDR;                              /* Set Column Address (0x21)        */
    sdata[1] = c_start;                                 /* COL start; eg 0                  */
    sdata[2] = c_stop;                                  /* COL end; max 'lcdwidth -1'; 127  */
    sdata[3] = PAGEADDR;                                /* Set Page Address (0x22)          */
    sdata[4] = p_start;                                 /* PAGE start; 0                    */
    sdata[5] = p_stop;                                  /* PAGE end; max=7((lcdheight/8)-1) */

    while (io_state != IO_COMPLETE);                    /* wait for dma completion          */
    GpioDataRegs.GPBCLEAR.bit.GPIO44 = 1;               /* CMD mode                         */
    dma_xfer(sdata, 5);                                 /* transfer 6 bytes                 */
}

/* INT7.1 is DMA Ch1    */
__interrupt void isr_dma_ch1(void)
{
    EALLOW;
    DmaRegs.CH1.CONTROL.bit.HALT = 1;
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP7;             /* Interrupt ACK                    */
    EDIS;
    return;
}

/* INT7.2 is DMA Ch2    */
__interrupt void isr_dma_ch2(void)
{
    EALLOW;
    DmaRegs.CH2.CONTROL.bit.HALT = 1;
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP7;             /* Interrupt ACK                    */
    io_state = IO_COMPLETE;
    EDIS;
    return;
}

void main(void)
{
    InitSysCtrl();
    init_mcbspa_gpio();

    DINT;
    InitPieCtrl();
    IER = 0x0000;
    IFR = 0x0000;
    InitPieVectTable();

    EALLOW;
    PieVectTable.DINTCH1 = &isr_dma_ch1;                /* Tx ISR DMA CH1 INT7.1            */
    PieVectTable.DINTCH2 = &isr_dma_ch2;                /* Rx ISR DMA CH2 INT7.2            */
    EDIS;

    setup_lcd_pins();
    ssd1306_reset();                                    /* Reset LCD                        */

    PieCtrlRegs.PIECTRL.bit.ENPIE = 1;                  /* Enable PIE block                 */
    PieCtrlRegs.PIEIER7.bit.INTx1 = 1;                  /* Enable PIE Group 7 INT1(DMA CH1) */
    PieCtrlRegs.PIEIER7.bit.INTx2 = 1;                  /* Enable PIE Group 7 INT2(DMA CH2) */
    IER = 0x40;                                         /* Enable CPU INT Group 7           */
    EINT;                                               /* Enable Global Interrupts         */

    ssd1306_init();                                     /* initialize LCD                   */

    fb_clear();                                         /* clear fb array                   */
    lcd_set_window(0, 0, 127, 7);                       /* col:0-127, page:0-7 access       */
    fb[0] = 0xff;                                       /* draw 8 pixels @x=0, y=0-7        */
    lcd_fb_put();                                       /* write to ssd1306                 */

    while (1) {}
}