Q2687 SPI Problem

I am trying to interface an ENC28J60 from MicroChip with
Q26 Developement Board.

The only thing I can read is 0x0 , and i believe that the board doesn’t generate
the Clock Signal .
I’ve heard that there is a bug in Open At , which makes the board act like this.

It is true ?
If someone has any ideea at lot i would be thankfull…

I’ve forgot … i use spi bus

Q2686/87 SPI bus is OK. I can play wave files from 2GB FAT16 SD card throught SPI 6.5Mb speed. You may check your SPI initialisation. You had better use a GPIO as CS. Also you need to setup proper SPI speed interfacing to ENC28J60.

From what i know about enc28j60 is needed to be setup at least 12 Mhz to work fine,
i set it up to 13 Mhz , maximum allowed by SPI Bus and all i can read is 0xFF and i don’t understand why…

Hi yuantuh,
I am Developing basic spi communication. I facing lots of problems . can u send me basic sample code for spi…
thanks
kiran

Have you looked at the samples included with the SDK :question:

Hi awneil,
i looked at sample code its designed for some external eeprom . Just i need basic spi to communicate with another microcontroller . just send data receive data …just spi configuration bus access read and write.if u have any basic sample code please copy to me.

thank you…
kiran

In what way does “basic SPI communication with another microcontroller” differ, essentially, from basic SPI communication with any slave device - such as a memory…?

That is pretty much what the SDK sample provides!

  • Configuration is there;
  • Bus writing is there - ie, sending data;
  • Bus reading is there - ie, receiving data.

You just mentioned the things you need right here :

if you look at the documentation you get the exact commands you need…
if you then look at the example code you can find the implementation of these commands.

hi , i studied basic example code but its not understandable form .tell what are basic thing i have to instillation for SPI communication.
i know something is it right …

  1. adl_busSPISettings_t (spi bus settings)
  2. adl_busSubscribe (bus subcribing)
    3.adl_busWrite
    4.ad_busRead
    apart from i have to any functions or setting are required.
    let me know plz.

hi just i want to know what are the basic functions i have to use in my programming for simple spi communication (q2686).

In what way is it “not understandable”?

Are you familiar with the basic operation of Open-AT applications in general - particularly their Event-Driven nature?
And how to effectively use the TRACE facilities?
If not, then you need to spend some time gaining that familiarity first.

Have you actually tried running the examples?
Even with no memory device connected, you should be able to observe the activity on the Q26 Clock, Chip-Select, and SPI output lines as it attempts to send commands to the (non-existant) chip - and reads should either give all-ones or all-zeros (depending on the state of the Q26 SPI input line).

You should be able to see the diagnostic TRACEs - and you can add further TRACEs of your own as you require.

Obviously, you will have to modify the points at which the code tries to wait for specific responses from the memory chip.

It might help you to also study the datasheet for the memory chip - that will show you what commands the chip is expecting from its master, and what responses it would give.

/*
 * spi_test.c
 *
 *  Created on: Sep 14, 2009
 *      Author: Kiran
 */

#include "adl_global.h"
#include "adl_bus.h"
adl_busAccess_t SpiBus_Access;
   // Bus access structure compute function
   void ComputeBusAccess ( u8 Opcode, u32 Address )
   {
          // Compute Bus Access structure from provided opcode & address
       u8 OpcodeMax = 32, AddressMax = 32;
       u8 OpcodeLength = 8, AddressLength = 16;

       // Set opcode
       SpiBus_Access.Opcode  = Opcode  << ( OpcodeMax - OpcodeLength );

       // Check if address is required
       if ( Address != 0xFFFF )
       {
           // Set address
           SpiBus_Access.Address = Address << ( AddressMax - AddressLength );
       }
       else
       {
           AddressLength = 0;
           SpiBus_Access.Address = 0;
       }
   }


const u16 wm_apmCustomStackSize = 1024;

// SPI Subscription data
adl_busSPISettings_t MySPIConfig =
   {
       5,                          // Clk_Speed    (2 MHz)
       ADL_BUS_SPI_CLK_MODE_0,     // Clk_Mode;
       ADL_BUS_SPI_ADDR_CS_GPIO,   // ChipSelect;
       ADL_BUS_SPI_CS_POL_LOW,     // ChipSelectPolarity;
       ADL_BUS_SPI_MSB_FIRST,      // LsbFirst;
       ADL_IO_GPIO | 35,           // GpioChipSelect;
       ADL_BUS_SPI_FRAME_HANDLING, // WriteHandling;
       ADL_BUS_SPI_DATA_UNIDIR,    // DataLinesConf;
       ADL_BUS_SPI_MASTER_MODE,
       ADL_BUS_SPI_BUSY_UNUSED
   };


// Write/Read buffer sizes
#define WRITE_SIZE 5
#define READ_SIZE 3


// BUS Handles
s32 MySPIHandle;
// Data buffers
u8 WriteBuffer [ WRITE_SIZE ], ReadBuffer [ READ_SIZE ];
// Somewhere in the application code, used as an event handler
void HelloWorld_TimerHandler ( u8 ID, void * Context )
{
	int a;
u32 AddSize=0;


adl_atSendResponse(ADL_AT_RSP, "\r\nmy function \r\n");
// Subscribe to the SPI1 BUS
[b]MySPIHandle = adl_busSubscribe ( ADL_BUS_ID_SPI, 1, &MySPIConfig );[/b]
TRACE((1,"MYSPIHANDLE %d",MySPIHandle));

// Configure the Address length to 0 (rewrite the default value)
adl_busIOCtl ( MySPIHandle, ADL_BUS_CMD_SET_ADD_SIZE, &AddSize );
// Write 5 bytes set to '0' on the SPI & I2C bus
//wm_memset ( WriteBuffer, WRITE_SIZE, 0 );
ComputeBusAccess(0x02,0xFFFF);
[b]a=adl_busWrite ( MySPIHandle, &SpiBus_Access, 3, "Emx" );[/b]
TRACE((1,"write %d",a));
// Read 3 bytes from the SPI & I2C bus
//adl_busRead ( MySPIHandle, &SpiBus_Access, READ_SIZE, ReadBuffer );
// Unsubscribe from subscribed BUS
adl_busUnsubscribe ( MySPIHandle );

}
void adl_main(adl_InitType_e adlInitType)
{
	adl_atSendResponse(ADL_AT_RSP, "\r\nMain Task\r\n");
	  /* Set 1s cyclic timer */
	    adl_tmrSubscribe ( TRUE, 10, ADL_TMR_100MS_MAX_VALUE, HelloWorld_TimerHandler );

}

the above code will work ?
what are main possible errors are there?
//
exp code:
i am using 3 wire mode (mosi ,miso,cs)Q2686 as master mode ,for every 100ms its sending data to slave device .
test result:
i checked with CRO its giving output at MOSI or at PIN NO 25.its giving fine wave forms.
if i connected to microcontrller its giving some garbage info…
what is the expected error in this code?
any help?..

I hope the above is a typo?
3 wire mode consists of SPI-CLK, SPI-IO and SPI-CS (GPIO 28, 29, 31 respectively for SPI-1).
you can’t leave out the Clock signal.

On the software side you need to:

  1. set up the bus properties
  2. subscribe to the bus-service

after that it depends on what your device expects from the spi-bus.
you might need to:

  1. set the op-code or the address
  2. read or write from the bus

As Madouc says, you cannot have SPI without the Clock signal!! :open_mouth:

You also need to ensure that both Master & Slave are using the same SPI Mode

Hi

One basic Doubt before initialization of SPI. Is it necessary to configure GPIO’s (sck-o/p,spi1-i as input,SPI1-i/o as Output )by using b[/b].
i am using 4 wire mode .
thanks and regards
kiran

Look at the sample!

I try to use the SPI for 3 or 4 days already and have read all your comments.

Yes, i looked at the samples and yes, i know the basics of AT-Programming, but i’ve still have a Problem.

I can write to the bus without Problems, but i can not read!

Here is my code. Please, tell my, what’s wrong?

#define SPI_SPEED  1
/**************************************************************/
void spiInit()
{
	s32 returncode ;
	u32 data ;

	adl_busSPISettings_t spiSettings = {
		SPI_SPEED ,
		ADL_BUS_SPI_CLK_MODE_3 ,
		ADL_BUS_SPI_ADDR_CS_GPIO ,
		ADL_BUS_SPI_CS_POL_LOW ,
		ADL_BUS_SPI_MSB_FIRST ,
		ADL_IO_GPIO | 31 ,
		ADL_BUS_SPI_LOAD_UNUSED,	// LoadSignal
		ADL_BUS_SPI_DATA_UNIDIR,		// DataLinesConf
		ADL_BUS_SPI_MASTER_MODE,	// MasterMode
		ADL_BUS_SPI_BUSY_UNUSED,	// BusySignal
	} ;

	TRACE((TL_SPEICHER,"spiInit()"));


	spiHandl = adl_busSubscribe(ADL_BUS_ID_SPI, 1, &spiSettings) ;

	TRACE((TL_SPEICHER, "adl_busSubscribe(SPI) : %d", spiHandl)) ;


     data = 8 ;
     returncode = adl_busIOCtl( spiHandl, ADL_BUS_CMD_SET_DATA_SIZE, &data) ;
     TRACE((TL_SPEICHER, "adl_busIOCtl( SPI, ADL_BUS_CMD_SET_DATA_SIZE, &data ) : %d", returncode )) ;
     data = 0 ;
     returncode = adl_busIOCtl( spiHandl, ADL_BUS_CMD_SET_ADD_SIZE, &data) ;
     TRACE((TL_SPEICHER, "adl_busIOCtl( SPI, ADL_BUS_CMD_SET_ADD_SIZE, &data ) : %d", returncode )) ;
     data = 0 ;
     returncode = adl_busIOCtl( spiHandl, ADL_BUS_CMD_SET_OP_SIZE, &data) ;
     TRACE((TL_SPEICHER, "adl_busIOCtl( SPI, ADL_BUS_CMD_SET_OP_SIZE, &data ) : %d", returncode )) ;

     TRACE((TL_SPEICHER, "spi_Init() complete")) ;
}
/**************************************************************/
void m25pSendSPI(charStream* sendData, charStream* reciveData)
{
	s32 returnwert;
	int i;

	adl_busAccess_t spiWriteMode = {0, 0} ;

	TRACE((TL_SPEICHER,"m25pSendSPI() %d",sendData->length));

	for(i=0;i<sendData->length;i++)
	{
		TRACE((TL_SPEICHER,"Data: %x",sendData->pChar[i]));
	}

	returnwert = adl_busWrite(spiHandl, &spiWriteMode, sendData->length, sendData->pChar) ;
	TRACE((TL_SPEICHER,"adl_busWrite: %d",returnwert));

	if(reciveData->length>0)
	{
	  returnwert=adl_busRead(spiHandl,&spiWriteMode,reciveData->length,reciveData->pChar);
	  TRACE((TL_SPEICHER,"adl_busRead: %d",returnwert));
	}
}
/**************************************************************/
bool  readExFlash( u32 udAddr, charStream *data)
{
    charStream sendStream;
    u8 pIns_Addr[5];

    // Step 1: Validate address input
    if(!(udAddr+data->length <  FLASH_SIZE))
    {
    	errorLog("Flash-Read-Instruction for wrong Address",udAddr);
    	return FALSE;
    }

    // Step 2: Initialize the data (i.e. Instruction) packet to be sent serially
    sendStream.length         = 5;
    sendStream.pChar          = pIns_Addr;
    pIns_Addr[0]              = SPI_FLASH_INS_READ;
    pIns_Addr[1]              = udAddr>>16;
    pIns_Addr[2]              = udAddr>>8;
    pIns_Addr[3]              = udAddr;
    pIns_Addr[4]              = SPI_FLASH_INS_DUMMY;

    // Step 3: Send the packet serially, and fill the buffer with the data being returned
    m25pSendSPI(&sendStream, data);

    return TRUE;
}
/**************************************************************/
void testFunction(void)
{
    charStream stream;
    stream.length=20;
    stream.pChar=adl_memGet(stream.length);

  //Initial SPI
   spiInit();

   stream.length=20;

   for(i=0;i<stream.length;i++)
   {
     stream.pChar[i]=0;
  }

   readExFlash(0x100,&stream);


   TRACE((1,"StreamerLenght: %d",stream.length));

   for(i=0;i<stream.length;i++)
   {
      TRACE((1,"Resived Data: %x",stream.pChar[i]));
   }
 
}

adl_busWrite without problems, adl_busRead doesn’t work

09/09/30,11:34:31:476 ADL 5 spiInit()
09/09/30,11:34:31:476 ADL 5 adl_busSubscribe(SPI) : 403456816
09/09/30,11:34:31:476 ADL 5 adl_busIOCtl( SPI, ADL_BUS_CMD_SET_DATA_SIZE, &data ) : 0
09/09/30,11:34:31:476 ADL 5 adl_busIOCtl( SPI, ADL_BUS_CMD_SET_ADD_SIZE, &data ) : 0
09/09/30,11:34:31:476 ADL 5 adl_busIOCtl( SPI, ADL_BUS_CMD_SET_OP_SIZE, &data ) : 0
09/09/30,11:34:31:476 ADL 5 spi_Init() complete
09/09/30,11:34:31:476 ADL 5 m25pSendSPI() 5
09/09/30,11:34:31:476 ADL 5 Data: 3
09/09/30,11:34:31:476 ADL 5 Data: 0
09/09/30,11:34:31:476 ADL 5 Data: 1
09/09/30,11:34:31:476 ADL 5 Data: 0
09/09/30,11:34:31:476 ADL 5 Data: aa
09/09/30,11:34:31:476 ADL 5 adl_busWrite: 0
09/09/30,11:34:31:476 ADL 5 adl_busRead: 0
09/09/30,11:34:31:476 ADL 1 StreamerLenght: 20
09/09/30,11:34:31:476 ADL 1 Resived Data: ff
09/09/30,11:34:31:585 ADL 1 Resived Data: ff
09/09/30,11:34:31:585 ADL 1 Resived Data: ff
09/09/30,11:34:31:585 ADL 1 Resived Data: ff
09/09/30,11:34:31:585 ADL 1 Resived Data: ff
09/09/30,11:34:31:585 ADL 1 Resived Data: ff
09/09/30,11:34:31:585 ADL 1 Resived Data: ff
09/09/30,11:34:31:585 ADL 1 Resived Data: ff
09/09/30,11:34:31:585 ADL 1 Resived Data: ff
09/09/30,11:34:31:585 ADL 1 Resived Data: ff
09/09/30,11:34:31:585 ADL 1 Resived Data: ff
09/09/30,11:34:31:585 ADL 1 Resived Data: ff
09/09/30,11:34:31:585 ADL 1 Resived Data: ff
09/09/30,11:34:31:585 ADL 1 Resived Data: ff
09/09/30,11:34:31:585 ADL 1 Resived Data: ff
09/09/30,11:34:31:585 ADL 1 Resived Data: ff
09/09/30,11:34:31:585 ADL 1 Resived Data: ff
09/09/30,11:34:31:585 ADL 1 Resived Data: ff
09/09/30,11:34:31:585 ADL 1 Resived Data: ff
09/09/30,11:34:31:585 ADL 1 Resived Data: ff

I always read 0xFF

With the KO, i messure the most bytes 0x00 and some others, but not 0xFF

I’m going to be crasy

obviously your SPI1-I (GPIO 30) is being held high.
are you sure your data is getting trough?

writing to the bus will always seem to go correct.
did you check the correct arrival of data on the slave side? (aka the component you’re trying to communicate with?