[AT32L021] 【AT-START-L021测评】+ spiflash读写测试

[复制链接]
 楼主| tlled 发表于 2024-12-2 00:13 | 显示全部楼层 |阅读模式
测试spiflash存储器读写。

一、硬件部分

测试使用SPI1接口。
001.png

二、程序部分

2.1、配置SPI1
spi1初始化部分程序可以使用软件AT32_Work_Bench生成
002.png

2.2、spi-flash.c
  1. /**
  2.   **************************************************************************
  3.   * [url=home.php?mod=space&uid=288409]@file[/url]     spi_flash.c
  4.   * [url=home.php?mod=space&uid=247401]@brief[/url]    spi_flash source code
  5.   **************************************************************************
  6.   *                       Copyright notice & Disclaimer
  7.   *
  8.   * The software Board Support Package (BSP) that is made available to
  9.   * download from Artery official website is the copyrighted work of Artery.
  10.   * Artery authorizes customers to use, copy, and distribute the BSP
  11.   * software and its related documentation for the purpose of design and
  12.   * development in conjunction with Artery microcontrollers. Use of the
  13.   * software is governed by this copyright notice and the following disclaimer.
  14.   *
  15.   * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
  16.   * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
  17.   * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
  18.   * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
  19.   * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
  20.   * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
  21.   *
  22.   **************************************************************************
  23.   */

  24. #include "spiflash/spi_flash.h"

  25. /** @addtogroup AT32L021_periph_examples
  26.   * @{
  27.   */

  28. /** @addtogroup 021_SPI_w25q_flash
  29.   * @{
  30.   */

  31. uint8_t spiflash_sector_buf[SPIF_SECTOR_SIZE];

  32. /**
  33.   * @brief  spi configuration.
  34.   * @param  none
  35.   * @retval none
  36.   */
  37. void spiflash_init(void)
  38. {
  39.   gpio_init_type gpio_initstructure;
  40.   spi_init_type spi_init_struct;

  41.   crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE);
  42.   crm_periph_clock_enable(CRM_DMA1_PERIPH_CLOCK, TRUE);
  43.   
  44.   gpio_pin_mux_config(GPIOA, GPIO_PINS_SOURCE5, GPIO_MUX_0);
  45.   gpio_pin_mux_config(GPIOA, GPIO_PINS_SOURCE6, GPIO_MUX_0);
  46.   gpio_pin_mux_config(GPIOA, GPIO_PINS_SOURCE7, GPIO_MUX_0);
  47.   
  48.   /* software cs, pa15 as a general io to control flash cs */
  49.   gpio_initstructure.gpio_out_type       = GPIO_OUTPUT_PUSH_PULL;
  50.   gpio_initstructure.gpio_pull           = GPIO_PULL_UP;
  51.   gpio_initstructure.gpio_mode           = GPIO_MODE_OUTPUT;
  52.   gpio_initstructure.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
  53.   gpio_initstructure.gpio_pins           = GPIO_PINS_15;
  54.   gpio_init(GPIOA, &gpio_initstructure);

  55.   /* sck */
  56.   gpio_initstructure.gpio_pull           = GPIO_PULL_UP;
  57.   gpio_initstructure.gpio_mode           = GPIO_MODE_MUX;
  58.   gpio_initstructure.gpio_pins           = GPIO_PINS_5;
  59.   gpio_init(GPIOA, &gpio_initstructure);

  60.   /* miso */
  61.   gpio_initstructure.gpio_pull           = GPIO_PULL_UP;
  62.   gpio_initstructure.gpio_mode           = GPIO_MODE_MUX;
  63.   gpio_initstructure.gpio_pins           = GPIO_PINS_6;
  64.   gpio_init(GPIOA, &gpio_initstructure);

  65.   /* mosi */
  66.   gpio_initstructure.gpio_pull           = GPIO_PULL_UP;
  67.   gpio_initstructure.gpio_mode           = GPIO_MODE_MUX;
  68.   gpio_initstructure.gpio_pins           = GPIO_PINS_7;
  69.   gpio_init(GPIOA, &gpio_initstructure);

  70.   FLASH_CS_HIGH();
  71.   crm_periph_clock_enable(CRM_SPI1_PERIPH_CLOCK, TRUE);
  72.   spi_default_para_init(&spi_init_struct);
  73.   spi_init_struct.transmission_mode = SPI_TRANSMIT_FULL_DUPLEX;
  74.   spi_init_struct.master_slave_mode = SPI_MODE_MASTER;
  75.   spi_init_struct.mclk_freq_division = SPI_MCLK_DIV_8;
  76.   spi_init_struct.first_bit_transmission = SPI_FIRST_BIT_MSB;
  77.   spi_init_struct.frame_bit_num = SPI_FRAME_8BIT;
  78.   spi_init_struct.clock_polarity = SPI_CLOCK_POLARITY_HIGH;
  79.   spi_init_struct.clock_phase = SPI_CLOCK_PHASE_2EDGE;
  80.   spi_init_struct.cs_mode_selection = SPI_CS_SOFTWARE_MODE;
  81.   spi_init(SPI1, &spi_init_struct);
  82.   spi_enable(SPI1, TRUE);
  83. }

  84. /**
  85.   * @brief  write data to flash
  86.   * @param  pbuffer: the pointer for data buffer
  87.   * @param  write_addr: the address where the data is written
  88.   * @param  length: buffer length
  89.   * @retval none
  90.   */
  91. void spiflash_write(uint8_t *pbuffer, uint32_t write_addr, uint32_t length)
  92. {
  93.   uint32_t sector_pos;
  94.   uint16_t sector_offset;
  95.   uint16_t sector_remain;
  96.   uint16_t index;
  97.   uint8_t *spiflash_buf;
  98.   spiflash_buf = spiflash_sector_buf;

  99.   /* sector address */
  100.   sector_pos = write_addr / SPIF_SECTOR_SIZE;

  101.   /* address offset in a sector */
  102.   sector_offset = write_addr % SPIF_SECTOR_SIZE;

  103.   /* the remain in a sector */
  104.   sector_remain = SPIF_SECTOR_SIZE - sector_offset;
  105.   if(length <= sector_remain)
  106.   {
  107.     /* smaller than a sector size */
  108.     sector_remain = length;
  109.   }
  110.   while(1)
  111.   {
  112.     /* read a sector */
  113.     spiflash_read(spiflash_buf, sector_pos * SPIF_SECTOR_SIZE, SPIF_SECTOR_SIZE);

  114.     /* validate the read erea */
  115.     for(index = 0; index < sector_remain; index++)
  116.     {
  117.       if(spiflash_buf[sector_offset + index] != 0xFF)
  118.       {
  119.         /* there are some data not equal 0xff, so this secotr needs erased */
  120.         break;
  121.       }
  122.     }
  123.     if(index < sector_remain)
  124.     {
  125.       /* erase the sector */
  126.       spiflash_sector_erase(sector_pos);

  127.       /* copy the write data */
  128.       for(index = 0; index < sector_remain; index++)
  129.       {
  130.         spiflash_buf[index + sector_offset] = pbuffer[index];
  131.       }
  132.       spiflash_write_nocheck(spiflash_buf, sector_pos * SPIF_SECTOR_SIZE, SPIF_SECTOR_SIZE); /* program the sector */
  133.     }
  134.     else
  135.     {
  136.       /* write directly in the erased area */
  137.       spiflash_write_nocheck(pbuffer, write_addr, sector_remain);
  138.     }
  139.     if(length == sector_remain)
  140.     {
  141.       /* write end */
  142.       break;
  143.     }
  144.     else
  145.     {
  146.       /* go on writing */
  147.       sector_pos++;
  148.       sector_offset = 0;

  149.       pbuffer += sector_remain;
  150.       write_addr += sector_remain;
  151.       length -= sector_remain;
  152.       if(length > SPIF_SECTOR_SIZE)
  153.       {
  154.         /* could not write the remain data in the next sector */
  155.         sector_remain = SPIF_SECTOR_SIZE;
  156.       }
  157.       else
  158.       {
  159.         /* could write the remain data in the next sector */
  160.         sector_remain = length;
  161.       }
  162.     }
  163.   }
  164. }

  165. /**
  166.   * @brief  read data from flash
  167.   * @param  pbuffer: the pointer for data buffer
  168.   * @param  read_addr: the address where the data is read
  169.   * @param  length: buffer length
  170.   * @retval none
  171.   */
  172. void spiflash_read(uint8_t *pbuffer, uint32_t read_addr, uint32_t length)
  173. {
  174.   FLASH_CS_LOW();
  175.   spi_byte_write(SPIF_READDATA); /* send instruction */
  176.   spi_byte_write((uint8_t)((read_addr) >> 16)); /* send 24-bit address */
  177.   spi_byte_write((uint8_t)((read_addr) >> 8));
  178.   spi_byte_write((uint8_t)read_addr);
  179.   spi_bytes_read(pbuffer, length);
  180.   FLASH_CS_HIGH();
  181. }

  182. /**
  183.   * @brief  erase a sector data
  184.   * @param  erase_addr: sector address to erase
  185.   * @retval none
  186.   */
  187. void spiflash_sector_erase(uint32_t erase_addr)
  188. {
  189.   erase_addr *= SPIF_SECTOR_SIZE; /* translate sector address to byte address */
  190.   spiflash_write_enable();
  191.   spiflash_wait_busy();
  192.   FLASH_CS_LOW();
  193.   spi_byte_write(SPIF_SECTORERASE);
  194.   spi_byte_write((uint8_t)((erase_addr) >> 16));
  195.   spi_byte_write((uint8_t)((erase_addr) >> 8));
  196.   spi_byte_write((uint8_t)erase_addr);
  197.   FLASH_CS_HIGH();
  198.   spiflash_wait_busy();
  199. }

  200. /**
  201.   * @brief  write data without check
  202.   * @param  pbuffer: the pointer for data buffer
  203.   * @param  write_addr: the address where the data is written
  204.   * @param  length: buffer length
  205.   * @retval none
  206.   */
  207. void spiflash_write_nocheck(uint8_t *pbuffer, uint32_t write_addr, uint32_t length)
  208. {
  209.   uint16_t page_remain;

  210.   /* remain bytes in a page */
  211.   page_remain = SPIF_PAGE_SIZE - write_addr % SPIF_PAGE_SIZE;
  212.   if(length <= page_remain)
  213.   {
  214.     /* smaller than a page size */
  215.     page_remain = length;
  216.   }
  217.   while(1)
  218.   {
  219.     spiflash_page_write(pbuffer, write_addr, page_remain);
  220.     if(length == page_remain)
  221.     {
  222.       /* all data are programmed */
  223.       break;
  224.     }
  225.     else
  226.     {
  227.       /* length > page_remain */
  228.       pbuffer += page_remain;
  229.       write_addr += page_remain;

  230.       /* the remain bytes to be prorammed */
  231.       length -= page_remain;
  232.       if(length > SPIF_PAGE_SIZE)
  233.       {
  234.         /* can be progrmmed a page at a time */
  235.         page_remain = SPIF_PAGE_SIZE;
  236.       }
  237.       else
  238.       {
  239.         /* smaller than a page size */
  240.         page_remain = length;
  241.       }
  242.     }
  243.   }
  244. }

  245. /**
  246.   * @brief  write a page data
  247.   * @param  pbuffer: the pointer for data buffer
  248.   * @param  write_addr: the address where the data is written
  249.   * @param  length: buffer length
  250.   * @retval none
  251.   */
  252. void spiflash_page_write(uint8_t *pbuffer, uint32_t write_addr, uint32_t length)
  253. {
  254.   if((0 < length) && (length <= SPIF_PAGE_SIZE))
  255.   {
  256.     /* set write enable */
  257.     spiflash_write_enable();

  258.     FLASH_CS_LOW();

  259.     /* send instruction */
  260.     spi_byte_write(SPIF_PAGEPROGRAM);

  261.     /* send 24-bit address */
  262.     spi_byte_write((uint8_t)((write_addr) >> 16));
  263.     spi_byte_write((uint8_t)((write_addr) >> 8));
  264.     spi_byte_write((uint8_t)write_addr);
  265.     spi_bytes_write(pbuffer,length);

  266.     FLASH_CS_HIGH();

  267.     /* wait for program end */
  268.     spiflash_wait_busy();
  269.   }
  270. }

  271. /**
  272.   * @brief  write data continuously
  273.   * @param  pbuffer: the pointer for data buffer
  274.   * @param  length: buffer length
  275.   * @retval none
  276.   */
  277. void spi_bytes_write(uint8_t *pbuffer, uint32_t length)
  278. {
  279.   volatile uint8_t dummy_data;

  280. #if defined(SPI_TRANS_DMA)
  281.   dma_init_type dma_init_struct;
  282.   dma_reset(DMA1_CHANNEL2);
  283.   dma_reset(DMA1_CHANNEL3);
  284.   
  285.   dma_flexible_config(DMA1, FLEX_CHANNEL2, DMA_FLEXIBLE_SPI2_RX);
  286.   dma_flexible_config(DMA1, FLEX_CHANNEL3, DMA_FLEXIBLE_SPI2_TX);
  287.   
  288.   dma_default_para_init(&dma_init_struct);
  289.   dma_init_struct.buffer_size = length;
  290.   dma_init_struct.direction = DMA_DIR_PERIPHERAL_TO_MEMORY;
  291.   dma_init_struct.memory_base_addr = (uint32_t)&dummy_data;
  292.   dma_init_struct.memory_data_width = DMA_MEMORY_DATA_WIDTH_BYTE;
  293.   dma_init_struct.memory_inc_enable = FALSE;
  294.   dma_init_struct.peripheral_base_addr = (uint32_t)(&SPI2->dt);
  295.   dma_init_struct.peripheral_data_width = DMA_PERIPHERAL_DATA_WIDTH_BYTE;
  296.   dma_init_struct.peripheral_inc_enable = FALSE;
  297.   dma_init_struct.priority = DMA_PRIORITY_VERY_HIGH;
  298.   dma_init_struct.loop_mode_enable = FALSE;
  299.   dma_init(DMA1_CHANNEL2, &dma_init_struct);

  300.   dma_init_struct.buffer_size = length;
  301.   dma_init_struct.direction = DMA_DIR_MEMORY_TO_PERIPHERAL;
  302.   dma_init_struct.memory_base_addr = (uint32_t)pbuffer;
  303.   dma_init_struct.memory_data_width = DMA_MEMORY_DATA_WIDTH_BYTE;
  304.   dma_init_struct.memory_inc_enable = TRUE;
  305.   dma_init_struct.peripheral_base_addr = (uint32_t)(&SPI2->dt);
  306.   dma_init_struct.peripheral_data_width = DMA_PERIPHERAL_DATA_WIDTH_BYTE;
  307.   dma_init_struct.peripheral_inc_enable = FALSE;
  308.   dma_init_struct.priority = DMA_PRIORITY_VERY_HIGH;
  309.   dma_init_struct.loop_mode_enable = FALSE;
  310.   dma_init(DMA1_CHANNEL3, &dma_init_struct);

  311.   spi_i2s_dma_transmitter_enable(SPI2, TRUE);
  312.   spi_i2s_dma_receiver_enable(SPI2, TRUE);

  313.   dma_channel_enable(DMA1_CHANNEL2, TRUE);
  314.   dma_channel_enable(DMA1_CHANNEL3, TRUE);

  315.   while(dma_flag_get(DMA1_FDT2_FLAG) == RESET);
  316.   dma_flag_clear(DMA1_FDT2_FLAG);

  317.   dma_channel_enable(DMA1_CHANNEL2, FALSE);
  318.   dma_channel_enable(DMA1_CHANNEL3, FALSE);

  319.   spi_i2s_dma_transmitter_enable(SPI2, FALSE);
  320.   spi_i2s_dma_receiver_enable(SPI2, FALSE);
  321. #else
  322.   while(length--)
  323.   {
  324.     while(spi_i2s_flag_get(SPI1, SPI_I2S_TDBE_FLAG) == RESET);
  325.     spi_i2s_data_transmit(SPI1, *pbuffer);
  326.     while(spi_i2s_flag_get(SPI1, SPI_I2S_RDBF_FLAG) == RESET);
  327.     dummy_data = spi_i2s_data_receive(SPI1);
  328.     pbuffer++;
  329.   }
  330. #endif
  331. }

  332. /**
  333.   * @brief  read data continuously
  334.   * @param  pbuffer: buffer to save data
  335.   * @param  length: buffer length
  336.   * @retval none
  337.   */
  338. void spi_bytes_read(uint8_t *pbuffer, uint32_t length)
  339. {
  340.   uint8_t write_value = FLASH_SPI_DUMMY_BYTE;

  341. #if defined(SPI_TRANS_DMA)
  342.   dma_init_type dma_init_struct;
  343.   dma_reset(DMA1_CHANNEL2);
  344.   dma_reset(DMA1_CHANNEL3);
  345.   
  346.   dma_flexible_config(DMA1, FLEX_CHANNEL2, DMA_FLEXIBLE_SPI2_RX);
  347.   dma_flexible_config(DMA1, FLEX_CHANNEL3, DMA_FLEXIBLE_SPI2_TX);
  348.   
  349.   dma_default_para_init(&dma_init_struct);
  350.   dma_init_struct.buffer_size = length;
  351.   dma_init_struct.direction = DMA_DIR_MEMORY_TO_PERIPHERAL;
  352.   dma_init_struct.memory_base_addr = (uint32_t)&write_value;
  353.   dma_init_struct.memory_data_width = DMA_MEMORY_DATA_WIDTH_BYTE;
  354.   dma_init_struct.memory_inc_enable = FALSE;
  355.   dma_init_struct.peripheral_base_addr = (uint32_t)(&SPI2->dt);
  356.   dma_init_struct.peripheral_data_width = DMA_PERIPHERAL_DATA_WIDTH_BYTE;
  357.   dma_init_struct.peripheral_inc_enable = FALSE;
  358.   dma_init_struct.priority = DMA_PRIORITY_VERY_HIGH;
  359.   dma_init_struct.loop_mode_enable = FALSE;
  360.   dma_init(DMA1_CHANNEL3, &dma_init_struct);

  361.   dma_init_struct.buffer_size = length;
  362.   dma_init_struct.direction = DMA_DIR_PERIPHERAL_TO_MEMORY;
  363.   dma_init_struct.memory_base_addr = (uint32_t)pbuffer;
  364.   dma_init_struct.memory_data_width = DMA_MEMORY_DATA_WIDTH_BYTE;
  365.   dma_init_struct.memory_inc_enable = TRUE;
  366.   dma_init_struct.peripheral_base_addr = (uint32_t)(&SPI2->dt);
  367.   dma_init_struct.peripheral_data_width = DMA_PERIPHERAL_DATA_WIDTH_BYTE;
  368.   dma_init_struct.peripheral_inc_enable = FALSE;
  369.   dma_init_struct.priority = DMA_PRIORITY_VERY_HIGH;
  370.   dma_init_struct.loop_mode_enable = FALSE;
  371.   dma_init(DMA1_CHANNEL2, &dma_init_struct);

  372.   spi_i2s_dma_transmitter_enable(SPI2, TRUE);
  373.   spi_i2s_dma_receiver_enable(SPI2, TRUE);
  374.   dma_channel_enable(DMA1_CHANNEL2, TRUE);
  375.   dma_channel_enable(DMA1_CHANNEL3, TRUE);

  376.   while(dma_flag_get(DMA1_FDT2_FLAG) == RESET);
  377.   dma_flag_clear(DMA1_FDT2_FLAG);

  378.   dma_channel_enable(DMA1_CHANNEL2, FALSE);
  379.   dma_channel_enable(DMA1_CHANNEL3, FALSE);

  380.   spi_i2s_dma_transmitter_enable(SPI2, FALSE);
  381.   spi_i2s_dma_receiver_enable(SPI2, FALSE);
  382. #else
  383.   while(length--)
  384.   {
  385.     while(spi_i2s_flag_get(SPI1, SPI_I2S_TDBE_FLAG) == RESET);
  386.     spi_i2s_data_transmit(SPI1, write_value);
  387.     while(spi_i2s_flag_get(SPI1, SPI_I2S_RDBF_FLAG) == RESET);
  388.     *pbuffer = spi_i2s_data_receive(SPI1);
  389.     pbuffer++;
  390.   }
  391. #endif
  392. }

  393. /**
  394.   * @brief  wait program done
  395.   * @param  none
  396.   * @retval none
  397.   */
  398. void spiflash_wait_busy(void)
  399. {
  400.   while((spiflash_read_sr1() & 0x01) == 0x01);
  401. }

  402. /**
  403.   * @brief  read sr1 register
  404.   * @param  none
  405.   * @retval none
  406.   */
  407. uint8_t spiflash_read_sr1(void)
  408. {
  409.   uint8_t breadbyte = 0;
  410.   FLASH_CS_LOW();
  411.   spi_byte_write(SPIF_READSTATUSREG1);
  412.   breadbyte = (uint8_t)spi_byte_read();
  413.   FLASH_CS_HIGH();
  414.   return (breadbyte);
  415. }

  416. /**
  417.   * @brief  enable write operation
  418.   * @param  none
  419.   * @retval none
  420.   */
  421. void spiflash_write_enable(void)
  422. {
  423.   FLASH_CS_LOW();
  424.   spi_byte_write(SPIF_WRITEENABLE);
  425.   FLASH_CS_HIGH();
  426. }

  427. /**
  428.   * @brief  read device id
  429.   * @param  none
  430.   * @retval device id
  431.   */
  432. uint16_t spiflash_read_id(void)
  433. {
  434.   uint16_t wreceivedata = 0;
  435.   FLASH_CS_LOW();
  436.   spi_byte_write(SPIF_MANUFACTDEVICEID);
  437.   spi_byte_write(0x00);
  438.   spi_byte_write(0x00);
  439.   spi_byte_write(0x00);
  440.   wreceivedata |= spi_byte_read() << 8;
  441.   wreceivedata |= spi_byte_read();
  442.   FLASH_CS_HIGH();
  443.   return wreceivedata;
  444. }

  445. /**
  446.   * @brief  write a byte to flash
  447.   * @param  data: data to write
  448.   * @retval flash return data
  449.   */
  450. uint8_t spi_byte_write(uint8_t data)
  451. {
  452.   uint8_t brxbuff;
  453.   spi_i2s_dma_transmitter_enable(SPI1, FALSE);
  454.   spi_i2s_dma_receiver_enable(SPI1, FALSE);
  455.   spi_i2s_data_transmit(SPI1, data);
  456.   while(spi_i2s_flag_get(SPI1, SPI_I2S_RDBF_FLAG) == RESET);
  457.   brxbuff = spi_i2s_data_receive(SPI1);
  458.   while(spi_i2s_flag_get(SPI1, SPI_I2S_BF_FLAG) != RESET);
  459.   return brxbuff;
  460. }

  461. /**
  462.   * @brief  read a byte to flash
  463.   * @param  none
  464.   * @retval flash return data
  465.   */
  466. uint8_t spi_byte_read(void)
  467. {
  468.   return (spi_byte_write(FLASH_SPI_DUMMY_BYTE));
  469. }

  470. /**
  471.   * @}
  472.   */

  473. /**
  474.   * @}
  475.   */



2.3、spi-flash.h
  1. /**
  2.   **************************************************************************
  3.   * @file     spi_flash.h
  4.   * @brief    header file of spi_flash
  5.   **************************************************************************
  6.   *                       Copyright notice & Disclaimer
  7.   *
  8.   * The software Board Support Package (BSP) that is made available to
  9.   * download from Artery official website is the copyrighted work of Artery.
  10.   * Artery authorizes customers to use, copy, and distribute the BSP
  11.   * software and its related documentation for the purpose of design and
  12.   * development in conjunction with Artery microcontrollers. Use of the
  13.   * software is governed by this copyright notice and the following disclaimer.
  14.   *
  15.   * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
  16.   * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
  17.   * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
  18.   * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
  19.   * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
  20.   * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
  21.   *
  22.   **************************************************************************
  23.   */

  24. #ifndef __SPI_FLASH_H
  25. #define __SPI_FLASH_H

  26. #include "at32l021.h"

  27. /** @addtogroup AT32L021_periph_examples
  28.   * @{
  29.   */

  30. /** @addtogroup 021_SPI_w25q_flash
  31.   * @{
  32.   */


  33. /* use dma transfer spi data */
  34. //#define SPI_TRANS_DMA

  35. /** @defgroup SPI_flash_cs_pin_definition
  36.   * @{
  37.   */

  38. #define FLASH_CS_HIGH()                  gpio_bits_set(GPIOA, GPIO_PINS_15)
  39. #define FLASH_CS_LOW()                   gpio_bits_reset(GPIOA, GPIO_PINS_15)

  40. /**
  41.   * @}
  42.   */

  43. /** @defgroup SPI_flash_id_definition
  44.   * @{
  45.   */

  46. /*
  47. * flash define
  48. */
  49. #define W25Q80                           0xEF13
  50. #define W25Q16                           0xEF14
  51. #define W25Q32                           0xEF15
  52. #define W25Q64                           0xEF16
  53. /* 16mb, the range of address:0~0xFFFFFF */
  54. #define W25Q128                          0xEF17

  55. /**
  56.   * @}
  57.   */

  58. /** @defgroup SPI_flash_operation_definition
  59.   * @{
  60.   */

  61. #define SPIF_CHIP_SIZE                   0x1000000
  62. #define SPIF_SECTOR_SIZE                 4096
  63. #define SPIF_PAGE_SIZE                   256

  64. #define SPIF_WRITEENABLE                 0x06
  65. #define SPIF_WRITEDISABLE                0x04
  66. /* s7-s0 */
  67. #define SPIF_READSTATUSREG1              0x05
  68. #define SPIF_WRITESTATUSREG1             0x01
  69. /* s15-s8 */
  70. #define SPIF_READSTATUSREG2              0x35
  71. #define SPIF_WRITESTATUSREG2             0x31
  72. /* s23-s16 */
  73. #define SPIF_READSTATUSREG3              0x15
  74. #define SPIF_WRITESTATUSREG3             0x11
  75. #define SPIF_READDATA                    0x03
  76. #define SPIF_FASTREADDATA                0x0B
  77. #define SPIF_FASTREADDUAL                0x3B
  78. #define SPIF_PAGEPROGRAM                 0x02
  79. /* block size:64kb */
  80. #define SPIF_BLOCKERASE                  0xD8
  81. #define SPIF_SECTORERASE                 0x20
  82. #define SPIF_CHIPERASE                   0xC7
  83. #define SPIF_POWERDOWN                   0xB9
  84. #define SPIF_RELEASEPOWERDOWN            0xAB
  85. #define SPIF_DEVICEID                    0xAB
  86. #define SPIF_MANUFACTDEVICEID            0x90
  87. #define SPIF_JEDECDEVICEID               0x9F
  88. #define FLASH_SPI_DUMMY_BYTE             0xA5

  89. /**
  90.   * @}
  91.   */

  92. /** @defgroup SPI_flash_exported_functions
  93.   * @{
  94.   */

  95. void spiflash_init(void);
  96. void spiflash_write(uint8_t *pbuffer, uint32_t write_addr, uint32_t length);
  97. void spiflash_read(uint8_t *pbuffer, uint32_t read_addr, uint32_t length);
  98. void spiflash_sector_erase(uint32_t erase_addr);
  99. void spiflash_write_nocheck(uint8_t *pbuffer, uint32_t write_addr, uint32_t length);
  100. void spiflash_page_write(uint8_t *pbuffer, uint32_t write_addr, uint32_t length);
  101. void spi_bytes_write(uint8_t *pbuffer, uint32_t length);
  102. void spi_bytes_read(uint8_t *pbuffer, uint32_t length);
  103. void spiflash_wait_busy(void);
  104. uint8_t spiflash_read_sr1(void);
  105. void spiflash_write_enable(void);
  106. uint16_t spiflash_read_id(void);
  107. uint8_t spi_byte_write(uint8_t data);
  108. uint8_t spi_byte_read(void);

  109. /**
  110.   * @}
  111.   */

  112. /**
  113.   * @}
  114.   */

  115. /**
  116.   * @}
  117.   */

  118. #endif



2.4、main.c
  1. #include "at32l021_clock.h"
  2. #include "usart/usart.h"
  3. #include "led/led.h"
  4. #include "delay/delay.h"
  5. #include "i2c/i2c.h"
  6. #include "oled/oled.h"
  7. #include "adc/adc.h"
  8. #include "spiflash/spi_flash.h"

  9. #define FLASH_TEST_ADDR                  0x1000
  10. #define SPI_BUF_SIZE                     256

  11. uint8_t tx_buffer[SPI_BUF_SIZE];
  12. uint8_t rx_buffer[SPI_BUF_SIZE];

  13. void tx_data_fill(void)
  14. {
  15.   uint32_t data_index = 0;
  16.   for(data_index = 0; data_index < SPI_BUF_SIZE; data_index++)
  17.   {
  18.     tx_buffer[data_index] = data_index;
  19.   }
  20. }

  21. int main(void)
  22. {
  23.         __IO uint32_t index = 0;
  24.         __IO uint32_t flash_id_index = 0;
  25.   system_clock_config();
  26.         init_usart(115200);
  27.         delay_init();
  28.         init_led();
  29.         printf("test\r\n");
  30.         tx_data_fill();
  31.         spiflash_init();
  32.         flash_id_index = spiflash_read_id();
  33.         if(flash_id_index !=0x5114)
  34.         {
  35.                 printf("flash id check error!\r\n");
  36.         }
  37.         else
  38.         {
  39.                 printf("flash id check success! id: %x\r\n", flash_id_index);
  40.         }
  41.        
  42.         spiflash_sector_erase(FLASH_TEST_ADDR / SPIF_SECTOR_SIZE);
  43.         spiflash_write(tx_buffer, FLASH_TEST_ADDR, SPI_BUF_SIZE);
  44.         spiflash_read(rx_buffer, FLASH_TEST_ADDR, SPI_BUF_SIZE);
  45.         printf("Read Data: ");
  46.   for(index = 0; index < SPI_BUF_SIZE; index++)
  47.   {
  48.     printf("%x ", rx_buffer[index]);
  49.   }
  50.        
  51.   while(1)
  52.   {
  53.     led2_tog();
  54.     delay_ms(200);
  55.   }
  56. }


三、运行结果

串口输出读出的数据
003.png

您需要登录后才可以回帖 登录 | 注册

本版积分规则

132

主题

701

帖子

7

粉丝
快速回复 在线客服 返回列表 返回顶部