SENT Transmission (SPC Pulse
Reception)
#include <xc.h>
#define FCY (8E+06)
#include <libpic30.h>
#define mFclk (4E+6)
#define mTickTime (50E-6)
#define mFrameTime (25E-3)
#define mSPCPulseWidth (56 * mTickTime)
void InputCapture_configure(void);
void SENT_Tx_configure(void);
uint8_t count = 0;
uint16_t falling_edge_capture = 0, rising_edge_capture = 0,delta,firstRead;
float pulseWidth;
int main(void) {
SENT_Tx_configure(); // Configure SENT for Transmission
InputCapture_configure(); // Configure Input Capture
while (1);
return 0;
}
void InputCapture_configure(void) {
_ICM1R = 27; // RP27 as Input Capture 1
CCP1CON1bits.CCSEL = 1; // Input capture mode
CCP1CON1bits.CLKSEL = 0; // Set the clock source (FPB/2)
CCP1CON1bits.T32 = 0; // 16-bit Dual Timer mode
CCP1CON1bits.MOD = 3; // Capture every edge of the event
CCP1CON2bits.ICS = 0; // Capture rising edge on the Pin
CCP1CON1bits.OPS = 0; // Interrupt on every input capture event
CCP1CON1bits.TMRPS = 0; // Set the clock pre-scaler (1:1)
CCP1CON1bits.ON = 1; // Enable CCP/input capture
CCP1TMR = 0;
__delay_ms(10);
_CCP1IF = 0; // Clear CCP interrupt flag
_CCP1IE = 1; // Enable CCP interrupt
}
void SENT_Tx_configure(void) {
_RP27R = 57; // RP27 as SENT1 output
SENT1CON1bits.RCVEN = 0; // Module operates as a transmitter
SENT1CON1bits.TXM = 1; // Synchronous Transmit
SENT1CON1bits.NIBCNT = 6; // 6 data nibbles per data packet
SENT1CON1bits.CRCEN = 1; // CRC is calculated using the J2716 method
SENT1CON1bits.PPP = 1; // SENTx messages transmitted with Pause Pulse
SENT1CON1bits.PS = 0; // Module clock is FSENT
SENT1CON2 = ((mTickTime * mFclk) - 1); // TICKTIME
SENT1CON3 = (mFrameTime / mTickTime); // FRAMETIME
_SENT1IE = 1; // Enable SENT1 interrupt
SENT1CON1bits.ON = 1; // Enable SENT module
SENT1DATbits.STAT = 0; // Status Nibble
SENT1DATbits.DATA1 = 1; // Data Nibble 1
SENT1DATbits.DATA2 = 2; // Data Nibble 2
SENT1DATbits.DATA3 = 3; // Data Nibble 3
SENT1DATbits.DATA4 = 4; // Data Nibble 4
SENT1DATbits.DATA5 = 5; // Data Nibble 5
SENT1DATbits.DATA6 = 6; // Data Nibble 6
}
void __attribute__((__interrupt__, __no_auto_psv__)) _CCP1Interrupt(void) {
_CCP1IF = 0; // Clear interrupt flag
count++;
if (count == 1) // Falling edge of the SPC pulse
{
firstRead = CCP1BUF;
falling_edge_capture = CCP1BUF;
} else if (count == 2)// Raising edge of the SPC pulse
{
count = 0; // Clear count
rising_edge_capture = CCP1BUF;
if (rising_edge_capture <= falling_edge_capture) {
delta = (0xFFFF - falling_edge_capture) + rising_edge_capture;// Rollover case
} else {
delta = rising_edge_capture - falling_edge_capture;// Non-rollover case
}
pulseWidth = delta / mFclk; // Calculate the pulse width
// Check if pulse width is within the range
if ((mSPCPulseWidth * 1.2) >= pulseWidth && (mSPCPulseWidth * 0.8) <= pulseWidth) {
_CCP1IE = 0; // Disable CCP interrupt
CCP1CON1bits.ON = 0; // Disable CCP/input capture
SENT1STATbits.SYNCTXEN = 1; // Initiate Synchronous Transmission
}
}
}
void __attribute__((__interrupt__, __no_auto_psv__)) _SENT1Interrupt(void) {
_SENT1IF = 0; // Clear SENT1 interrupt flag
while (SENT1STATbits.PAUSE == 1); // Wait till PAUSE pulse is transmitted
CCP1CON1bits.ON = 1; // Enable CCP/input capture
CCP1TMR = 0;
__delay_ms(1);
_CCP1IF = 0; // Clear CCP interrupt flag
_CCP1IE = 1; // Enable CCP interrupt
}
SENT Reception (SPC Pulse Transmission)
#include <xc.h>
#define FCY (8E+6)
#include<libpic30.h>
#define mFclk (4E+6)
#define mTickTime (50E-6)
#define mFrameTime (25E-3)
#define mSyncCount (8 * mFclk * mTickTime)
#define mSyncMin (0.8 * mSyncCount)
#define mSyncMax (1.2 * mSyncCount)
void OutputCompare_configure();
void SENT_RX_configure();
void SendSPCPulse();
uint8_t mReceivedData[7];
uint8_t i;
int main(void) {
ANSELB = 0;
_TRISC6 = 1; // Connect a Pull-Up switch to RC15
OutputCompare_configure(); // Configure Output Compare
SENT_RX_configure(); // Configure SENT for Reception
while(_RC6 == 0); // Wait till pull-up switch is pressed
SendSPCPulse(); // Send SPC pulse
while(1)
{
if(SENT1STATbits.RXIDLE == 1) // Check if the line is Idle
{
//Receiver can request for SENT data through SendSPCPulse() function
SendSPCPulse();
}
}
return 0;
}
void OutputCompare_configure(){
_CCP3IF = 0; // Clear CCP interrupt flag
_CCP3IE = 1; // Enable CCP interrupt
// Set MCCP operating mode
CCP3CON1bits.CCSEL = 0; // Set MCCP operating mode (OC mode)
CCP3CON1bits.MOD = 0b100; // Set mode
//Configure MCCP Timebase
CCP3CON1bits.T32 = 0; // Set timebase width (16-bit)
CCP3CON1bits.TMRSYNC = 0; // Set timebase synchronization
CCP3CON1bits.CLKSEL = 0b000; // Set the clock source (FSENT)
CCP3CON1bits.TMRPS = 0b00; // Set the clock pre-scaler (1:1)
CCP3CON1bits.ONESHOT = 1;
CCP3CON1bits.TRIGEN = 1; // Set Sync/Triggered mode (Synchronous)
CCP3CON1bits.SYNC = 0b1001; // Select Sync/Trigger source
//Configure MCCP output for PWM signal
CCP3CON2bits.OCAEN = 1; // Enable desired output signals (OC1A)
CCP3CON3bits.POLACE = 1; //Configure output polarity (Active High)
CCP3CON3bits.OSCNT = 0;
CCP3TMR = 0x0000; //Initialize timer prior to enable module.
CCP3RA = (56 * mTickTime * mFclk); // Set the rising edge compare value
CCP3RB = (56 * mTickTime * mFclk)*2; // Set the falling edge compare value
CCP3PR = CCP3RB; //Configure timebase period
CCP3CON1bits.ON = 1; // Enable MCCP module
}
void SENT_RX_configure()
{
_RP26R = 57; // RP26 as SENT1 output
_SENT1R = 26; // RP26 as SENT1 input
SENT1CON1bits.RCVEN = 1; // Module operates as a receiver
SENT1CON1bits.NIBCNT = 6; // 6 data nibbles per data packet
SENT1CON1bits.CRCEN = 1; // CRC is calculated using the J2716 method
SENT1CON1bits.PPP = 1; // SENTx messages transmitted with Pause Pulse
SENT1CON1bits.PS = 0; // Module clock is FSENT
SENT1CON1bits.SPCEN = 1; // Enable SPC
SENT1CON2 = mSyncMax; // SYNCMAX
SENT1CON3 = mSyncMin; // SYNCMIN
_SENT1IE = 1; // Enable SENT1 interrupt
SENT1CON1bits.ON = 1; // Enable SENT module
}
void SendSPCPulse()
{
CCP3STATbits.TRSET = 1; // Set the Trigger
while(CCP3STATbits.CCPTRIG);
}
void __attribute__((__interrupt__,__no_auto_psv__)) _CCP3Interrupt (void)
{
_CCP3IF = 0; // Clear interrupt flag
CCP3STATbits.TRSET = 0; // Set the Trigger
CCP3CON1bits.ON = 0; // Disable MCCP module
}
void __attribute__((__interrupt__,__no_auto_psv__)) _SENT1Interrupt (void)
{
_SENT1IF = 0; // Clear interrupt flag
i=0;
mReceivedData[i++] = SENT1DATbits.STAT; // Read STAT
mReceivedData[i++] = SENT1DATbits.DATA1; // Read DATA1
mReceivedData[i++] = SENT1DATbits.DATA2; // Read DATA2
mReceivedData[i++] = SENT1DATbits.DATA3; // Read DATA3
mReceivedData[i++] = SENT1DATbits.DATA4; // Read DATA4
mReceivedData[i++] = SENT1DATbits.DATA5; // Read DATA5
mReceivedData[i++] = SENT1DATbits.DATA6; // Read DATA6
while(SENT1STATbits.PAUSE == 1); // Wait till PAUSE pulse is received
CCP3CON1bits.ON = 1; // Enable MCCP module
}