MT6260D SPI 的问题,求高手探讨

来源:互联网 发布:c语言中求最大公约数 编辑:程序博客网 时间:2024/05/21 13:19
BB搭载了一个指纹芯片,需要SPI通讯,看了下代码,SPI就提供了几个接口,具体怎么用看不透彻,按照自己的思路写了一个,发现写数据时连信号都没有,有木有人整过这方面的东西经验共享一下。

设计用的SPI 是UART2复用的,初始化的时候用spi_open(spi_port) 这个port是用0还是1.初始化除了open还spi_configure了一下,具体里面的参数代表什么至今还没去研究。初始化完成后就是读写数据了。两个接口spi_write  spi_read   。尝试发一个数据出去没什么反应,而且这两个函数里面
if (INT_QueryIsNonCachedRAM(pBuffer, length * count) != 1)是干什么的,这个使这个函数返回FALSE了。

感觉应该没多少东西,但是这几个接口说实在得用了后也感觉心里没底,用示波器量信号 CLK和MOSI MISO这些都没有。不知是哪里有问题,有经验的大大指导一下。


好长时间没上论坛,下面贴出结论,希望能帮到大家
原来的问题是发送数据时在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.

0 0