airwill 发表于 2014-12-1 07:55
如果是外部连接 SPIMOSI和SPIMISO 进行程序自测spi功能, 肯定是没有问题的.
不过没有看到软件的内部连接的 ...
现在arm外部连接 SPIMOSI和SPIMISO 进行程序自测spi成功,dsp的spi内部连接程序自测spi成功。现在有两个问题:1、我看资料理解spi通信clock polarity=0,clock phase=0时,则在主机clk上升沿时,主机SPIDAT发送数据,从机SPIDAT发送数据,在主机clk下降沿时,主机SPIDAT锁存从机发送数据(SPIMISO引脚上电平),从机SPIDAT锁存主机发送数据(SPIMOSI引脚电平),自测时,将SPIMISO和SPIMOSI连接,主机和从机发送内容不同时,而SPIMISO和SPIMOSI又是一根线,不是矛盾吗?
2、我现在的arm和dsp的spi通信,能通上,但是收到的数据不对,不知道是什么原因。程序贴上,您指点一下,谢谢!(arm收到的rx 一直为0,arm的tx为2时,dsp收4)
arm程序:
/*
* SPI testing utility (using spidev driver)
*
* Copyright (c) 2007 MontaVista Software, Inc.
* Copyright (c) 2007 Anton Vorontsov <avorontsov@ru.mvista.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License.
*
* Cross-compile with cross-gcc -I/path/to/cross-kernel/include
*/
#include <stdint.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/types.h>
#include <linux/spi/spidev.h>
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
static void pabort(const char *s)
{
perror(s);
abort();
}
static const char *device = "/dev/spidev1.0";
static uint8_t mode=0;
static uint8_t bits = 8;
static uint32_t speed =500000;
static uint16_t delay=0;
static void transfer(int fd)
{
int ret;
uint8_t tx[1]={2};
uint8_t rx[1]={5};
struct spi_ioc_transfer tr = {
.tx_buf = (unsigned long)tx,
.rx_buf = (unsigned long)rx,
.len = ARRAY_SIZE(tx),
.delay_usecs = delay,
.speed_hz = speed,
.bits_per_word = bits,
};
ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);
if (ret < 1)
pabort("can't send spi message");
printf("%.2X ", rx[0]);
puts("");
}
static void print_usage(const char *prog)
{
printf("Usage: %s [-DsbdlHOLC3]\n", prog);
puts(" -D --device device to use (default /dev/spidev1.0)\n"
" -s --speed max speed (Hz)\n"
" -d --delay delay (usec)\n"
" -b --bpw bits per word \n"
" -l --loop loopback\n"
" -H --cpha clock phase\n"
" -O --cpol clock polarity\n"
" -L --lsb least significant bit first\n"
" -C --cs-high chip select active high\n"
" -3 --3wire SI/SO signals shared\n");
exit(1);
}
static void parse_opts(int argc, char *argv[])
{
while (1) {
static const struct option lopts[] = {
{ "device", 1, 0, 'D' },
{ "speed", 1, 0, 's' },
{ "delay", 1, 0, 'd' },
{ "bpw", 1, 0, 'b' },
{ "loop", 0, 0, 'l' },
{ "cpha", 0, 0, 'H' },
{ "cpol", 0, 0, 'O' },
{ "lsb", 0, 0, 'L' },
{ "cs-high", 0, 0, 'C' },
{ "3wire", 0, 0, '3' },
{ "no-cs", 0, 0, 'N' },
{ "ready", 0, 0, 'R' },
{ NULL, 0, 0, 0 },
};
int c;
c = getopt_long(argc, argv, "D:s:d:b:lHOLC3NR", lopts, NULL);
if (c == -1)
break;
switch (c) {
case 'D':
device = optarg;
break;
case 's':
speed = atoi(optarg);
break;
case 'd':
delay = atoi(optarg);
break;
case 'b':
bits = atoi(optarg);
break;
case 'l':
mode |= SPI_LOOP;
break;
case 'H':
mode |= SPI_CPHA;
break;
case 'O':
mode |= SPI_CPOL;
break;
case 'L':
mode |= SPI_LSB_FIRST;
break;
case 'C':
mode |= SPI_CS_HIGH;
break;
case '3':
mode |= SPI_3WIRE;
break;
case 'N':
mode |= SPI_NO_CS;
break;
case 'R':
mode |= SPI_READY;
break;
default:
print_usage(argv[0]);
break;
}
}
}
int main(int argc, char *argv[])
{
int ret = 0;
int fd;
parse_opts(argc, argv);
fd = open(device, O_RDWR);
if (fd < 0)
pabort("can't open device");
/*
* spi mode
*/
ret = ioctl(fd, SPI_IOC_WR_MODE, &mode);
if (ret == -1)
pabort("can't set spi mode");
ret = ioctl(fd, SPI_IOC_RD_MODE, &mode);
if (ret == -1)
pabort("can't get spi mode");
/*
* bits per word
*/
ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits);
if (ret == -1)
pabort("can't set bits per word");
ret = ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits);
if (ret == -1)
pabort("can't get bits per word");
/*
* max speed hz
*/
ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);
if (ret == -1)
pabort("can't set max speed hz");
ret = ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed);
if (ret == -1)
pabort("can't get max speed hz");
printf("spi mode: %d\n", mode);
printf("bits per word: %d\n", bits);
printf("max speed: %d Hz (%d KHz)\n", speed, speed/1000);
while(1){
transfer(fd);
}
close(fd);
return ret;
}
dsp程序:
DSP28_sysCtrl.c
#include "DSP28_Device.h"
//---------------------------------------------------------------------------
// InitSysCtrl:
//---------------------------------------------------------------------------
// This function initializes the System Control registers to a known state.
//
void InitSysCtrl(void)
{
Uint16 i;
EALLOW;
// On TMX samples, to get the best performance of on chip RAM blocks M0/M1/L0/L1/H0 internal
// control registers bit have to be enabled. The bits are in Device emulation registers.
DevEmuRegs.M0RAMDFT = 0x0300;
DevEmuRegs.M1RAMDFT = 0x0300;
DevEmuRegs.L0RAMDFT = 0x0300;
DevEmuRegs.L1RAMDFT = 0x0300;
DevEmuRegs.H0RAMDFT = 0x0300;
// Disable watchdog module
SysCtrlRegs.WDCR= 0x0068;
// Initalize PLL
SysCtrlRegs.PLLCR = 0x06;
// Wait for PLL to lock
for(i= 0; i< 5000; i++){}
// HISPCP/LOSPCP prescale register settings, normally it will be set to default values
SysCtrlRegs.HISPCP.all = 0x0001;
SysCtrlRegs.LOSPCP.all = 0x0002;
// Peripheral clock enables set for the selected peripherals.
SysCtrlRegs.PCLKCR.bit.EVAENCLK=1;
SysCtrlRegs.PCLKCR.bit.EVBENCLK=1;
SysCtrlRegs.PCLKCR.bit.SCIENCLKA=1;
// SysCtrlRegs.PCLKCR.bit.SCIENCLKB=1;
SysCtrlRegs.PCLKCR.bit.SPIENCLK=1;//spi模块时钟使能
EDIS;
}
DSP28_spi.c
void InitSpi(void)
{
// Initialize SPI-A:
// Initialize SCI-A:
EALLOW;
GpioMuxRegs.GPFMUX.all = 0x000f;
EDIS;
/* loopback0x1f 8 bit data */
SpiaRegs.SPICCR.all = 0x07;
SpiaRegs.SPICTL.all = 0x02;//0x07
//SpiaRegs.SPIBRR = 0x7f;
SpiaRegs.SPICCR.all = 0x87;//0x9f
//PieCtrl.PIEIER6.bit.INTx1 = 1;
// PieCtrl.PIEIER6.bit.INTx2 = 1;
//tbd...
//tbd...
}
unsigned int Spi_TxReady(void)
{
unsigned int i;
if(SpiaRegs.SPISTS.bit.BUFFULL_FLAG == 1)
{
i = 0;
}
else
{
i = 1;
}
return(i);
}
unsigned int Spi_RxReady(void)
{
unsigned int i;
if(SpiaRegs.SPISTS.bit.INT_FLAG == 1)
{
i = 1;
}
else
{
i = 0;
}
return(i);
}
interrupt void SPIRXINTA_ISR(void); // SPI
interrupt void SPITXINTA_ISR(void); // SPI
主程序:
#include "DSP28_Device.h"
unsigned int Spi_VarRx[100];
unsigned int i,j;
//interrupt void ISRSciaTx(void);
//interrupt void ISRSciaRx(void);
void main(void)
{
/*初始化系统*/
InitSysCtrl();
/* 关中断 */
DINT;
IER = 0x0000;
IFR = 0x0000;
/* 初始化PIE控制寄存器 */
InitPieCtrl();
/* 初始化PIE参数表 */
InitPieVectTable();
/* 初始化外设寄存器 */
InitPeripherals();
// init_spi();
for(i = 0; i < 100; i++)
{
Spi_VarRx = 0;
}
i = 0;
j = 0;
#if Spi_Int
EALLOW; // This is needed to write to EALLOW protected registers
PieVectTable.SPITXINTA = &SPITXINTA_ISR;
PieVectTable.SPIRXINTA = &SPIRXINTA_ISR;
EDIS; // This is needed to disable write to EALLOW protected registers
/* 设置IER寄存器 */
IER |= M_INT6;
#endif
/* 开中断 */
EINT; // Enable Global interrupt INTM
ERTM; // Enable Global realtime interrupt DBGM
for(;;)
{
if(Spi_TxReady() == 1)//发送寄存器空
{
SpiaRegs.SPITXBUF = i;
i++;
if(i == 100)
{
i = 0;
}
}
#if !Spi_Int
if(Spi_RxReady() == 1)//接收寄存器接到了
{
Spi_VarRx[j] = SpiaRegs.SPIRXBUF&0x00FF;
j++;
if(j == 100)
{
j = 0;
}
}
#endif
}
} |