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.

TMS320c6670 SPI片选信号始终为低电平



Hi all,

我最近在写6670的SPI驱动。6670 SPI总线上挂了两片flash,一片是直接接到DSP上,另外一片通过CPLD接到DSP上。问题出现在后一个flash上:

我在初始化SPI时,将cs端的默认状态设置为没有数据传输时cs端为高电平。但是程序一跑完这条语句,cs就始终处于低电平状态,回不到高电平。由于向flash写指令

时,必须要cs回到高电平才能将指令写进去,所以现在没法控制flash的读写。请问这是怎么回事?

Thx

Nick

  • 一般来说,cs片选信号是从高拉低表示选中slave device,一直到所有信息发送/接收完毕后再次拉高表示释放slave device。在配置好寄存器之后,enable SPI模块就可以让片选信号变化,并向slave device写指令和数据。没法控制flash的读写还有可能是时序等其它问题,不一定是cs的问题。下面是SPI初始化配置寄存器的代码参考:

    /* SPI soft reset procedure. */

       SPI_SPIGCR0 = CSL_SPI_SPIGCR0_RESET_IN_RESET;

       spi_delay (2000);

       SPI_SPIGCR0 = CSL_SPI_SPIGCR0_RESET_OUT_OF_RESET;

       /* Set master mode, powered up but not activated */

       SPI_SPIGCR1 =   (CSL_SPI_SPIGCR1_MASTER_MASTER << CSL_SPI_SPIGCR1_MASTER_SHIFT)   |

                       (CSL_SPI_SPIGCR1_CLKMOD_INTERNAL << CSL_SPI_SPIGCR1_CLKMOD_SHIFT);

       /* Set functional pins by the value of cs. */

       if (cs == 0) {

           SPI_SPIPC0 =    (CSL_SPI_SPIPC0_SCS0FUN0_SPI << CSL_SPI_SPIPC0_SCS0FUN0_SHIFT) |

                           (CSL_SPI_SPIPC0_CLKFUN_SPI << CSL_SPI_SPIPC0_CLKFUN_SHIFT)     |

                           (CSL_SPI_SPIPC0_SIMOFUN_SPI << CSL_SPI_SPIPC0_SIMOFUN_SHIFT)   |

                           (CSL_SPI_SPIPC0_SOMIFUN_SPI << CSL_SPI_SPIPC0_SOMIFUN_SHIFT);

       } else if (cs == 1) {

           SPI_SPIPC0 =    (CSL_SPI_SPIPC0_SCS0FUN1_SPI << CSL_SPI_SPIPC0_SCS0FUN1_SHIFT) |

                           (CSL_SPI_SPIPC0_CLKFUN_SPI << CSL_SPI_SPIPC0_CLKFUN_SHIFT)     |

                           (CSL_SPI_SPIPC0_SIMOFUN_SPI << CSL_SPI_SPIPC0_SIMOFUN_SHIFT)   |

                           (CSL_SPI_SPIPC0_SOMIFUN_SPI << CSL_SPI_SPIPC0_SOMIFUN_SHIFT);

       }

       /* Setup format. Format should be the same except CHAR length. */

       scalar = ((SPI_MODULE_CLK / freq) - 1 ) & 0xFF; //There's a calc bug here. Just set freq to 1000000.

       if ( bit_sel == 0) {

           SPI_SPIFMT0 =   (8 << CSL_SPI_SPIFMT_CHARLEN_SHIFT)               |

                           (scalar << CSL_SPI_SPIFMT_PRESCALE_SHIFT)                      |

                           (CSL_SPI_SPIFMT_PHASE_NO_DELAY << CSL_SPI_SPIFMT_PHASE_SHIFT)     |

                           (CSL_SPI_SPIFMT_POLARITY_LOW << CSL_SPI_SPIFMT_POLARITY_SHIFT) |

                           (CSL_SPI_SPIFMT_SHIFTDIR_MSB << CSL_SPI_SPIFMT_SHIFTDIR_SHIFT);

       }else if ( bit_sel == 1) {

           SPI_SPIFMT0 =   (16 << CSL_SPI_SPIFMT_CHARLEN_SHIFT)               |

                           (scalar << CSL_SPI_SPIFMT_PRESCALE_SHIFT)                      |

                           (CSL_SPI_SPIFMT_PHASE_NO_DELAY << CSL_SPI_SPIFMT_PHASE_SHIFT)     |

                           (CSL_SPI_SPIFMT_POLARITY_LOW << CSL_SPI_SPIFMT_POLARITY_SHIFT) |

                           (CSL_SPI_SPIFMT_SHIFTDIR_MSB << CSL_SPI_SPIFMT_SHIFTDIR_SHIFT);

       }

       /* hold cs active at end of transfer until explicitly de-asserted */

       data1_reg_val = (CSL_SPI_SPIDAT1_CSHOLD_ENABLE << CSL_SPI_SPIDAT1_CSHOLD_SHIFT) |

                       (0x02 << CSL_SPI_SPIDAT1_CSNR_SHIFT);

       SPI_SPIDAT1 =   (CSL_SPI_SPIDAT1_CSHOLD_ENABLE << CSL_SPI_SPIDAT1_CSHOLD_SHIFT) |

                       (0x02 << CSL_SPI_SPIDAT1_CSNR_SHIFT);

       /* including a minor delay. No science here. Should be good even with no delay. */

       SPI_SPIDELAY =  (8 << CSL_SPI_SPIDELAY_C2TDELAY_SHIFT) |

                       (8 << CSL_SPI_SPIDELAY_T2CDELAY_SHIFT);

       /* default chip select register */

       SPI_SPIDEF  = CSL_SPI_SPIDEF_RESETVAL;

       /* no interrupts */

       SPI_SPIINT0 = CSL_SPI_SPIINT0_RESETVAL;

       SPI_SPILVL  = CSL_SPI_SPILVL_RESETVAL;

       /* enable SPI */

       SPI_SPIGCR1 |= ( CSL_SPI_SPIGCR1_ENABLE_ENABLE << CSL_SPI_SPIGCR1_ENABLE_SHIFT );