|
楼主 |
发表于 2013-12-19 14:26:19
|
显示全部楼层
好长时间没上论坛,下面贴出结论,希望能帮到大家
原来的问题是发送数据时在spi_write函数里的
#if defined(__MTK_TARGET__)
#if defined(SPI_MAUI_LOAD)
/* ensure non-cachable DMA address. */
{
if (INT_QueryIsNonCachedRAM(pBuffer, length * count) != 1)
{
//ASSERT(0);
return SPI_RESULT_INVALID_ARGUMENT;
}
}
#endif
#endif
这地方return掉了,导致这个地方return的原因是定义全局变量的buffer时需要这样写:
pragma arm section rwdata = "NONCACHEDRW", zidata = "NONCACHEDZI"
__align(4) kal_uint8 spi_src_buffer_all[512] = {0};
__align(4) kal_uint8 spi_dest_buffer_all[512] = {0};
#pragma arm section rwdata, zidata
#pragma 这两行一定要加上,好像是内存对齐的东西。__align(4) 也一定要加上。
下面贴出初始化和发送数据的代码
void Hld_spi_init(void)
{
SPI_RESULT spi_result = SPI_RESULT_OK;
SPI_CONFIG_PARAM_T attr;
SPI_MODE_T mode_parameter;
kal_uint32 hld_spi_id = 0;
spi_init();
hld_spi_handle = spi_open(HLD_SPI_PORT);
hld_spi_id = ((SPI_INTERNAL_HANDLE_T*)hld_spi_handle)->id;
if(KAL_FALSE == spi_reset(hld_spi_id))
{
dbg_print("\r\nspi_reset fail!\r\n");
}
spi_clear_fifo(hld_spi_id,SPI_TX);
spi_clear_fifo(hld_spi_id,SPI_RX);
dbg_print("\r\n\hld_spi_id = %d\r\n", hld_spi_id);
memset(&attr, 0, sizeof(SPI_CONFIG_PARAM_T));
//频率 clock
attr.cs_setup_time = 1;
attr.cs_hold_time = 1;
attr.clk_high_time = 0;
attr.clk_low_time = 0;
attr.cs_idle_time = 1;
attr.tx_msbf = SPI_MSBF_MSB;
attr.rx_msbf = SPI_MSBF_MSB;
attr.tx_endian = SPI_ENDIAN_LITTLE;
attr.rx_endian = SPI_ENDIAN_LITTLE;
attr.clk_polarity = SPI_CPOL_B0;
attr.clk_fmt = SPI_CPHA_B0;
spi_result = spi_configure(hld_spi_handle, &attr);
if (SPI_RESULT_OK != spi_result)
{
dbg_print("\r\n spi_configure fail\r\n");
return;
}
spi_set_endian_reverse(hld_spi_id,SPI_TX,KAL_FALSE);
spi_set_endian_reverse(hld_spi_id,SPI_RX,KAL_FALSE);
// disable SPI de-assert mode
mode_parameter.mode = SPI_MODE_DEASSERT;
mode_parameter.bEnable = KAL_FALSE;
spi_result = spi_ioctl(hld_spi_handle, SPI_IOCTL_SET_MODE, &mode_parameter);
if (SPI_RESULT_OK != spi_result)
{
dbg_print("\r\n spi_ioctl fail\r\n");
return;
}
//disable SPI pause mode
mode_parameter.mode = SPI_MODE_PAUSE;
mode_parameter.bEnable = KAL_FALSE;
spi_result = spi_ioctl(hld_spi_handle, SPI_IOCTL_SET_MODE, &mode_parameter);
if (SPI_RESULT_OK != spi_result)
{
dbg_print("\r\n spi_ioctl pause fail\r\n");
return;
}
}
void Hld_send_byte(kal_uint8 data)
{
SPI_RESULT result = SPI_RESULT_OK;
SPI_MODE_T mode_parameter;
//dbg_print("\r\n0xA002_0C20 = %x\r\n", DRV_Reg32(0xA0020C20));
mode_parameter.mode = SPI_MODE_DEASSERT;
mode_parameter.bEnable = KAL_TRUE;
result = spi_ioctl(hld_spi_handle, SPI_IOCTL_SET_MODE, &mode_parameter);
spi_src_buffer_all[0] = data;
result = spi_write(hld_spi_handle, spi_src_buffer_all, 1, 1, NULL);
if(result != SPI_RESULT_OK)
{
dbg_print("\r\nssp_send_byte fail");
}
mode_parameter.bEnable = KAL_FALSE;
result = spi_ioctl(hld_spi_handle, SPI_IOCTL_SET_MODE, &mode_parameter);
dbg_print("\r\nssp_send_byte:send %x,rec %x\r\n",spi_src_buffer_all[0],spi_dest_buffer_all[0]);
}
下面讲一下频率的设置,也就是init中
//频率 clock
attr.cs_setup_time = 1;
attr.cs_hold_time = 1;
attr.clk_high_time = 0;
attr.clk_low_time = 0;
attr.cs_idle_time = 1;
/*下面5个变量的含义请参见datasheet*/
kal_uint8 setup_time;//cs变低, clk等这么长时间, clk才起来.
kal_uint8 hold_time;//
/*下面2个变量是通过调节clk的low level和high level的时间来分频,从而修改SPI的clk*/
kal_uint8 clk_low; //<== clk的low level时间//
kal_uint8 clk_high; //<== clk的high level时间
kal_uint8 idle_time;
The chip select setup time = (CS_SETUP_COUNT+1) * CLK_PERIOD
The chip select hold time = (CS_HOLD_COUNT+1) * CLK_PERIOD.
The SCK clock low time = (SCK_LOW_COUNT+1) * CLK_PERIOD.
The SCK clock high time = (SCK_HIGH_COUNT+1) * CLK_PERIOD.
CLK_PERIOD = 1/65MHz.
|
|