I've been trying to get SPI working on my dsPic33FJ64MC802 for a few days now so I'm desperately needing help because nothing seems to be coming out of SCK1 or SDO according to the o-scope.
This is what I'm trying to achieve:
- SPI in master mode
- don't care about sdi
- should be able to see sck or sdo on the oscope
What I noticed that may be wrong:
- reconfiguring the pins does not seem to work (I've tried unlocking them with no success)
I never found a full SPI example for the pic33 online, so this is what I have from several examples:
#include "SPIUtils.h"
#include<spi.h>
// this may not be needed, I'm not sure
_FOSC(IOL1WAY_OFF);
unsigned int datard ;
void __attribute__((__interrupt__,auto_psv)) _SPI1Interrupt(void)
{
IFS0bits.SPI1IF = 0;
}
void __attribute__((__interrupt__,auto_psv)) _SPI2Interrupt(void)
{
IFS2bits.SPI2IF = 0;
SPI1STATbits.SPIROV = 0; /* Clear SPI1 receive overflow
flag if set */
}
// For dsPic33FJ64MC802 on a pic microstick
void SPITransmit() {
//__builtin_disi(20); // need to disable interupts first?
// PPS needs to first unlock the pins before re-assignment
__builtin_write_OSCCONL(0x46); // unlock sequence - step 1
__builtin_write_OSCCONH(0x57); // unlock sequence - step 2
_IOLOCK = 0;
// Pins can now change - though, these don't change in the SFR debugger window... why?
_RP0R = 8; // configure sck1 as output on pin 4 /RB0/RP0
_RP1R = 7; // configure sdo as output on pin 5 /RB1/RP1
RPINR20bits.SCK1R = 4; //configure sck1 as input on pin 4
RPINR20bits.SDI1R = 6; // configure SDI for input on pin 6
// these change as expected in the debugger
TRISBbits.TRISB0 = 0; //sck pin 4 as output
TRISBbits.TRISB1 = 0; //sdo pin 5 as output
TRISBbits.TRISB2 = 1; //sdi pin 6 as input
/* Holds the information about SPI configuartion */
unsigned int SPICONValue = 0;
/* Holds the information about SPI Enable/Disable */
unsigned int SPISTATValue = 0;
/* Turn off SPI modules */
CloseSPI1();
CloseSPI2();
TMR1 = 0;
/* Configure SPI1 interrupt */
ConfigIntSPI1(SPI_INT_EN & SPI_INT_PRI_6);
/* Configure SPI1 module to transmit 16 bit timer1 value in master mode */
SPICONValue = FRAME_ENABLE_OFF & FRAME_SYNC_OUTPUT & ENABLE_SDO_PIN & SPI_MODE16_ON &
SPI_SMP_OFF & SPI_CKE_OFF & SLAVE_ENABLE_OFF & CLK_POL_ACTIVE_HIGH &
MASTER_ENABLE_ON & SEC_PRESCAL_7_1 & PRI_PRESCAL_64_1;
SPISTATValue = SPI_ENABLE & SPI_IDLE_CON & SPI_RX_OVFLOW_CLR;
// what is this third parameter..? the tools library does not mention it.
// is this the problem? The two parameter OpenSPI1 is not available
OpenSPI1(SPICONValue, SPISTATValue, 0);
SPICONValue = FRAME_ENABLE_OFF & FRAME_SYNC_OUTPUT & ENABLE_SDO_PIN & SPI_MODE16_ON &
SPI_SMP_OFF & SPI_CKE_OFF & SLAVE_ENABLE_OFF & CLK_POL_ACTIVE_HIGH &
MASTER_ENABLE_OFF & SEC_PRESCAL_7_1 & PRI_PRESCAL_64_1;
SPISTATValue = SPI_ENABLE & SPI_IDLE_CON & SPI_RX_OVFLOW_CLR;
OpenSPI2(SPICONValue, SPISTATValue, 0);
// for the moment, I only care about monitoring data out and the clk in the
// o-scope
while (1) {
// repeadtedly send out 10101..
WriteSPI1(0xAAAA);
while (SPI1STATbits.SPITBF);
}
// don't care about the input
// while (!DataRdySPI2());
// datard = ReadSPI2();
// if (datard <= 600) {
// PORTBbits.RB0 = 1;
// }
/* Turn off SPI module and clear IF bit */
CloseSPI1();
CloseSPI2();
__builtin_write_OSCCONL(0x46); // unlock sequence - step 1
__builtin_write_OSCCONH(0x57); // unlock sequence - step 2
_IOLOCK = 1; // re-lock the ports
}
and use it like so:
#include <p33FJ64MC802.h>
#include <stdint.h>
#include <xc.h>
#include "main.h"
#include "BlinkLed.h"
#include "SPIUtils.h"
int main()
{
//BlinkLedOnPortB(2, 8);
SPITransmit();
return 0;
}
I can't tell what on earth I'm doing wrong. This is the pic microstick.
Best Answer
You don't need to remap your SPI peripheral inside SPITransmit() this only needs to be done once inside your main() for example. Also you can only use the SPI peripheral once the pin assignment is locked. What you are trying to do is transmit while the pin assignment is unlocked therefore in essence your pins have not been properly remapped.
Try the suggestion below.