1 /*
2  * Copyright (C) 2015-2017 Alibaba Group Holding Limited
3  */
4 
5 //#include "platform_peripheral.h"
6 
7 #include "aos/hal/flash.h"
8 #include "board.h"
9 #include "flash_api.h"
10 #include "hal_platform.h"
11 
12 #define SPI_FLASH_SEC_SIZE  4096    /**< SPI Flash sector size */
13 
14 #define ROUND_DOWN(a,b) (((a) / (b)) * (b))
15 
16 flash_t flash_obj;
17 
18 extern const hal_logic_partition_t hal_partitions[];
19 extern size_t hal_partitions_amount;
20 
hal_flash_get_info(hal_partition_t in_partition)21 hal_logic_partition_t *hal_flash_get_info(hal_partition_t in_partition)
22 {
23     hal_logic_partition_t *logic_partition;
24 
25     logic_partition = (hal_logic_partition_t *)&hal_partitions[ in_partition ];
26 
27     return logic_partition;
28 }
29 
hal_flash_erase(hal_partition_t in_partition,uint32_t off_set,uint32_t size)30 int32_t hal_flash_erase(hal_partition_t in_partition, uint32_t off_set, uint32_t size)
31 {
32     uint32_t addr;
33     uint32_t start_addr, end_addr;
34     int32_t ret = 0;
35     hal_logic_partition_t *partition_info;
36 
37     partition_info = hal_flash_get_info( in_partition );
38 
39     if(size + off_set > partition_info->partition_length){
40         DBG_8195A("\r\n hal_flash_erase err, partition %d, part_len 0x%x, offset 0x%x, size 0x%x\r\n", in_partition, partition_info->partition_length, off_set, size);
41         return -1;
42       }
43 
44     start_addr = ROUND_DOWN((partition_info->partition_start_addr + off_set), SPI_FLASH_SEC_SIZE);
45     end_addr = ROUND_DOWN((partition_info->partition_start_addr + off_set + size - 1), SPI_FLASH_SEC_SIZE);
46 
47     for (addr = start_addr; addr <= end_addr; addr += SPI_FLASH_SEC_SIZE) {
48         flash_erase_sector(&flash_obj, addr);
49     }
50 
51     return 0;
52 }
53 
hal_flash_write(hal_partition_t in_partition,uint32_t * off_set,const void * in_buf,uint32_t in_buf_len)54 int32_t hal_flash_write(hal_partition_t in_partition, uint32_t *off_set, const void *in_buf , uint32_t in_buf_len)
55 {
56     uint32_t addr;
57     uint32_t start_addr, end_addr;
58     int32_t ret = 0;
59     hal_logic_partition_t *partition_info;
60 
61     partition_info = hal_flash_get_info( in_partition );
62     if(off_set == NULL || in_buf == NULL || *off_set + in_buf_len > partition_info->partition_length){
63         DBG_8195A("\r\n hal_flash_write err, partition %d, part_len 0x%x, offset 0x%x, size 0x%x\r\n", in_partition, partition_info->partition_length, off_set, in_buf_len);
64         return -1;
65     }
66     start_addr = partition_info->partition_start_addr + *off_set;
67     ret = flash_stream_write(&flash_obj, start_addr, in_buf_len, (uint8_t *)in_buf);
68 
69     *off_set += in_buf_len;
70     return 0;
71 }
72 
hal_flash_read(hal_partition_t in_partition,uint32_t * off_set,void * out_buf,uint32_t out_buf_len)73 int32_t hal_flash_read(hal_partition_t in_partition, uint32_t *off_set, void *out_buf, uint32_t out_buf_len)
74 {
75     int32_t ret = 0;
76     uint32_t start_addr;
77     hal_logic_partition_t *partition_info;
78 
79     partition_info = hal_flash_get_info( in_partition );
80 
81     if(off_set == NULL || out_buf == NULL || *off_set + out_buf_len > partition_info->partition_length){
82         return -1;
83         DBG_8195A("\r\n hal_flash_read err, partition %d, part_len 0x%x, offset 0x%x, size 0x%x\r\n", in_partition, partition_info->partition_length, off_set, out_buf_len);
84     }
85 
86     start_addr = partition_info->partition_start_addr + *off_set;
87     flash_stream_read(&flash_obj, start_addr, out_buf_len, out_buf);
88 
89     *off_set += out_buf_len;
90 
91     return ret;
92 
93 }
94 
hal_flash_enable_secure(hal_partition_t in_partition,uint32_t off_set,uint32_t size)95 int32_t hal_flash_enable_secure(hal_partition_t in_partition, uint32_t off_set, uint32_t size)
96 {
97     return 0;
98 }
99 
hal_flash_dis_secure(hal_partition_t in_partition,uint32_t off_set,uint32_t size)100 int32_t hal_flash_dis_secure(hal_partition_t in_partition, uint32_t off_set, uint32_t size)
101 {
102     return 0;
103 }
104 
hal_flash_addr2offset(hal_partition_t * in_partition,uint32_t * off_set,uint32_t addr)105 int32_t hal_flash_addr2offset(hal_partition_t *in_partition, uint32_t *off_set, uint32_t addr)
106 {
107     int32_t i;
108     uint32_t logic_addr, start_addr, end_addr;
109     hal_logic_partition_t *partition_info;
110 
111     if (addr < SPI_FLASH_BASE) {
112         return -1;
113     }
114 
115     logic_addr = addr - SPI_FLASH_BASE;
116 
117     for (i = 0; i < hal_partitions_amount; i++) {
118         partition_info = hal_flash_get_info(i);
119         start_addr = partition_info->partition_start_addr;
120         end_addr = start_addr + partition_info->partition_length;
121 
122         if ((logic_addr >= start_addr) && (logic_addr < end_addr)) {
123             *in_partition = i;
124             *off_set = logic_addr - start_addr;
125             return 0;
126         }
127     }
128 
129     return -1;
130 }
131 
hal_flash_info_get(hal_partition_t in_partition,hal_logic_partition_t * partition)132 int32_t hal_flash_info_get(hal_partition_t in_partition, hal_logic_partition_t *partition)
133 {
134     return -1;
135 }