在线时间543 小时
UID1650185
注册时间2017-4-19
NXP金币573
TA的每日心情 | 怒 2021-1-28 20:09 |
---|
签到天数: 317 天 连续签到: 1 天 [LV.8]以坛为家I
金牌会员
 
- 积分
- 9264
- 最后登录
- 2022-5-12
|
本帖最后由 小马哥-1650185 于 2017-7-25 13:05 编辑
本帖就来说下基于rtt的音频库 最难修改的地方-------spi 驱动 sdcard,参考FAE 最新提供的demo,详谈修改过的地方
大概看了下,系统时钟是修改的关键,之前忽略了这个地方。
1.bsp/lpc5411x_audio/Libraries/lpc_chip/chip_5410x/clock_5411x.c
函数void Chip_Clock_EnablePeriphClock(CHIP_SYSCON_CLOCK_T clk)
修改为:
(ps:这里不修改也是可以正常的效果)
- void Chip_Clock_EnablePeriphClock(CHIP_SYSCON_CLOCK_T clk)
- {
- uint32_t clkEnab = (uint32_t) clk;
- if (clkEnab >= 128) {
- clkEnab = clkEnab - 128;
- LPC_ASYNC_SYSCON->ASYNCAPBCLKCTRLSET |= (1 << clkEnab);
- }
- else if (clkEnab >= 32) {
- LPC_SYSCON->AHBCLKCTRLSET[1] |= (1 << (clkEnab - 32));
- }
- else {
- LPC_SYSCON->AHBCLKCTRLSET[0] |= (1 << clkEnab);
- }
- }
复制代码 修改前后对比
2. bsp/lpc5411x_audio/Libraries/lpc_chip/chip_5410x/syscon_5411x.h
L311:
RESET_UTICK = 10, /*!< Micro Tick Timer */
修改为
RESET_UTICK = 32 + 10, /*!< Micro Tick Timer */
这里的修改非常关键,小马哥就是差这一句没改,导致整体不能工作,,,囧
3.bsp/lpc5411x_audio/drivers/drv_i2c.c
wm8904 iic gpio修改,这个前面帖子有改过的。SCL: I2C1_SCL PIO1_1
SDA: I2C1_SDA PIO1_2
- #define GPIO_PORT_I2C_SCL
- #define I2C_SCL_PORT <font color="#ff0000">1</font>
- #define I2C_SCL_PIN <font color="#ff0000"> 1</font>
- #define GPIO_PORT_I2C_SDA
- #define I2C_SDA_PORT <font color="#ff0000">1</font>
- #define I2C_SDA_PIN <font color="#ff0000"> 2</font>
复制代码
函数void rt_hw_i2c_init(void)中的iic 初始化也做下修改
- Chip_IOCON_PinMuxSet(LPC_IOCON, <font color="#ff0000">1, 1</font>, IOCON_FUNC5 | IOCON_DIGITAL_EN | IOCON_FASTI2C_EN);
- Chip_IOCON_PinMuxSet(LPC_IOCON,<font color="#ff0000"> 1, 2,</font> IOCON_FUNC5 | IOCON_DIGITAL_EN | IOCON_FASTI2C_EN);
复制代码
4.bsp/lpc5411x_audio/drivers/drv_i2s_wm8904.c
- static void codec_gpio_config(void) //GPIO_Configuration(void)
- {
- rt_kprintf("codec_gpio_config\r\n");
- Chip_IOCON_PinMuxSet(LPC_IOCON, 0, 5, IOCON_FUNC1 | IOCON_DIGITAL_EN); // Flexcomm 6 / SDA
- Chip_IOCON_PinMuxSet(LPC_IOCON, 0, 6, IOCON_FUNC1 | IOCON_DIGITAL_EN); // Flexcomm 6 / WS
- Chip_IOCON_PinMuxSet(LPC_IOCON, 0, 7, IOCON_FUNC1 | IOCON_DIGITAL_EN); // Flexcomm 6 / SCK
- Chip_IOCON_PinMuxSet(LPC_IOCON, 1, <font color="#ff0000">12</font>, IOCON_FUNC4 | IOCON_DIGITAL_EN); // Flexcomm 7 / SCK
- Chip_IOCON_PinMuxSet(LPC_IOCON, 1, <font color="#ff0000">13</font>, IOCON_FUNC4 | IOCON_DIGITAL_EN); // Flexcomm 7 / SDA
- Chip_IOCON_PinMuxSet(LPC_IOCON, 1, <font color="#ff0000">14</font>, IOCON_FUNC4 | IOCON_DIGITAL_EN); // Flexcomm 7 / WS
- }
复制代码
5.bsp/lpc5411x_audio/drivers/drv_spi.c
这里对比了下,fae的,发现我之前修改的是正确的。
FAE是这样修改的
- #define SPI1_FLEXCOMM 2 /* SPI1 associated with FLEXCOMM3 for Slave */
- #define SDCARD_SPI LPC_SPI1
- #define DMA_RX_CHANNEL DMA_CH4
- #define DMA_TX_CHANNEL DMA_CH5
复制代码
其实这麼做是不严谨的,描述容易误导人,因为sdcard 用到的是spi2,
SPI1用到的FLEXCOMM 是 3,fae直接把这个值该成了2. 这里同学们明白就行
我就说下我自己之前的修改思路吧
增加下面的宏
- #define SPI2_FLEXCOMM 2
- #define MY_SPI LPC_SPI2 //LPC_SPI1
- #define MY_DMA_CH_RX DMA_CH4 //DMA_CH6
- #define MY_DMA_CH_TX DMA_CH5 //DMA_CH7
复制代码
其中SPI2 Defines定义为
- /* SPI2 Defines */
- #define LPC_SPI2_BASE __APPEND3(LPC_FLEXCOMM,SPI2_FLEXCOMM,_BASE)
- #define LPC_SPI2 ((LPC_SPI_T *) LPC_SPI2_BASE)
- #define SPI2_IRQHandler __APPEND3(FLEXCOMM,SPI2_FLEXCOMM,_IRQHandler)
- #define SPI2_IRQn __APPEND3(FLEXCOMM,SPI2_FLEXCOMM,_IRQn)
- #define DMAREQ_SPI2_RX __APPEND3(DMAREQ_FLEXCOMM,SPI2_FLEXCOMM,_RX)
- #define DMAREQ_SPI2_TX __APPEND3(DMAREQ_FLEXCOMM,SPI2_FLEXCOMM,_TX)
复制代码
然后把文件中 的
LPC_SPI1 全部替换为MY_SPI
DMA_CH6全部替换为 MY_DMA_CH_RX
DMA_CH7全部替换为MY_DMA_CH_TX
还有FAE吧 #define SPI_USE_DMA 1 修改为了 #define SPI_USE_DMA 0 不太明白用意,不修改也没发现什么异常
然后就是spi 的gpio配置修改了
- /* Connect the SPI1 signals to port pins */
- Chip_IOCON_PinMuxSet(LPC_IOCON, 0, 10, (IOCON_FUNC1 | IOCON_MODE_PULLUP | IOCON_DIGITAL_EN)); /* SPI1_SCK */
- Chip_IOCON_PinMuxSet(LPC_IOCON, 0, 8, (IOCON_FUNC1 | IOCON_MODE_PULLUP | IOCON_DIGITAL_EN)); /* SPI1_MOSI */
- Chip_IOCON_PinMuxSet(LPC_IOCON, 0, 9, (IOCON_FUNC1 | IOCON_MODE_PULLUP | IOCON_DIGITAL_EN)); /* SPI1_MISO */
- Chip_IOCON_PinMuxSet(LPC_IOCON, 0, 3, (<font color="#ff0000">IOCON_FUNC0 </font>| IOCON_MODE_PULLUP | IOCON_DIGITAL_EN)); /* SPI1_SSEL0 */
-
- Chip_GPIO_SetPinDIROutput(LPC_GPIO, 0, 3);
- Chip_GPIO_SetPinState(LPC_GPIO, 0, 3, 1UL);
复制代码 cs引脚一定要配置为普通io口,下面所有的cs引脚都替换为P0_3
- if(message->cs_take)
- {
- Chip_GPIO_SetPinState(LPC_GPIO, 0, 3, 0UL);
- }
复制代码
- /* release CS */
- if(message->cs_release) {
- Chip_GPIO_SetPinState(LPC_GPIO, 0, 3, 1UL);
- }
复制代码- void rt_hw_spi_init(void)
- {
- static struct lpc54110_spi_bus lpc_spi;
- static struct lpc54110_spi_cs spi_cs;
- static struct rt_spi_device spi_device;
-
- spi_cs.GPIOx = LPC_GPIO;
- spi_cs.GPIO_Port = 0;
- spi_cs.GPIO_Pin = 3;
- lpc_spi_register(MY_SPI, &lpc_spi, "spi1");
- rt_spi_bus_attach_device(&spi_device, "spi10", "spi1", (void*)&spi_cs);
- }
复制代码
然后就修改结束了。。。测试MP3播放ok,具体测试见上个帖子。。。。
小结:
通过对比FAE修改的demo,发现除了第一条,和第二条外,别的都修改了,看来不同型号的cpu,时钟也是不同的。下面就来仔细看下手册 关于时钟修改的部分吧
第一条:其实不修改也是没问题的LPC_ASYNC_SYSCON->ASYNCAPBCLKCTRLSET |= (1 << clkEnab);
LPC_SYSCON->AHBCLKCTRLSET[1] |= (1 << (clkEnab - 32));
LPC_SYSCON->AHBCLKCTRLSET[0] |= (1 << clkEnab);
第二条,重点来看下这个是什么东东吧
PRESETCTRL1寄存器的BIT10 :
RESET_UTICK = 32+10, /*!< Micro Tick Timer */
原音频库为 RESET_UTICK = 10,bit位不对应。。。
PRESETCTRL0 和PRESETCTRL1 都是32位寄存器,RESET_UTICK 是PRESETCTRL1 的bit10,就需要加上PRESETCTRL0的偏移32,可能描述不太准确,大概就是这么个意思吧。
RESET_UTICK 错误的话,导致后面的 RESET_FLEXCOMM0, /*!< FlexComm 0 */
RESET_FLEXCOMM1, /*!< FlexComm 1 */
RESET_FLEXCOMM2, /*!< FlexComm 2 */
RESET_FLEXCOMM3, /*!< FlexComm 3 */
RESET_FLEXCOMM4, /*!< FlexComm 4 */
RESET_FLEXCOMM5, /*!< FlexComm 5 */
RESET_FLEXCOMM6, /*!< FlexComm 6 */
RESET_FLEXCOMM7, /*!< FlexComm 7 */
RESET_DMIC, /*!< Digital MIC */
全部错误,这也是spi2 配置异常的原因了
看下这两个寄存器就明白了
这里会产生一个蝴蝶效应,到时所有的FlexCOMM 初始化错误。
- /* Initialize FlexCOMM to a given peripheral */
- int Chip_FLEXCOMM_Init(LPC_FLEXCOMM_T *pFCOMM, FLEXCOMM_PERIPH_T periph)
- {
- int ret;
- int idx = Chip_FLEXCOMM_GetIndex(pFCOMM);
- if (idx < 0)
- return idx;
- /* Enable the peripheral clock */
- Chip_Clock_EnablePeriphClock((CHIP_SYSCON_CLOCK_T) (SYSCON_CLOCK_FLEXCOMM0 + idx));
- /* Reset FlexCOMM */
- Chip_SYSCON_PeriphReset((CHIP_SYSCON_PERIPH_RESET_T) (RESET_FLEXCOMM0 + idx));
- /* Set the FLEXCOMM to given peripheral */
- ret = Chip_FLEXCOMM_SetPeriph(pFCOMM, periph, 0);
- if (ret) {
- return ret;
- }
- /* By default enable wakeup from this peripheral */
- Chip_SYSCON_EnableWakeup((CHIP_SYSCON_WAKEUP_T) (SYSCON_STARTER_FLEXCOMM0 + idx));
- /* Set a default source for this flexcomm */
- Chip_Clock_SetFLEXCOMMClockSource(idx, SYSCON_FLEXCOMMCLKSELSRC_FRO12MHZ);
- return 0;
- }
复制代码
相关初始化部分全部错误
我们再来对比下syscon_5411x.h 和clock_5411x.h中的RESET_UTICK 和SYSCON_CLOCK_UTICK
看下图吧,
clock_5411x.h中的SYSCON_CLOCK_UTICK 是等于 32+10的
syscon_5411x.h 中的RESET_UTICK 是我们修改成的32+10的。。。
也许是这个音频库本身存在bug吧,或者原音频库mcu 的PRESETCTRL 寄存器和这个不一样吧
最后再来看下万利demo 关于这个的配置吧
到此修改分析完成,,,,不得不说我们的FAE真的好强大,佩服佩服啊,回头想一想,出问题的地方不在 之前想当然的移位sdcard-spi配置问你题,,,是这里的复位bit出了问题,引发了一连串的蝴蝶效应,,,,
|
|