mbed-os

Dependents:   cobaLCDJoyMotor_Thread odometry_omni_3roda_v3 odometry_omni_3roda_v1 odometry_omni_3roda_v2 ... more

Committer:
be_bryan
Date:
Mon Dec 11 17:54:04 2017 +0000
Revision:
0:b74591d5ab33
motor ++

Who changed what in which revision?

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