This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

dm357 spi no clock output

I am using dm357' s SPI port to communicate with fpga.dm357 is master,i can write data to spidata1 register,but i cannot detect clock at th spi_clk pin.Also,when i config spi pins as gpio,i wrtie data to spi_clk(mux with gpio40) pin ,no signal out put,but other gpio work good.

anybody is using spi port on the dm357 or dm644x platform?

my program is as follows:

///////////////////////////

// INCLUDES

//////////////////////////

#include <linux/init.h>

#include <linux/module.h>

#include <linux/kernel.h>

#include <linux/delay.h> // udelay()

#include <linux/fs.h> // everything...

#include <asm/uaccess.h> // copy_from/to_user



// Definition for SPI Base Address and the local Power or Sleep Controller LPSoC

#include <asm/arch/hardware.h>

#include <asm/hardware/clock.h>



///////////////////////////

// PROTOTYPES

//////////////////////////

/* Declaration of dv_spi.c functions */

int dv_spi_open(struct inode *inode, struct file *filp);

int dv_spi_release(struct inode *inode, struct file *filp);

ssize_t dv_spi_read(struct file *filp, char *buf, size_t count, loff_t *f_pos);

ssize_t dv_spi_write(struct file *filp, const char *buf, size_t count,loff_t *f_pos);

static void dv_spi_exit(void);

static int dv_spi_init(void);



///////////////////////////

// DEFINITIONS & GLOBALS

//////////////////////////

// Register definitions to control the SPI

#define SPIGCR0 0x01c66800

#define SPIGCR1 0x01c66804

#define SPIINT 0x01c66808

#define SPILVL 0x01c6680c

#define SPIFLG 0x01C66810
// SPI Flag Status Register

#define SPIPC0 0x01C66814
// SPI Pin Control Register 0

#define SPIPC2 0x01C6681C
// SPI Pin Control Register 2

#define SPIDAT1 0x01C6683C
// SPI Shift Register 1

#define SPIBUF 0x01C66840
// SPI Buffer Register

#define SPIEMU 0x01C66844
// SPI Emulation Register

#define SPIDELAY 0x01C66848
// SPI Delay Register

#define SPIDEF 0x01C6684C
// SPI Default Chip Select Register

#define SPIFMT0 0x01C66850
// SPI Data Format Register 0

#define SPIFMT1 0x01C66854
// SPI Data Format Register 1

#define SPIFMT2 0x01C66858
// SPI Data Format Register 2

#define SPIFMT3 0x01C6685C
// SPI Data Format Register 3

#define INTVEC0 0x01C66860
// SPI Interrupt Vector Register 0

#define INTVEC1 0x01C66864
// SPI Interrupt Vector Register 1



// Definition for GPIO Pin Multiplexing

#define PINMUX1 0x01c40004



// SPI format - Polarity and Phase

// ***NOTE*** It doesn't seem like the SPI Phase for the davinci follows the standard

// phase as described by the motorola architecture. I.E. phase 0 = sample on rising edge of clock

// In the davinci it seems this is opposite.

#define SPI_PHASE 1
// Set these values to whatever you need

#define SPI_POLARITY 0



// Macro for accessing a memory location such as a register

#define SPI_REG(reg) (*(int *__iomem) IO_ADDRESS(reg))



// Version numbers

#define MAJOR_VERSION 60

#define MINOR_VERSION 01



// Global pointer to the clock struct. We use this to start up the LPSoC(local power system on chip)

// so our SPI peripheral has power going to it.

static struct clk *g_clkptr = 0;



// Structure that declares the usual file access functions

static struct file_operations dv_spi_fops = {

read: dv_spi_read,

write: dv_spi_write,

open: dv_spi_open,

release: dv_spi_release

};



// We will use a 1K read buffer to store data

static unsigned char *g_readbuf = 0;

static unsigned int g_readbufcount = 0;





static int dv_spi_init(void)

{

int result;



/* Registering device */

result = register_chrdev(MAJOR_VERSION, "spi",&dv_spi_fops);

if (result < 0)

{

printk("<1>dv_spi: cannot obtain major number %d\n", MAJOR_VERSION);

return result;

}



// Allocate space for the read buffer

g_readbuf = kmalloc(1024, GFP_KERNEL);

if (!g_readbuf)

{

result = -ENOMEM;

dv_spi_exit();

return result;

}



printk("<1>Inserting SPI module\n");

return 0;

}



static void dv_spi_exit(void)

{

/* Freeing the major number */

unregister_chrdev(MAJOR_VERSION, "spi");



/* Freeing buffer memory */

if(g_readbuf)

kfree(g_readbuf);



if (g_clkptr)

dv_spi_release(0,0);



printk("<1>Removing SPI module\n");

}





// Called when a userspace program opens the file

int dv_spi_open(struct inode *inode, struct file *filp)

{

unsigned int control;



// Power up the SPI hardware by requesting and enabling the
clock

g_clkptr = clk_get(NULL, "SPICLK");

if(g_clkptr <= 0) printk("<l>Error could not get the clock\n");

else clk_enable(g_clkptr);



// --------------------------------

// Configure GPIO Pins for SPI

// --------------------------------

// Enable the SPI pins on the GPIO

SPI_REG(PINMUX1) |= 0x100;



// --------------------------------

// Reset SPI

// --------------------------------

control=0x00000000;

SPI_REG(SPIGCR0)=control;
// Place SPI peripheral in reset

mdelay(1);
// Delay for a bit

control=0x00000001;

SPI_REG(SPIGCR0)=control;
// Remove from reset



// --------------------------------

// Enable SPI CLK & Master

// --------------------------------

control=0x00000003;

SPI_REG(SPIGCR1)=control;



// --------------------------------

// Enable pins : DI,DO,CLK,EN0

// --------------------------------

control=0x00000E01;

SPI_REG(SPIPC0)=control;



/* --------------------------------

// Set data format in SPIFMT0 - THIS CAN BE CHANGED BY IOCTL commands

// SHIFTDIR in bit 20 set to 1 : MSB first

// POLARITY and PHASE in bit 17, 16 set to 0, 0

// PRESCALE in bit 15-8 set to whatever you need, SPI_CLK =SYSCLK5 / (Prescale + 1)

// CHARLEN in bit 4-0 set to 08 : 8 bit characters

-------------------------------- */

control=0x00000000 | (SPI_POLARITY << 17) | (SPI_PHASE <<16) | (0x7 << 8) | 0x8;

SPI_REG(SPIFMT0)=control;



// --------------------------------

// Set data format for used -> SPIFMT0

// --------------------------------

control=0x00000000 | (0x00 << 24);

SPI_REG(SPIDAT1)=control;





// --------------------------------

// Set hold time and setup time

// --------------------------------

control=0x00000000 | (0x03 << 16) | (0x06 << 24);

SPI_REG(SPIDELAY)=control;





// --------------------------------

// Set Chip Select Default

// CSHOLD -> 0 -> release SPI_EN0 state after transmission-> bit 28

// CSNR -> 2 -> Only use SPI_EN0

// --------------------------------

control=SPI_REG(SPIDAT1);

control|= (0x2 << 16);

SPI_REG(SPIDAT1)=control;



// --------------------------------

// Enable for transmitting

// --------------------------------

control=SPI_REG(SPIGCR1);

control=control | 1 << 24; // enable SPIENA

SPI_REG(SPIGCR1)=control;



// Zero out our read buffer

memset(g_readbuf, 0, 1024);

g_readbufcount = 0;



return 0;

}





// Called when a userspace program closes the file

int dv_spi_release(struct inode *inode, struct file *filp)

{

// Place SPI peripheral into reset

SPI_REG(SPIGCR0)=0;



// Remove the SPI output on the GPIO

SPI_REG(PINMUX1) &= ~0x100;



// Disable the clock thus removing power from the peripheral

if(g_clkptr)

clk_disable(g_clkptr);

g_clkptr = 0;



return 0;

}





// Reading from the SPI device

ssize_t dv_spi_read(struct file *filp, char *buf, size_t count, loff_t *f_pos)

{

// printk("<1>Attempting to read %d bytes and we only have %d bytes\n",count,g_readbufcount);



if(g_readbufcount == 0) return 0; // No data





// See if there is enough available

if(count > g_readbufcount) count = g_readbufcount;



// Transferring data to user space

copy_to_user(buf,g_readbuf,count);



// Now shift the memory down


memmove(&g_readbuf[0],&g_readbuf[count],g_readbufcount-count);

g_readbufcount -= count;



// Advance the file pointer

*f_pos += count;

return count;

}



// Writing to the SPI device

ssize_t dv_spi_write(struct file *filp, const char *buf, size_t count,loff_t *f_pos)

{

unsigned char spiData;

size_t i;

unsigned int control;

unsigned int ReadByte;



// Wait until the TX buffer is clear

control = SPI_REG(SPIBUF);

while(control & (1 << 29)) //Wait until the TX data has been transmitted

control = SPI_REG(SPIBUF);



// Write out data one byte at a time

for(i=0; i < count; i++)

{

ReadByte = 0;

// Send the data

copy_from_user(&spiData,buf+i,1);



control = 0x00000000 | (0x1 << 28) | (0x2 <<16) | spiData; // Hold the chip select line between multibytes

SPI_REG(SPIDAT1) = control;

if(i == (count -1))

SPI_REG(SPIDAT1) =0x00000000 | (0x2 << 16) | spiData; // Remove the chip select hold





control = SPI_REG(SPIBUF);

while(control & (1 << 29))
// Wait until the TX data has been transmitted

{

// Check for data received

if(!(control & (1 << 31)))

{

// We have
just read a byte of data, store it.


if(g_readbufcount < 1024)

{

//
printk("<1>Read in byte value = %d!\n",count);


g_readbuf[g_readbufcount] = control & 0xFF;


g_readbufcount++;


ReadByte = 1;

}

}

control = SPI_REG(SPIBUF);

}



// Make sure we have always read in a byte

while(!ReadByte)

{

// Check for data received

if(!(control & (1 << 31)))

{

//
printk("<1>we received a byte with value %d\n",control & 0xFF);

// We have
just read a byte of data, store it.


if(g_readbufcount < 1024)

{

//
printk("<1>Read in byte value = %d\n",control);


g_readbuf[g_readbufcount] = control & 0xFF;


g_readbufcount++;


ReadByte = 1;

}

}

control = SPI_REG(SPIBUF);

}

}



return count;

}





MODULE_LICENSE("Dual BSD/GPL");

module_init(dv_spi_init);

module_exit(dv_spi_exit);