工具/软件:Linux
我们在 SPI 总线上有三个器件。 主器件是 OMAP/ARM 处理器、以2MHz 的频率驱动时钟(这已通过示波器进行验证)。 两个从器件位于 OMAP 的芯片选择2和3上。 正在成功发送和接收数据。 问题是、我们接收数据的速率比它应该慢一个数量级。 我们不是以3584Hz (理想频率)读取数据、而是以177Hz 的频率读取数据。 当我们不发送/接收数据时、我已验证轮询环路本身以3584Hz 的频率运行。 当我打开函数从器件中读取数据时、每个器件需要~5.7毫秒的时间来轮询和接收完整的数据流。 请求数据大小为32字节、任一器件的最大响应大小为32字节。 因此、总往返轮询/响应为64字节或512位。
我们不使用 DMA 的部分原因是有关如何使用 DMA 的文档太差。 如果存在阻塞条件、如本例所示、使用 SPI 读取数据、这可能是一种解决方案。
对问题可能有什么想法?
谢谢、
Erik Jones
支持信息:
--------------------------------------------
处理器:SOMOMAPL138-10-1602QHIR-B
编译器包:CodeSourcery Sourcery G++ Lite 4.3.3版(Sourcery G++ Lite 2009q1-203)
RootFS:Arago
SPI 应用代码:
bool SPIController::sendData (spiDevices spiDevice、SPIRequestBase *命令){
int spiDev = open (spiDeviceTable[spiDevice].deviceName.c_str()、O_RDWR);
INT MODE = SPI_MODE_0;
int res = 0;
struct spi_io_transfer spiControl;
memset (&spiControl、0、sizeof (spiControl));
setCS (spiDevice、true);
char * xmitBuffer = new char [spiDeviceTable[spiDevice].max_packet_length];
memset (xmitBuffer、0、spiDeviceTable[spiDevice].max_packet_length);
memcpy (xmitBuffer、Command->getPacketbuffer ()、spiDeviceTable[spiDevice].max_packet_length);
char * recvBuffer = new char [spiDeviceTable[spiDevice].max_packet_length];
memset (recvBuffer、0、spiDeviceTable[spiDevice].max_packet_length);
RES = ioctl (spiDev、SPI_IOC_WR_MODE、&MODE);
spiControl.TX_Buf =(无符号长整型) xmitBuffer;
spiControl.Rx_Buf =(无符号长整型) recvBuffer;
spiControl.len = spiDeviceTable[spiDevice].max_packet_length;
spiControl.speed_Hz = SPIController:spiClock;
spiControl.cs_change = 0;
spiControl.bits_per_word = 8;
spiControl.delay_usecs = 0;
if (spiDevice = PIM_datalogger)
xmitBuffer[spiDeviceTable[spiDevice].max_packet_length-1]= 0xAA;
RES = ioctl (spiDev、SPI_IOC_MESSAGE (1)、&spiControl);
//临时检测
if (spiDevice =PIM_platform &&*(recvBuffer + spiDeviceTable[spiDevice].max_packet_length - 1)=0){
memMove (recvBuffer+1、recvBuffer、spiDeviceTable[spiDevice].max_packet_length-1);
*recvBuffer=0;
//Sign extension
if ((*(recvBuffer+1)& 0x80)>0)
* recvBuffer = 0xFF;
}
SPIResponseBase * pr = SPIResponseBase::Dispatch (recvBuffer、spiDevice、spiDeviceTable[spiDevice].max_packet_length);
SPIController::当前遥测.U16_DatLog_ActiveFile_Index_HB = DataLogController::getFileNum()>> 16;
SPIController::当前遥测.U16_DatLog_ActiveFile_Index_LB = DataLogController:getFileNum()& 0xFF;
SPIController::currentTelemety.u8_ConfigFile_ID = NetworkServerController::getConfigFileID();
SPIController::currentTelemety.u8_mode = NetworkServerController::getCurrentMode();
SPIController::currentTelemetice.u32_counter++;
SPIController::currentTelemetry =*pr;
Close (spidDev);
setCS (spiDevice、false);
删除[] xmitBuffer;
删除[] recvBuffer;
删除 pr;
返回 true;
}
bool SPIController::setCS (spiDevices spiDevice、bool enable){
std::字符串 devicePin、enableStr;
enableStr =启用? "0":"1";
switch (spiDevice){
案例 PIM_PLANTANT:
devicePin = SPIController:SPI_CS2;
中断;
案例 PIM_DATALOGGER:
devicePin = SPI 控制器::SPI_CS3;
中断;
}
std::string setval_str ="/sys/class/gpio/gpio + devicePin +"/value";
ofstream setvalgpio (setval_str.c_str ());//打开 GPIO 的值文件
if (setvalgpio < 0){
COUT <<"操作失败:无法设置 GPIO"<<devicePin <<"."<endl;
返回 false;
}
setvalgpio << enableStr;//write value to value file
setvalgpio.close();//关闭值文件
返回 true;
}
内核:来自 ti-dvsdk-omap138-EVM 4.02.0.6 - 2.6.33-RC4-psp03.2.0.14
芯片选择2和3上的 SPI 器件。 通过硬编码 SPI 驱动器修改将时钟设置为2MHz。 在 mach-Davinci/board-da850-EVM.c 中:
静态结构 SPI_board_info da850_SPI_board_info[]={
[0]={
modalias ="m25p80"、
.platform_data =&spi_flash_data、
.mode = SPI_MODE_0、
.max_speed_Hz = 2000000、/* 3V 时的最大采样率*
.bus_num = 1、
.chip_select = 0、
}、
/*可编程隔离安装*/
[1]={
modalias ="spidev"、
.mode = SPI_MODE_0、
.max_speed_Hz = 2000000、/* 3V 时的最大采样率*
.bus_num = 1、
.chip_select = 2、
}、
[2]={
modalias ="spidev"、
.mode = SPI_MODE_0、
.max_speed_Hz = 2000000、/* 3V 时的最大采样率*
.bus_num = 1、
.chip_select = 3、
}、
};