SPI Slave+DMA

General discussion on mikroC PRO for dsPIC30/33 and PIC24.
Post Reply
Author
Message
jalal_am
Posts: 57
Joined: 07 Jul 2012 16:17

SPI Slave+DMA

#1 Post by jalal_am » 28 Jul 2017 00:10

Hi mates,
I am working on SPI connection between two dsPIC33EP512MU810. master side sends the data, but the slave side does not work. I spend lots of time on it but I couldn't manage to solve its problem. I would be grateful if you take a look at the program and share your comments. or possibly provide me an example.

Thanks
The program is very large so I just decided to post SPI and DMA part to avoid wasting your time.

Code: Select all

#include "Config.h"
 unsigned short COMND, RAMP_SHAPE, LOP, FRQ_JMPN, SLP_CMP;
 float FTHETA, DELTHETA;
 volatile bit ACCDCC, ROT_DIR, REV, FRT_LOP, JMP_LOP, JMP_OC;
 int* EXAM;
 far unsigned int BUFF1A [4], BUFF1B[4], BUFF[2], BUFF2A[4], BUFF2B[4];
 int* pv1;
 unsigned int ReadWordArr[64];
 unsigned int WriteWordArr[64];

 void Timer1Int() iv IVT_ADDR_T1INTERRUPT {            //Voltage vector rotation
  T1IF_bit = 0;
/*if (ROT_DIR==1) FTHETA = FTHETA + DELTHETA;
  else FTHETA = FTHETA - DELTHETA;
  if (FTHETA>65535) FTHETA=FTHETA-65535;
  if (FTHETA<0) FTHETA=65535-FTHETA;
  THETA = FTHETA;*/
  }

 void Timer2Int() iv IVT_ADDR_T2INTERRUPT {           //Transition timer
  T2IF_bit = 0;
 /*STEP_N+=1;*/}

  void DMA1Int() iv IVT_ADDR_DMA1INTERRUPT {
unsigned int DMAREC1 =0;
 if (DMAREC1==0)
 {asm nop; }
 else{asm nop;}
 DMAREC1^=1;
 IFS0bits.DMA1IF=0;
 }
 void DMA0Int() iv IVT_ADDR_DMA0INTERRUPT {
unsigned int DMAREC =0;
 if (DMAREC==0)
 {asm nop; }
 else{asm nop;}
 DMAREC^=1;
 IFS0bits.DMA0IF=0;
 }

void SPI1_INT() iv IVT_ADDR_SPI1INTERRUPT {
  IFS0bits.SPI1IF=0;
}

  void SPI1EER() iv IVT_ADDR_SPI1ERRINTERRUPT {
  SPI1STATbits.SPIEN = 0; // Disable SPI module
  SPI1STATbits.SPIROV=0; //Clear the Receive Overflow Flag
  IFS0bits.SPI1EIF = 0; // Clear the SPI2 Error Interrupt Flag
  SPI1STATbits.SPIEN = 1; // Enable SPI module
}


 void main() {

   Osc_Config(140);
   //ADCINIT(10);
   DMA0INIT(&BUFF1A, &BUFF1B);
   TIMER1_Config();
   //////////////////////////////////////////////////////
   ANSELB=0x003C;
   TRISB=0x003C;
   ANSELD= 0x0000;
   TRISD  = 0x0000;
   ANSELG= 0x0000;
   TRISG  = 0x1000;
   Unlock_IOLOCK();
   PPS_Mapping_NoLock(126, _OUTPUT, _SDO1);     // Set pin RD5 to be Output, and map SD03 to it
   PPS_Mapping_NoLock(34, _INPUT, _SCK1IN);  // Set pin RD3 to be Output, and map SCK3 to it
   PPS_Mapping_NoLock(124, _INPUT,  _SDI1);     // Set pin RD4 to be Input,  and map SDI3 to it
   PPS_Mapping_NoLock(35, _INPUT,  _SS1IN);
   Lock_IOLOCK();
  ///////////////////////////////////////////////////////////////
/*SPI1STAT= ;
  SPI1CON1= ;
  SPI1CON2= ;*/
      SPI1_Init_Advanced(_SPI_SLAVE,             // Initialize SPI1 module
                     _SPI_16_BIT,              // master_mode    = _SPI_MASTER
                     _SPI_PRESCALE_SEC_1,     // data_mode      = _SPI_8_BIT
                     _SPI_PRESCALE_PRI_4,     // sec. prescaler = _SPI_PRESCALE_SEC_1
                     _SPI_SS_ENABLE,         // pri. prescaler = _SPI_PRESCALE_PRI_4
                     _SPI_DATA_SAMPLE_MIDDLE, // slave_select   = _SPI_SS_DISABLE (Only for slave mod)
                     _SPI_CLK_IDLE_LOW,       // data_sample    = _SPI_DATA_SAMPLE_END
                     _SPI_IDLE_2_ACTIVE);     // clock_idle     = _SPI_CLK_IDLE_HIGH
     SPI1STATbits.SPIROV=0; //Clear the Receive Overflow Flag
     IFS0BITS.SPI1EIF = 0; // Clear the Error Interrupt flag
     IEC0BITS.SPI1EIE = 1; // Enable the error interrupt
     SPI1BUF = 0; 
     SPI1STAT.SPIEN=0;                                          // edge           = _SPI_ACTIVE_2_IDLE

   ////////////////////////////////////////////////////////////////
  DMA1CON=2; //continious Ping-pong Disabled
  DMA1PAD= &SPI1BUF;
  DMA1CNT=3;
  DMA1REQ=10; //SPI1 Transfer is done
  DMA1STAL=&BUFF2A[0];
  DMA1STAH=0x000;
  DMA1STBL=&BUFF2B[0];
  DMA1STBH=0x000;
  IFS0BITS.DMA1IF=0;
  IEC0BITS.DMA1IE=1;
  DMA1CON=0x8002;
  DMA1REQ.b15= 1;
  while (DMA1REQbits.FORCE == 1);
       SPI1STAT.SPIEN=1;

   //////////////////////////////////////////////////////////////
   while (1) {
     // SPI1_Write(0x0356);
   for (LOP=0; LOP<4; LOP++){
    LATD=BUFF2A[LOP];
    Delay_us(1);
    }
  //////////////////////////////////////////////////////////////Update Frequency
for (LOP=0; LOP<4; LOP++){
    WriteWordArr[LOP]= BUFF2A[LOP];}
 for (LOP=4; LOP<64; LOP++){
    WriteWordArr[LOP]= 0;
    }
    FLASH_Erase(0x055400);
    FLASH_Write(0x055400, WriteWordArr);
    FLASH_Read(0x055400, ReadWordArr, 64);
     /////////////////////////////////////////////////////////
     }}
Oscilator configuration:

Code: Select all

 void Osc_Config(unsigned int CLKFREQ) {
  OSCCON=0x33E0;
  CLKDIV=0x0006;       //PLL's Divider Configuration (divided by CLKDIV<4:0>+2)
  PLLFBD=(CLKFREQ-1)*2;             //PLL's Feedback Congiguration (multiply by PLLFBD+2)
  //OSCTUN=0;
  //REFOCON=0;
  ACLKCON3=0xE4A0;        //Axuliary OSC PLL Configuration 0x00F0 post divider; 0x000F prescale
  ACLKDIV3=7;}    
DMA0 is used for ADC and works properly. Its code is as below:

Code: Select all

  void DMA0INIT(unsigned int BUFFA, unsigned int BUFFB ) {
   AD1CON1bits.ADON=0;
   AD1CON2bits.BUFM=0;
   AD1CON4bits.ADDMAEN=1;
   DMA0CON=2;
   DMA0PAD= &ADC1BUF0;
   DMA0CNT=3;
   DMA0REQ=13;
   DMA0STAL=BUFFA;
   DMA0STAH=0x000;
   DMA0STBL=BUFFB;
   DMA0STBH=0x0000;
   IFS0BITS.DMA0IF=0;
   IEC0BITS.DMA0IE=1;
   DMA0CONBITS.CHEN=1;
   AD1CON1bits.ADDMABM=1;
   AD1CON2bits.SMPI=3;
   AD1CON4bits.DMABL=0;
   IFS0BITS.AD1IF=0;
   IEC0BITS.AD1IE=0;
   AD1CON1bits.ADON=1;}

Post Reply

Return to “mikroC PRO for dsPIC30/33 and PIC24 General”