1.GPIO的初始化
void spi_flash_gpio_init(void)
{
spi_parameter_struct spi_init_struct;
rcu_periph_clock_enable(RCU_GPIOA);
rcu_periph_clock_enable(RCU_GPIOB);
rcu_periph_clock_enable(RCU_SPI0);
/* SPI0_CLK(PA11), SPI0_MISO_IO1(PA10), SPI0_MOSI_IO0(PA9),SPI0_IO2(PB3) and SPI0_IO3(PB4) GPIO pin configuration */
gpio_af_set(GPIOA, GPIO_AF_0, GPIO_PIN_9 | GPIO_PIN_10 |GPIO_PIN_11);
gpio_af_set(GPIOB, GPIO_AF_6, GPIO_PIN_3 | GPIO_PIN_4);
gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_9 | GPIO_PIN_10 |GPIO_PIN_11);
gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_166MHZ, GPIO_PIN_9 | GPIO_PIN_10 |GPIO_PIN_11);
gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_3 | GPIO_PIN_4);
gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_166MHZ, GPIO_PIN_3 | GPIO_PIN_4);
/* SPI0_CS(PA12) GPIO pin configuration */
gpio_mode_set(GPIOA, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_12);
gpio_output_options_set(GPIOA , GPIO_OTYPE_PP,GPIO_OSPEED_166MHZ , GPIO_PIN_12);
//gpio_bit_set(GPIOA, GPIO_PIN_12);
/* chip select invalid */
SPI_FLASH_CS_HIGH();
}
2.SPI0的初始化
void spi_init(void)
{
spi_i2s_deinit(SPI0);
spi_struct_para_init(&spi_init_struct);
/* SPI0 parameter configuration */
spi_init_struct.trans_mode = SPI_TRANSMODE_FULLDUPLEX;
spi_init_struct.device_mode = SPI_MASTER;
spi_init_struct.frame_size = SPI_FRAMESIZE_8BIT;
spi_init_struct.clock_polarity_phase = SPI_CK_PL_LOW_PH_1EDGE;
spi_init_struct.nss = SPI_NSS_SOFT;
spi_init_struct.prescale = SPI_PSC_4;
spi_init_struct.endian = SPI_ENDIAN_MSB;
spi_init(SPI0, &spi_init_struct);
/* enable quad wire SPI_IO2 and SPI_IO3 pin output */
qspi_io23_output_enable(SPI0);
/* enable SPI0 */
spi_enable(SPI0);
}
3. 通过DMA 读取FLASH 数据
void Dma_spi0_read_data(uint8_t* pbuffer, uint16_t num_byte_to_read)
{
uint8_t SendData;
dma_single_data_parameter_struct dma_init_struct;
dma_single_data_para_struct_init(&dma_init_struct);
dma_channel_disable(DMA1, DMA_CH2);
dma_channel_disable(DMA1, DMA_CH3);
/* SPI0 transmit dma config: DMA1,DMA_CH3 SPI0_TX */
dma_deinit(DMA1, DMA_CH3);
dma_init_struct.periph_addr = (uint32_t)&SPI_DATA(SPI0);
dma_init_struct.memory0_addr = (uint32_t)&SendData;
dma_init_struct.direction = DMA_MEMORY_TO_PERIPH;
dma_init_struct.periph_memory_width = DMA_MEMORY_WIDTH_8BIT;
dma_init_struct.priority = DMA_PRIORITY_HIGH;
dma_init_struct.number = num_byte_to_read;
dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_DISABLE;
dma_init_struct.circular_mode = DMA_CIRCULAR_MODE_DISABLE;
dma_single_data_mode_init(DMA1, DMA_CH3, &dma_init_struct);
/* connect DMA1_CH3 to SPI0 TX */
dma_channel_subperipheral_select(DMA1, DMA_CH3, DMA_SUBPERI3);
dma_flag_clear(DMA1,DMA_CH3,DMA_INTF_HTFIF);
dma_flag_clear(DMA1,DMA_CH3,DMA_INTF_FTFIF);
/* enable DMA transfer complete interrupt */
// dma_interrupt_enable(DMA1, DMA_CH0, DMA_INT_FTF);
/* SPI0 receive dma config:DMA1-DMA_CH2 SPI0_RX*/
dma_deinit(DMA1, DMA_CH2);
dma_init_struct.periph_addr = (uint32_t)&SPI_DATA(SPI0);
dma_init_struct.memory0_addr = (uint32_t)pbuffer;
dma_init_struct.direction = DMA_PERIPH_TO_MEMORY;
dma_init_struct.priority = DMA_PRIORITY_HIGH;
dma_init_struct.number = num_byte_to_read;
dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
dma_single_data_mode_init(DMA1, DMA_CH2, &dma_init_struct);
/* connect DMA1_CH2 to SPI0 RX */
dma_channel_subperipheral_select(DMA1, DMA_CH2, DMA_SUBPERI3);
/* enable DMA receive complete interrupt */
dma_interrupt_enable(DMA1, DMA_CH2, DMA_INT_FTF);
/*configure DMA interrupt*/
nvic_irq_enable(DMA1_Channel2_IRQn, 0, 1);
dma_channel_enable(DMA1, DMA_CH2);
/* SPI DMA enable */
spi_dma_enable(SPI0, SPI_DMA_RECEIVE);
/* DMA channel enable */
dma_channel_enable(DMA1,DMA_CH3);
/* SPI DMA enable */
spi_dma_enable(SPI0, SPI_DMA_TRANSMIT);
// /* wait dma transmite complete */
while(!dma_flag_get(DMA1, DMA_CH3, DMA_INTF_FTFIF));
// /* wait dma receive complete */
while(!dma_flag_get(DMA1, DMA_CH2, DMA_INTF_FTFIF));
dma_interrupt_flag_clear(DMA1, DMA_CH3, DMA_INTF_HTFIF);//半
dma_interrupt_flag_clear(DMA1 , DMA_CH3, DMA_INTF_FTFIF);
dma_interrupt_flag_clear(DMA1, DMA_CH2, DMA_INTF_HTFIF);//半
dma_interrupt_flag_clear(DMA1 , DMA_CH2, DMA_INTF_FTFIF);
spi_dma_disable(SPI0, SPI_DMA_RECEIVE);
spi_dma_disable(SPI0, SPI_DMA_TRANSMIT);
dma_channel_disable(DMA1, DMA_CH2);
dma_channel_disable(DMA1, DMA_CH3);
}
4.通过DMA写FLASH数据
void Dma_spi0_write_data(uint8_t* pbuffer, uint16_t num_byte_to_write)
{
uint8_t ReadData;
dma_single_data_parameter_struct dma_init_struct;
dma_single_data_para_struct_init(&dma_init_struct);
dma_channel_disable(DMA1, DMA_CH2);
dma_channel_disable(DMA1, DMA_CH3);
/* SPI0 transmit dma config: DMA1,DMA_CH3 SPI0_TX */
dma_deinit(DMA1, DMA_CH3);
dma_init_struct.periph_addr = (uint32_t)&SPI_DATA(SPI0);
dma_init_struct.memory0_addr = (uint32_t)&pbuffer;
dma_init_struct.direction = DMA_MEMORY_TO_PERIPH;
dma_init_struct.periph_memory_width = DMA_MEMORY_WIDTH_8BIT;
dma_init_struct.priority = DMA_PRIORITY_HIGH;
dma_init_struct.number = num_byte_to_write;
dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
dma_init_struct.circular_mode = DMA_CIRCULAR_MODE_DISABLE;
dma_single_data_mode_init(DMA1, DMA_CH3, &dma_init_struct);
/* connect DMA1_CH3 to SPI0 TX */
dma_channel_subperipheral_select(DMA1, DMA_CH3, DMA_SUBPERI3);
dma_flag_clear(DMA1,DMA_CH3,DMA_INTF_HTFIF);
dma_flag_clear(DMA1,DMA_CH3,DMA_INTF_FTFIF);
/* enable DMA transfer complete interrupt */
// dma_interrupt_enable(DMA1, DMA_CH0, DMA_INT_FTF);
/* SPI0 receive dma config:DMA1-DMA_CH2 SPI0_RX*/
dma_deinit(DMA1, DMA_CH2);
dma_init_struct.periph_addr = (uint32_t)&SPI_DATA(SPI0);
dma_init_struct.memory0_addr = (uint32_t)&ReadData;
dma_init_struct.direction = DMA_PERIPH_TO_MEMORY;
dma_init_struct.priority = DMA_PRIORITY_HIGH;
dma_init_struct.number = num_byte_to_write;
dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_DISABLE;
dma_single_data_mode_init(DMA1, DMA_CH2, &dma_init_struct);
/* connect DMA1_CH2 to SPI0 RX */
dma_channel_subperipheral_select(DMA1, DMA_CH2, DMA_SUBPERI3);
dma_channel_enable(DMA1, DMA_CH2);
/* SPI DMA enable */
spi_dma_enable(SPI0, SPI_DMA_RECEIVE);
/* DMA channel enable */
dma_channel_enable(DMA1,DMA_CH3);
/* SPI DMA enable */
spi_dma_enable(SPI0, SPI_DMA_TRANSMIT);
/* wait dma transmite complete */
while(!dma_flag_get(DMA1, DMA_CH3, DMA_INTF_FTFIF));
/* wait dma receive complete */
while(!dma_flag_get(DMA1, DMA_CH2, DMA_INTF_FTFIF));
dma_interrupt_flag_clear(DMA1, DMA_CH3, DMA_INTF_HTFIF);//半
dma_interrupt_flag_clear(DMA1 , DMA_CH3, DMA_INTF_FTFIF);
dma_interrupt_flag_clear(DMA1, DMA_CH2, DMA_INTF_HTFIF);//半
dma_interrupt_flag_clear(DMA1 , DMA_CH2, DMA_INTF_FTFIF);
spi_dma_disable(SPI0, SPI_DMA_RECEIVE);
spi_dma_disable(SPI0, SPI_DMA_TRANSMIT);
dma_channel_disable(DMA1, DMA_CH2);
dma_channel_disable(DMA1, DMA_CH3);
}
5.通过DMA读取FLASH数据, 少量初始化寄存器
void Dma_spi0_read_data_repeat(uint8_t* pbuffer, uint16_t num_byte_to_read)
{
uint32_t ctl;
uint8_t SendData;
dma_channel_disable(DMA1, DMA_CH2);
dma_channel_disable(DMA1, DMA_CH3);
/* configure peripheral base address */
DMA_CHPADDR(DMA1, DMA_CH3) = (uint32_t)&SPI_DATA(SPI0);
/* configure memory base address */
DMA_CHM0ADDR(DMA1, DMA_CH3) = (uint32_t)&SendData;
DMA_CHCNT(DMA1, DMA_CH3) = num_byte_to_read;
// DMA_CHCTL(DMA1, DMA_CH3) &= ~DMA_CHXCTL_PNAGA;//DMA_PERIPH_INCREASE_DISABLE
// DMA_CHCTL(DMA1, DMA_CH3) &= ~DMA_CHXCTL_MNAGA;//DMA_MEMORY_INCREASE_DISABLE
// ctl = DMA_CHCTL(DMA1, DMA_CH3);
// ctl &= ~(DMA_CHXCTL_PWIDTH | DMA_CHXCTL_MWIDTH | DMA_CHXCTL_PRIO | DMA_CHXCTL_TM);
// ctl |= (DMA_MEMORY_WIDTH_8BIT | (DMA_PERIPH_WIDTH_8BIT << 2) | DMA_PRIORITY_HIGH | DMA_MEMORY_TO_PERIPH);
// DMA_CHCTL(DMA1, DMA_CH3) = ctl;
// DMA_CHCTL(DMA1, DMA_CH3) &= ~DMA_CHXCTL_CMEN;//DMA_CIRCULAR_MODE_DISABLE
// /* connect DMA1_CH3 to SPI0 TX */
// dma_channel_subperipheral_select(DMA1, DMA_CH3, DMA_SUBPERI3);
//dma_flag_clear(DMA1,DMA_CH3,DMA_INTF_HTFIF);
dma_flag_clear(DMA1,DMA_CH3,DMA_INTF_FTFIF);
/* enable DMA transfer complete interrupt */
// dma_interrupt_enable(DMA1, DMA_CH0, DMA_INT_FTF);
/* SPI0 receive dma config:DMA1-DMA_CH2 SPI0_RX*/
DMA_CHPADDR(DMA1, DMA_CH2) = (uint32_t)&SPI_DATA(SPI0);
DMA_CHM0ADDR(DMA1, DMA_CH2) = (uint32_t)pbuffer;
DMA_CHCNT(DMA1, DMA_CH2) = num_byte_to_read;
// DMA_CHCTL(DMA1, DMA_CH2) &= ~DMA_CHXCTL_PNAGA;//DMA_PERIPH_INCREASE_DISABLE
// DMA_CHCTL(DMA1, DMA_CH2) |= DMA_CHXCTL_MNAGA;//DMA_MEMORY_INCREASE_ENABLE
// ctl = DMA_CHCTL(DMA1, DMA_CH2);
// ctl &= ~(DMA_CHXCTL_PWIDTH | DMA_CHXCTL_MWIDTH | DMA_CHXCTL_PRIO | DMA_CHXCTL_TM);
// ctl |= (DMA_MEMORY_WIDTH_8BIT | (DMA_PERIPH_WIDTH_8BIT << 2) | DMA_PRIORITY_HIGH | DMA_PERIPH_TO_MEMORY);
// DMA_CHCTL(DMA1, DMA_CH2) = ctl;
// DMA_CHCTL(DMA1, DMA_CH2) &= ~DMA_CHXCTL_CMEN;//DMA_CIRCULAR_MODE_DISABLE
// /* connect DMA1_CH2 to SPI0 RX */
// dma_channel_subperipheral_select(DMA1, DMA_CH2, DMA_SUBPERI3);
//dma_flag_clear(DMA1,DMA_CH2,DMA_INTF_HTFIF);
dma_flag_clear(DMA1,DMA_CH2,DMA_INTF_FTFIF);
/* enable DMA receive complete interrupt */
// dma_interrupt_enable(DMA1, DMA_CH2, DMA_INT_FTF);
/*configure DMA interrupt*/
// nvic_irq_enable(DMA1_Channel2_IRQn, 0, 1);
dma_channel_enable(DMA1, DMA_CH2);
/* SPI DMA enable */
spi_dma_enable(SPI0, SPI_DMA_RECEIVE);
/* DMA channel enable */
dma_channel_enable(DMA1,DMA_CH3);
/* SPI DMA enable */
spi_dma_enable(SPI0, SPI_DMA_TRANSMIT);
// /* wait dma transmite complete */
while(!dma_flag_get(DMA1, DMA_CH3, DMA_INTF_FTFIF));
// /* wait dma receive complete */
while(!dma_flag_get(DMA1, DMA_CH2, DMA_INTF_FTFIF));
dma_interrupt_flag_clear(DMA1, DMA_CH3, DMA_INTF_HTFIF);//半
dma_interrupt_flag_clear(DMA1 , DMA_CH3, DMA_INTF_FTFIF);
dma_interrupt_flag_clear(DMA1, DMA_CH2, DMA_INTF_HTFIF);//半
dma_interrupt_flag_clear(DMA1 , DMA_CH2, DMA_INTF_FTFIF);
spi_dma_disable(SPI0, SPI_DMA_RECEIVE);
spi_dma_disable(SPI0, SPI_DMA_TRANSMIT);
dma_channel_disable(DMA1, DMA_CH2);
dma_channel_disable(DMA1, DMA_CH3);
}