- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I need collect data from PIC18F4550 by SPI connection. The PIC is the Master running with Polarity = 0 and Phase = 1. The FPGA uses Altera IP SPI (3 wires Serial). All wires [SCK, MISO, MOSI and SS] are correct connected. The transfer works but with a lot of errors. A huge part of bytes toggle one or more bits. The problem can occur in all eight bits. Sometimes correct transfers are done. Tracking the origin of errors, I implement a function on PIC, controlling the SPI wires, for emulate the SPI transfer and certify about what's is happening. This function controls the time between bits and time between transfers. The code are below. In FPGA side, I'm polling for detection of new byte and print it in NIOS console. I tried different byte patterns for my tests and yours inverse. Pattern from PIC to FPGA 01010101 11001100 11110000 00111100 Pattern from FPGA to PIC 1111 1111 0000 0000 In all cases, except for [PIC 0xFF -> FPGA], errors occur. In case of [PIC 0x00 <-> 0x00 FPGA] Errors occur too. The cable has 10cm soldered direct in hosing for PIC chip. A picture is worth a thousand words. dl dot dropbox dot com/u/68170/DSC00273.JPG After all tests, I believe that FPGA is the problem. Yes, I tried use other 4 wires for connection in different pins of I/O Port of my DE2-70. Same error behavior. After this detailed description of my problems, if someone can give-me some light of problem, I'll thanks a lot So let's to the codes: PIC18F4550 first. Pic running using 3.3V of FPGA
char SPIMasterBruteForce(char data)
{
//Phase 1
//Polarity/Enable 0
# define DELAY_SPI Delay10KTCYx(240); // about 200-300 milliseconds
typedef volatile near union {
struct{
unsigned DT0:1;
unsigned DT1:1;
unsigned DT2:1;
unsigned DT3:1;
unsigned DT4:1;
unsigned DT5:1;
unsigned DT6:1;
unsigned DT7:1;
};
unsigned data;
} DATA;
DATA DATA_OUT;
DATA DATA_IN;
DATA_OUT.data = 0; // Clean for clean
DATA_IN.data = 0; //
DATA_OUT.data = data;
PORTAbits.RA5=1; // SS Inactive.
DELAY_SPI;
PORTDbits.RD1=1; // LED ON
// Not necessary clock cycle before transfer.
DELAY_SPI;
PORTBbits.RB1=1; // SCK
DELAY_SPI;
PORTBbits.RB1=0; // SCK
DELAY_SPI;
//
PORTBbits.RB1=0; // SCK (LOW)
PORTAbits.RA5=0; // SS Active (LOW);
DELAY_SPI;
DELAY_SPI;
DELAY_SPI;
// 7//////////////////////////////
PORTBbits.RB1=1; // SCK Propagate Bit
PORTCbits.RC7=DATA_OUT.DT7; // SDO
DELAY_SPI;
DATA_IN.DT7=PORTBbits.RB0; // SDI Capture Bit
PORTBbits.RB1=0; // SCK
DELAY_SPI;
// 6//////////////////////////////
PORTBbits.RB1=1; // SCK (HIGH)
PORTCbits.RC7=DATA_OUT.DT6; // SDO
DELAY_SPI;
DATA_IN.DT6=PORTBbits.RB0; // SDI
PORTBbits.RB1=0; // SCK (LOW)
DELAY_SPI;
// 5//////////////////////////////
PORTBbits.RB1=1; // SCK
PORTCbits.RC7=DATA_OUT.DT5; // SDO
DELAY_SPI;
DATA_IN.DT5=PORTBbits.RB0; // SDI
PORTBbits.RB1=0; // SCK
DELAY_SPI;
// 4//////////////////////////////
PORTBbits.RB1=1; // SCK
PORTCbits.RC7=DATA_OUT.DT4; // SDO
DELAY_SPI;
DATA_IN.DT4=PORTBbits.RB0; // SDI
PORTBbits.RB1=0; // SCK
DELAY_SPI;
// 3//////////////////////////////
PORTBbits.RB1=1; // SCK
PORTCbits.RC7=DATA_OUT.DT3; // SDO
DELAY_SPI;
DATA_IN.DT3=PORTBbits.RB0; // SDI
PORTBbits.RB1=0; // SCK
DELAY_SPI;
// 2//////////////////////////////
PORTBbits.RB1=1; // SCK
PORTCbits.RC7=DATA_OUT.DT2; // SDO
DELAY_SPI;
DATA_IN.DT2=PORTBbits.RB0; // SDI
PORTBbits.RB1=0; // SCK
DELAY_SPI;
// 1//////////////////////////////
PORTBbits.RB1=1; // SCK
PORTCbits.RC7=DATA_OUT.DT1; // SDO
DELAY_SPI;
DATA_IN.DT1=PORTBbits.RB0; // SDI
PORTBbits.RB1=0; // SCK
DELAY_SPI;
// 0 /////////////////////////////
PORTBbits.RB1=1; // SCK
PORTCbits.RC7=DATA_OUT.DT0; // SDO
DELAY_SPI;
DATA_IN.DT0=PORTBbits.RB0; // SDI
PORTBbits.RB1=0; // SCK
DELAY_SPI;
//////////////////////////////////
DELAY_SPI;
DELAY_SPI;
DELAY_SPI;
PORTAbits.RA5=1; // SS inactive (HIGH) ;
// Not necessary clock cycle after transfer.
DELAY_SPI;
PORTBbits.RB1=1;
DELAY_SPI;
PORTBbits.RB1=0;
DELAY_SPI;
PORTDbits.RD1=0; // LED OFF
return DATA_IN.data;
}
void SPIMasterMySPITest(void)
{
// Setup IO Pins in PIC
TRISCbits.TRISC0 = 0; //LED Green - Output
TRISDbits.TRISD1 = 0; //LED Yellow - Output
TRISDbits.TRISD0 = 0; //LED Red - Output
PORTCbits.RC0 = 0; // LED Green - OFF
PORTDbits.RD1 = 0; // LED Yellow- OFF
PORTDbits.RD0 = 0; // LED Red - OFF
TRISBbits.TRISB1 = 0; // SCK - Output
PORTBbits.RB1 = 0; // SCK - (LOW)
TRISBbits.TRISB0 = 1; // SDI - Input (MISO)
PORTBbits.RB0 = 0; // Not necessary - Force cleaning of bit register
TRISCbits.TRISC7 = 0; // SDO - Output (MOSI)
PORTCbits.RC7 = 0; // SDO - (LOW)
TRISAbits.TRISA5 = 0; // SS - Output
PORTAbits.RA5 = 1; // SS - (LOW)
while (1)
{
PORTDbits.RD1=1; // Yellow LED ON
Delay10KTCYx(240); // BIG Delay between transfers
SPIMasterBruteForce(0b10101010); // Sending the number 170 for test
PORTDbits.RD1=0; // Yellow LED ON
Delay10KTCYx(240); // BIG Delay between transfers
}
}
void main(void)
{
ADCON0 = 0x00; // ADC OFF
ADCON1 = 0x0F; // ALL I/O PINS DIGITAL
CMCON = 0x07; // COMPARATOR DISCONNECTED FROM PORT(A)
while (1)
{
SPIMasterMySPITest();
}
}
NOW FPGA CODE
void SPIPolling(void)
{
if (IORD_ALTERA_AVALON_SPI_STATUS(SPI_BASE) & ALTERA_AVALON_SPI_STATUS_RRDY_MSK )
{
printf(": %d \n", (char)IORD_ALTERA_AVALON_SPI_RXDATA(SPI_BASE));
}
if (IORD_ALTERA_AVALON_SPI_STATUS(SPI_BASE) & ALTERA_AVALON_SPI_STATUS_TRDY_MSK )
{
IOWR_ALTERA_AVALON_SPI_TXDATA(SPI_BASE, 0); //255 );
}
}
int main()
{
unsigned char count = 0;
unsigned int count2 = 25000;
printf("Hello from Nios II!\n");
while(1)
{
SPIPolling();
// Some lights to indicate that my NIOS is alive.
IOWR_ALTERA_AVALON_PIO_DATA(LED_BASE, count ) ;
count++;
if (count==255) count = 0;
while (count2) count2--;
if (!count2) count2 = 25000;
}
return 0;
}
Link Copied
2 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Are you sure that the clock on the FPGA's SPI interface isn't too fast for the PIC controller?
Try to put a signaltap probe on the SPI interface to see what the signals look like.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I notice, that are writing SDO and reading SDI after SCK rising edge, which correspondends to no usual SPI mode. I don't see, which SPI mode is implemented in the FPGA, but I guess that it doesn't match the master's behaviour, which would explain well the erratic result.
P.S.: If you intend SPI mode 0, you have to set SDO before the rising clock edge.
Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page