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 }