From Ben Katz mbed-dev library. Removed unnecessary target files to reduce the overall size by a factor of 10 to make it easier to import into the online IDE.

Dependents:   motor_driver motor_driver_screaming_fix

Committer:
saloutos
Date:
Thu Nov 26 04:08:56 2020 +0000
Revision:
0:083111ae2a11
first commit of leaned mbed dev lib

Who changed what in which revision?

UserRevisionLine numberNew contents of line
saloutos 0:083111ae2a11 1 /* mbed Microcontroller Library
saloutos 0:083111ae2a11 2 * Copyright (c) 2017 ARM Limited
saloutos 0:083111ae2a11 3 *
saloutos 0:083111ae2a11 4 * Licensed under the Apache License, Version 2.0 (the "License");
saloutos 0:083111ae2a11 5 * you may not use this file except in compliance with the License.
saloutos 0:083111ae2a11 6 * You may obtain a copy of the License at
saloutos 0:083111ae2a11 7 *
saloutos 0:083111ae2a11 8 * http://www.apache.org/licenses/LICENSE-2.0
saloutos 0:083111ae2a11 9 *
saloutos 0:083111ae2a11 10 * Unless required by applicable law or agreed to in writing, software
saloutos 0:083111ae2a11 11 * distributed under the License is distributed on an "AS IS" BASIS,
saloutos 0:083111ae2a11 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
saloutos 0:083111ae2a11 13 * See the License for the specific language governing permissions and
saloutos 0:083111ae2a11 14 * limitations under the License.
saloutos 0:083111ae2a11 15 */
saloutos 0:083111ae2a11 16
saloutos 0:083111ae2a11 17 #include "flash_api.h"
saloutos 0:083111ae2a11 18 #include "flash_data.h"
saloutos 0:083111ae2a11 19 #include "mbed_critical.h"
saloutos 0:083111ae2a11 20
saloutos 0:083111ae2a11 21 #define MBED_FLASH_ALGO_ERASE 1UL
saloutos 0:083111ae2a11 22 #define MBED_FLASH_ALGO_PROGRAM 2UL
saloutos 0:083111ae2a11 23
saloutos 0:083111ae2a11 24 extern uint32_t SystemCoreClock;
saloutos 0:083111ae2a11 25
saloutos 0:083111ae2a11 26 /*
saloutos 0:083111ae2a11 27 This binary blob (thumb code) sets r9 (static base) as the code we are jumping to
saloutos 0:083111ae2a11 28 is PIC (position independent code).
saloutos 0:083111ae2a11 29
saloutos 0:083111ae2a11 30 These are the instructions (r0 is a pointer to arg_t):
saloutos 0:083111ae2a11 31 push {r5, lr, r4}
saloutos 0:083111ae2a11 32 mov r5, r9
saloutos 0:083111ae2a11 33 push {r5}
saloutos 0:083111ae2a11 34 ldr r5, [r0, #20]
saloutos 0:083111ae2a11 35 ldr r3, [r0, #16]
saloutos 0:083111ae2a11 36 mov r9, r3
saloutos 0:083111ae2a11 37 ldr r3, [r0, #12]
saloutos 0:083111ae2a11 38 ldr r2, [r0, #8]
saloutos 0:083111ae2a11 39 ldr r1, [r0, #4]
saloutos 0:083111ae2a11 40 ldr r0, [r0, #0]
saloutos 0:083111ae2a11 41 blx r5
saloutos 0:083111ae2a11 42 pop {r5}
saloutos 0:083111ae2a11 43 mov r9, r5
saloutos 0:083111ae2a11 44 pop {r4-r5, pc}
saloutos 0:083111ae2a11 45 bx r14
saloutos 0:083111ae2a11 46 */
saloutos 0:083111ae2a11 47 static uint32_t jump_to_flash_algo[] = {
saloutos 0:083111ae2a11 48 0x464DB530,
saloutos 0:083111ae2a11 49 0x6945B420,
saloutos 0:083111ae2a11 50 0x46996903,
saloutos 0:083111ae2a11 51 0x688268C3,
saloutos 0:083111ae2a11 52 0x68006841,
saloutos 0:083111ae2a11 53 0xBC2047A8,
saloutos 0:083111ae2a11 54 0xBD3046A9
saloutos 0:083111ae2a11 55 };
saloutos 0:083111ae2a11 56
saloutos 0:083111ae2a11 57 // should be called within critical section
saloutos 0:083111ae2a11 58 static int32_t flash_algo_init(flash_t *obj, uint32_t address, uint32_t function)
saloutos 0:083111ae2a11 59 {
saloutos 0:083111ae2a11 60 args_t arguments = {
saloutos 0:083111ae2a11 61 .r0 = address,
saloutos 0:083111ae2a11 62 .r1 = SystemCoreClock,
saloutos 0:083111ae2a11 63 .r2 = function,
saloutos 0:083111ae2a11 64 .r3 = 0,
saloutos 0:083111ae2a11 65 .r9 = (uint32_t)obj->flash_algo->algo_blob + obj->flash_algo->static_base,
saloutos 0:083111ae2a11 66 .pc = (uint32_t)obj->flash_algo->algo_blob + obj->flash_algo->init
saloutos 0:083111ae2a11 67 };
saloutos 0:083111ae2a11 68 return ((flash_algo_jump_t)(((uint32_t)&jump_to_flash_algo) | 1))(&arguments);
saloutos 0:083111ae2a11 69 }
saloutos 0:083111ae2a11 70
saloutos 0:083111ae2a11 71 // should be called within critical section
saloutos 0:083111ae2a11 72 static int32_t flash_algo_uninit(flash_t *obj, uint32_t address, uint32_t function)
saloutos 0:083111ae2a11 73 {
saloutos 0:083111ae2a11 74 args_t arguments = {
saloutos 0:083111ae2a11 75 .r0 = address,
saloutos 0:083111ae2a11 76 .r1 = SystemCoreClock,
saloutos 0:083111ae2a11 77 .r2 = function,
saloutos 0:083111ae2a11 78 .r3 = 0,
saloutos 0:083111ae2a11 79 .r9 = (uint32_t)obj->flash_algo->algo_blob + obj->flash_algo->static_base,
saloutos 0:083111ae2a11 80 .pc = (uint32_t)obj->flash_algo->algo_blob + obj->flash_algo->uninit
saloutos 0:083111ae2a11 81 };
saloutos 0:083111ae2a11 82 return ((flash_algo_jump_t)(((uint32_t)&jump_to_flash_algo) | 1))(&arguments);
saloutos 0:083111ae2a11 83 }
saloutos 0:083111ae2a11 84
saloutos 0:083111ae2a11 85
saloutos 0:083111ae2a11 86 int32_t flash_init(flash_t *obj)
saloutos 0:083111ae2a11 87 {
saloutos 0:083111ae2a11 88 flash_set_target_config(obj);
saloutos 0:083111ae2a11 89 return 0;
saloutos 0:083111ae2a11 90 }
saloutos 0:083111ae2a11 91
saloutos 0:083111ae2a11 92 int32_t flash_free(flash_t *obj)
saloutos 0:083111ae2a11 93 {
saloutos 0:083111ae2a11 94 return 0;
saloutos 0:083111ae2a11 95 }
saloutos 0:083111ae2a11 96
saloutos 0:083111ae2a11 97 int32_t flash_erase_sector(flash_t *obj, uint32_t address)
saloutos 0:083111ae2a11 98 {
saloutos 0:083111ae2a11 99 core_util_critical_section_enter();
saloutos 0:083111ae2a11 100 flash_algo_init(obj, address, MBED_FLASH_ALGO_ERASE);
saloutos 0:083111ae2a11 101
saloutos 0:083111ae2a11 102 args_t arguments = {
saloutos 0:083111ae2a11 103 .r0 = address,
saloutos 0:083111ae2a11 104 .r1 = 0,
saloutos 0:083111ae2a11 105 .r2 = 0,
saloutos 0:083111ae2a11 106 .r3 = 0,
saloutos 0:083111ae2a11 107 .r9 = (uint32_t)obj->flash_algo->algo_blob + obj->flash_algo->static_base,
saloutos 0:083111ae2a11 108 .pc = (uint32_t)obj->flash_algo->algo_blob + obj->flash_algo->erase_sector
saloutos 0:083111ae2a11 109 };
saloutos 0:083111ae2a11 110 int32_t ret = ((flash_algo_jump_t)(((uint32_t)&jump_to_flash_algo) | 1))(&arguments);
saloutos 0:083111ae2a11 111
saloutos 0:083111ae2a11 112 flash_algo_uninit(obj, address, MBED_FLASH_ALGO_ERASE);
saloutos 0:083111ae2a11 113 core_util_critical_section_exit();
saloutos 0:083111ae2a11 114 return ret ? -1 : 0;
saloutos 0:083111ae2a11 115 }
saloutos 0:083111ae2a11 116
saloutos 0:083111ae2a11 117
saloutos 0:083111ae2a11 118 int32_t flash_program_page(flash_t *obj, uint32_t address, const uint8_t *data, uint32_t size)
saloutos 0:083111ae2a11 119 {
saloutos 0:083111ae2a11 120 core_util_critical_section_enter();
saloutos 0:083111ae2a11 121 flash_algo_init(obj, address, MBED_FLASH_ALGO_PROGRAM);
saloutos 0:083111ae2a11 122
saloutos 0:083111ae2a11 123 args_t arguments = {
saloutos 0:083111ae2a11 124 .r0 = address,
saloutos 0:083111ae2a11 125 .r1 = size,
saloutos 0:083111ae2a11 126 .r2 = (uint32_t)data,
saloutos 0:083111ae2a11 127 .r3 = 0,
saloutos 0:083111ae2a11 128 .r9 = (uint32_t)obj->flash_algo->algo_blob + obj->flash_algo->static_base,
saloutos 0:083111ae2a11 129 .pc = (uint32_t)obj->flash_algo->algo_blob + obj->flash_algo->program_page
saloutos 0:083111ae2a11 130 };
saloutos 0:083111ae2a11 131 int32_t ret = ((flash_algo_jump_t)(((uint32_t)&jump_to_flash_algo) | 1))(&arguments);
saloutos 0:083111ae2a11 132
saloutos 0:083111ae2a11 133 flash_algo_uninit(obj, address, MBED_FLASH_ALGO_PROGRAM);
saloutos 0:083111ae2a11 134 core_util_critical_section_exit();
saloutos 0:083111ae2a11 135 return ret ? -1 : 0;
saloutos 0:083111ae2a11 136 }
saloutos 0:083111ae2a11 137
saloutos 0:083111ae2a11 138
saloutos 0:083111ae2a11 139 uint32_t flash_get_sector_size(const flash_t *obj, uint32_t address)
saloutos 0:083111ae2a11 140 {
saloutos 0:083111ae2a11 141 const sector_info_t *sectors = obj->target_config->sectors;
saloutos 0:083111ae2a11 142
saloutos 0:083111ae2a11 143 if (address >= obj->target_config->flash_start + obj->target_config->flash_size) {
saloutos 0:083111ae2a11 144 return MBED_FLASH_INVALID_SIZE;
saloutos 0:083111ae2a11 145 }
saloutos 0:083111ae2a11 146
saloutos 0:083111ae2a11 147 int sector_index = obj->target_config->sector_info_count - 1;
saloutos 0:083111ae2a11 148 for (; sector_index >= 0; sector_index--) {
saloutos 0:083111ae2a11 149 if (address >= sectors[sector_index].start) {
saloutos 0:083111ae2a11 150 return sectors[sector_index].size;
saloutos 0:083111ae2a11 151 }
saloutos 0:083111ae2a11 152 }
saloutos 0:083111ae2a11 153 return MBED_FLASH_INVALID_SIZE;
saloutos 0:083111ae2a11 154 }
saloutos 0:083111ae2a11 155
saloutos 0:083111ae2a11 156 uint32_t flash_get_page_size(const flash_t *obj)
saloutos 0:083111ae2a11 157 {
saloutos 0:083111ae2a11 158 return obj->target_config->page_size;
saloutos 0:083111ae2a11 159 }
saloutos 0:083111ae2a11 160
saloutos 0:083111ae2a11 161 uint32_t flash_get_start_address(const flash_t *obj)
saloutos 0:083111ae2a11 162 {
saloutos 0:083111ae2a11 163 return obj->target_config->flash_start;
saloutos 0:083111ae2a11 164 }
saloutos 0:083111ae2a11 165
saloutos 0:083111ae2a11 166 uint32_t flash_get_size(const flash_t *obj)
saloutos 0:083111ae2a11 167 {
saloutos 0:083111ae2a11 168 return obj->target_config->flash_size;
saloutos 0:083111ae2a11 169 }