• AVR Freaks

Helpful ReplyHot!dspic33ck128MP208 - DMA reading SPI causes softtrap w/undocumented INTCON3 value

Author
cbarn
Starting Member
  • Total Posts : 51
  • Reward points : 0
  • Joined: 2007/01/20 11:02:14
  • Location: 0
  • Status: offline
2019/03/22 10:47:40 (permalink)
0

dspic33ck128MP208 - DMA reading SPI causes softtrap w/undocumented INTCON3 value

As I was attempting to bring up use of a DMA channel to read the SPI2BUF, the program starting causing softtraps where INTCON3 has a value of 0x20.  This value is not documented in the family datasheet.
 
I've used DMA w/CK family from the ADC without issues previously.  I've used SPI with ISR (CK family) without issues.  But putting it together hasn't worked.  I've tested w/both SPI1 and SPI2. 
 
This application doesn't need to write SPI, so ultimately will use null write, but for now I just write to SPI2BUFL thinking that will cause the DMA to read the SPI2BUFL when that transmission is complete.  So - I'm probably not doing this correctly - but I've become stuck on what appears to be a crazy softtrap.
 
Believe the code is now running using the built in FRC and I've not specified the use of any IOs.  Before cutting it down, I was able to the SPI clock on an IO when I wrote to SPIBUFL.
 
My code - 
void SPI1_Initialize (uint16_t clk_div)
{
    SPI1CON1H = 0x00;
    SPI1CON2L = 0x00;
    SPI1STATL = 0x00;
    
    SPI1BRGL = clk_div;

    SPI1IMSKL = 0x00;
    SPI1IMSKH = 0x00;
    SPI1URDTL = 0x00;
    SPI1URDTH = 0x00;
    
    SPI1CON1L = 0;
    SPI1CON1Lbits.MODE16 = 1; // 1 or 0 causes trap
    SPI1CON1Lbits.MSTEN = 1;
    
    SPI1IMSKLbits.SPIRBFEN = 1;
    SPI1CON1Lbits.SPIEN = 1;
    
    _SPI1TXIP = 0;
    _SPI1IE = 0;
}



#define DMA_BUFFER_ITEMS 64
struct {
  // working buffer
  uint16_t p_buffer[DMA_BUFFER_ITEMS];
  uint16_t buffer_end;
} spi_dma_state;


// prepare the DMA controller reads a fixed number of samples
void DMA_SPI_configure(uint16_t n_items) {
  
  DMACON = 0 ; // disable mod
  
  // set DMA module address limits
  DMAL = 0; // DMAL = (uint16_t)buffer;
  DMAH = 10000; // DMAH = (uint16_t)&spi_dma_state.buffer_end;

  DMACH0 = 0; // disable channel 0

  DMASRC0 = (uint16_t)SPI1BUFL;
  DMADST0 = (uint16_t)spi_dma_state.p_buffer;
  DMACNT0 = n_items;

#define DMA_TRIGGER_SPI1_RX 0x2
#define DMA_TRIGGER_SPI2_RX 0x10
#define DMA_TRIGGER_SPI3_RX 0x62
  //DMAINT0bits.CHSEL = DMA_TRIGGER_SPI2_RX;
    DMAINT0bits.CHSEL = DMA_TRIGGER_SPI1_RX;

    // DMACH0bits.NULLW = 1;
    // DMACH0bits.RELOAD = 1;
    // DMACH0bits.SAMODE = 3;
    // DMACH0bits.DAMODE = 0;
    // DMACH0bits.TRMODE = 0;
    DMACH0bits.CHEN = 1;

  DMACON = 0x8000; // enable module, fixed priority
  _DMA0IF = 0;
  _DMA0IP = 0;
  _DMA0IE = 0;
}



int main(void)
{
  volatile uint32_t j;
  
  // CLOCK_Initialize();

    __builtin_disable_interrupts();
    
    DMA_SPI_configure(10);
    //SPI2_Initialize (250);
    SPI1_Initialize (250);
    __builtin_disable_interrupts();
    
    while(1) {
      // SPI2BUFL = 55; // without the write to the buffer, no SPI activity -> no trap
      SPI1BUFL = 55; // without the write to the buffer, no SPI activity -> no trap
       for(j=0;j<30215;j++) asm("NOP");
     }
    
    return 1;
}

 
 
Code to setup the dspic :
#include <xc.h>
// Configuration bits: selected in the GUI

// FOSCSEL
#pragma config FNOSC = FRC //Oscillator Source Selection->Internal Fast RC (FRC)
#pragma config IESO = OFF //Two-speed Oscillator Start-up Enable bit->Start up device with FRC, then switch to user-selected oscillator source

// FICD
#pragma config ICS = PGD3 //ICD Communication Channel Select bits->Communicate on PGC3 and PGD3
#pragma config JTAGEN = OFF //JTAG Enable bit->JTAG is disabled
#pragma config NOBTSWP = DISABLED //BOOTSWP instruction disable bit->BOOTSWP instruction is disabled

// FBTSEQ
#pragma config BSEQ = 4095 //Relative value defining which partition will be active after device Reset; the partition containing a lower boot number will be active->4095
#pragma config IBSEQ = 4095 //The one's complement of BSEQ; must be calculated by the user and written during device programming.->4095

// FBOOT
#pragma config BTMODE = SINGLE //Device Boot Mode Configuration->Device is in Single Boot (legacy) mode


typedef enum
{
    /* ----- Traps ----- */
    TRAPS_OSC_FAIL = 0, /** Oscillator Fail Trap vector */
    TRAPS_STACK_ERR = 1, /** Stack Error Trap Vector */
    TRAPS_ADDRESS_ERR = 2, /** Address error Trap vector */
    TRAPS_MATH_ERR = 3, /** Math Error Trap vector */
    TRAPS_HARD_ERR = 7, /** Generic Hard Trap vector */
    TRAPS_APLL_ERR = 11, /** Generic Soft Trap vector */
} TRAPS_ERROR_CODE;
void __attribute__((naked, noreturn, weak)) TRAPS_halt_on_error(uint16_t code);

#define ERROR_HANDLER __attribute__((interrupt, no_auto_psv, keep, section("error_handler")))
#define ERROR_HANDLER_NORETURN ERROR_HANDLER __attribute__((noreturn))
#define FAILSAFE_STACK_GUARDSIZE 8

static uint16_t TRAPS_error_code = -1;
void __attribute__((naked, noreturn, weak)) TRAPS_halt_on_error(uint16_t code)
{
    TRAPS_error_code = code;
#ifdef __DEBUG
    __builtin_software_breakpoint();
    /* If we are in debug mode, cause a software breakpoint in the debugger */
#endif
    while(1);
    
}


void ERROR_HANDLER_NORETURN _OscillatorFail(void)
{
    INTCON1bits.OSCFAIL = 0; //Clear the trap flag
    TRAPS_halt_on_error(TRAPS_OSC_FAIL);
}

/** Address error Trap vector**/
void ERROR_HANDLER_NORETURN _AddressError(void)
{
    INTCON1bits.ADDRERR = 0; //Clear the trap flag
    TRAPS_halt_on_error(TRAPS_ADDRESS_ERR);
}
/** Math Error Trap vector**/
void ERROR_HANDLER_NORETURN _MathError(void)
{
    INTCON1bits.MATHERR = 0; //Clear the trap flag
    TRAPS_halt_on_error(TRAPS_MATH_ERR);
}
/** Generic Hard Trap vector**/
void ERROR_HANDLER_NORETURN _HardTrapError(void)
{
    INTCON4bits.SGHT = 0; //Clear the trap flag
    TRAPS_halt_on_error(TRAPS_HARD_ERR);
}
/** Generic Soft Trap vector**/
void ERROR_HANDLER_NORETURN _SoftTrapError(void)
{
  // INTCON3bits.APLL = 0; //Clear the trap flag
  // TRAPS_halt_on_error(TRAPS_APLL_ERR);
  TRAPS_halt_on_error(INTCON3);
  
}



post edited by cbarn - 2019/03/22 11:11:00

Attached Image(s)

#1
Weydert
Super Member
  • Total Posts : 483
  • Reward points : 0
  • Joined: 2008/07/02 04:22:40
  • Location: Aachen/Germany
  • Status: offline
Re: dspic33ck128MP208 - DMA reading SPI causes softtrap w/undocumented INTCON3 value 2019/03/24 02:24:38 (permalink) ☄ Helpfulby cbarn 2019/03/24 10:21:58
4 (1)
hi,
change:
DMASRC0 = (uint16_t)SPI1BUFL;
to
DMASRC0 = (uint16_t)&SPI1BUFL;
and try again.

Best Regards


Rainer
#2
cbarn
Starting Member
  • Total Posts : 51
  • Reward points : 0
  • Joined: 2007/01/20 11:02:14
  • Location: 0
  • Status: offline
Re: dspic33ck128MP208 - DMA reading SPI causes softtrap w/undocumented INTCON3 value 2019/03/24 10:31:02 (permalink)
0
Weydert - getting the correct source address fixed the trap - thank you for catching this.
 
Any thoughts on bit 5 being set in INTCON3?  This is undocumented behavior.
I would have expected ADDRERR or DMACERR to be set in INTCON1.  

Although looking closer, I see that INTCON1.DMACERR is also bit 5 .  And possibly the _AddressError trap should have been taken.   Looks like in the dspic33F - bit 5 of INTCON1 would have been set (no INTCON3) and there is  a special trap for DMA errors (_DMACError).
 
 
post edited by cbarn - 2019/03/24 10:44:30
#3
Gort2015
Klaatu Barada Nikto
  • Total Posts : 3122
  • Reward points : 0
  • Joined: 2015/04/30 10:49:57
  • Location: 0
  • Status: offline
Re: dspic33ck128MP208 - DMA reading SPI causes softtrap w/undocumented INTCON3 value 2019/03/24 11:07:35 (permalink)
0
The CH and CK chips, bit 5 of INTCON3 is always read as zero.
 
 
 
Wait for it...

MPLab X playing up, bug in your code? Nevermind, Star Trek:Discovery will be with us soon.
https://www.youtube.com/watch?v=Iu1qa8N2ID0
+ ST:Continues, "What Ships are Made for", Q's back.
#4
cbarn
Starting Member
  • Total Posts : 51
  • Reward points : 0
  • Joined: 2007/01/20 11:02:14
  • Location: 0
  • Status: offline
Re: dspic33ck128MP208 - DMA reading SPI causes softtrap w/undocumented INTCON3 value 2019/03/24 21:47:25 (permalink)
0
Gort2015
The CH and CK chips, bit 5 of INTCON3 is always read as zero.
Wait for it...

Did you make my mistake and not read the full post?  Please look at this screen shot.  Pretty sure you can reproduce it with the code I attached.

#5
Gort2015
Klaatu Barada Nikto
  • Total Posts : 3122
  • Reward points : 0
  • Joined: 2015/04/30 10:49:57
  • Location: 0
  • Status: offline
Re: dspic33ck128MP208 - DMA reading SPI causes softtrap w/undocumented INTCON3 value 2019/03/25 17:45:36 (permalink)
0
It is documented in both the reference manuals for CH and CK chips.
 
From Docs: (Page 116 of CK)
U = Unimplemented bit, read as ‘0’
post edited by Gort2015 - 2019/03/25 18:00:07

MPLab X playing up, bug in your code? Nevermind, Star Trek:Discovery will be with us soon.
https://www.youtube.com/watch?v=Iu1qa8N2ID0
+ ST:Continues, "What Ships are Made for", Q's back.
#6
spdmtl
New Member
  • Total Posts : 10
  • Reward points : 0
  • Status: offline
Re: dspic33ck128MP208 - DMA reading SPI causes softtrap w/undocumented INTCON3 value 2019/04/24 13:32:42 (permalink)
0
Interrupt FRM 70000600 linked in datasheet has INTCON3<5> defined as DMA address trap
 
bit 5 DAE: DMA Address Error Soft Trap Status bit
1 = DMA Address error soft trap has occurred
0 = DMA Address error soft trap has not occurred
#7
Jump to:
© 2019 APG vNext Commercial Version 4.5