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 "mbed_critical.h"
be_bryan 0:b74591d5ab33 19
be_bryan 0:b74591d5ab33 20 #if DEVICE_FLASH
be_bryan 0:b74591d5ab33 21 #include "mbed_assert.h"
be_bryan 0:b74591d5ab33 22 #include "cmsis.h"
be_bryan 0:b74591d5ab33 23
be_bryan 0:b74591d5ab33 24 /* L1 targets embed 16 pages sectors */
be_bryan 0:b74591d5ab33 25 #define NUM_PAGES_IN_SECTOR 16
be_bryan 0:b74591d5ab33 26
be_bryan 0:b74591d5ab33 27 int32_t flash_init(flash_t *obj)
be_bryan 0:b74591d5ab33 28 {
be_bryan 0:b74591d5ab33 29 return 0;
be_bryan 0:b74591d5ab33 30 }
be_bryan 0:b74591d5ab33 31
be_bryan 0:b74591d5ab33 32 int32_t flash_free(flash_t *obj)
be_bryan 0:b74591d5ab33 33 {
be_bryan 0:b74591d5ab33 34 return 0;
be_bryan 0:b74591d5ab33 35 }
be_bryan 0:b74591d5ab33 36
be_bryan 0:b74591d5ab33 37 static int32_t flash_unlock(void)
be_bryan 0:b74591d5ab33 38 {
be_bryan 0:b74591d5ab33 39 /* Allow Access to Flash control registers and user Falsh */
be_bryan 0:b74591d5ab33 40 if (HAL_FLASH_Unlock()) {
be_bryan 0:b74591d5ab33 41 return -1;
be_bryan 0:b74591d5ab33 42 } else {
be_bryan 0:b74591d5ab33 43 return 0;
be_bryan 0:b74591d5ab33 44 }
be_bryan 0:b74591d5ab33 45 }
be_bryan 0:b74591d5ab33 46
be_bryan 0:b74591d5ab33 47 static int32_t flash_lock(void)
be_bryan 0:b74591d5ab33 48 {
be_bryan 0:b74591d5ab33 49 /* Disable the Flash option control register access (recommended to protect
be_bryan 0:b74591d5ab33 50 the option Bytes against possible unwanted operations) */
be_bryan 0:b74591d5ab33 51 if (HAL_FLASH_Lock()) {
be_bryan 0:b74591d5ab33 52 return -1;
be_bryan 0:b74591d5ab33 53 } else {
be_bryan 0:b74591d5ab33 54 return 0;
be_bryan 0:b74591d5ab33 55 }
be_bryan 0:b74591d5ab33 56 }
be_bryan 0:b74591d5ab33 57
be_bryan 0:b74591d5ab33 58 int32_t flash_erase_sector(flash_t *obj, uint32_t address)
be_bryan 0:b74591d5ab33 59 {
be_bryan 0:b74591d5ab33 60 uint32_t PAGEError = 0;
be_bryan 0:b74591d5ab33 61 FLASH_EraseInitTypeDef EraseInitStruct;
be_bryan 0:b74591d5ab33 62 int32_t status = 0;
be_bryan 0:b74591d5ab33 63
be_bryan 0:b74591d5ab33 64 if ((address >= (FLASH_BASE + FLASH_SIZE)) || (address < FLASH_BASE)) {
be_bryan 0:b74591d5ab33 65
be_bryan 0:b74591d5ab33 66 return -1;
be_bryan 0:b74591d5ab33 67 }
be_bryan 0:b74591d5ab33 68
be_bryan 0:b74591d5ab33 69 if (flash_unlock() != HAL_OK) {
be_bryan 0:b74591d5ab33 70 return -1;
be_bryan 0:b74591d5ab33 71 }
be_bryan 0:b74591d5ab33 72
be_bryan 0:b74591d5ab33 73 __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERR | FLASH_FLAG_EOP | FLASH_FLAG_PGAERR | FLASH_FLAG_WRPERR);
be_bryan 0:b74591d5ab33 74 /* MBED HAL erases 1 sector at a time */
be_bryan 0:b74591d5ab33 75 /* Fill EraseInit structure*/
be_bryan 0:b74591d5ab33 76 EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;
be_bryan 0:b74591d5ab33 77 EraseInitStruct.PageAddress = address;
be_bryan 0:b74591d5ab33 78 EraseInitStruct.NbPages = NUM_PAGES_IN_SECTOR;
be_bryan 0:b74591d5ab33 79
be_bryan 0:b74591d5ab33 80 /* Note: If an erase operation in Flash memory also concerns data in the data or instruction cache,
be_bryan 0:b74591d5ab33 81 you have to make sure that these data are rewritten before they are accessed during code
be_bryan 0:b74591d5ab33 82 execution. If this cannot be done safely, it is recommended to flush the caches by setting the
be_bryan 0:b74591d5ab33 83 DCRST and ICRST bits in the FLASH_CR register. */
be_bryan 0:b74591d5ab33 84
be_bryan 0:b74591d5ab33 85 if (HAL_FLASHEx_Erase(&EraseInitStruct, &PAGEError) != HAL_OK) {
be_bryan 0:b74591d5ab33 86 status = -1;
be_bryan 0:b74591d5ab33 87 }
be_bryan 0:b74591d5ab33 88
be_bryan 0:b74591d5ab33 89 flash_lock();
be_bryan 0:b74591d5ab33 90
be_bryan 0:b74591d5ab33 91 return status;
be_bryan 0:b74591d5ab33 92
be_bryan 0:b74591d5ab33 93 }
be_bryan 0:b74591d5ab33 94
be_bryan 0:b74591d5ab33 95 int32_t flash_program_page(flash_t *obj, uint32_t address,
be_bryan 0:b74591d5ab33 96 const uint8_t *data, uint32_t size)
be_bryan 0:b74591d5ab33 97 {
be_bryan 0:b74591d5ab33 98 uint32_t StartAddress = 0;
be_bryan 0:b74591d5ab33 99 int32_t status = 0;
be_bryan 0:b74591d5ab33 100
be_bryan 0:b74591d5ab33 101 if ((address >= (FLASH_BASE + FLASH_SIZE)) || (address < FLASH_BASE)) {
be_bryan 0:b74591d5ab33 102 return -1;
be_bryan 0:b74591d5ab33 103 }
be_bryan 0:b74591d5ab33 104
be_bryan 0:b74591d5ab33 105 if ((size % 4) != 0) {
be_bryan 0:b74591d5ab33 106 /* L1 flash devices can only be programmed 32bits/4 bytes at a time */
be_bryan 0:b74591d5ab33 107 return -1;
be_bryan 0:b74591d5ab33 108 }
be_bryan 0:b74591d5ab33 109
be_bryan 0:b74591d5ab33 110 if (flash_unlock() != HAL_OK) {
be_bryan 0:b74591d5ab33 111 return -1;
be_bryan 0:b74591d5ab33 112 }
be_bryan 0:b74591d5ab33 113
be_bryan 0:b74591d5ab33 114 /* Program the user Flash area word by word */
be_bryan 0:b74591d5ab33 115 StartAddress = address;
be_bryan 0:b74591d5ab33 116
be_bryan 0:b74591d5ab33 117 /* HW needs an aligned address to program flash, which data
be_bryan 0:b74591d5ab33 118 * parameters doesn't ensure */
be_bryan 0:b74591d5ab33 119 if ((uint32_t) data % 4 != 0) {
be_bryan 0:b74591d5ab33 120 volatile uint32_t data32;
be_bryan 0:b74591d5ab33 121 while (address < (StartAddress + size) && (status == 0)) {
be_bryan 0:b74591d5ab33 122 for (uint8_t i =0; i < 4; i++) {
be_bryan 0:b74591d5ab33 123 *(((uint8_t *) &data32) + i) = *(data + i);
be_bryan 0:b74591d5ab33 124 }
be_bryan 0:b74591d5ab33 125
be_bryan 0:b74591d5ab33 126 if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, address, data32) == HAL_OK) {
be_bryan 0:b74591d5ab33 127 address = address + 4;
be_bryan 0:b74591d5ab33 128 data = data + 4;
be_bryan 0:b74591d5ab33 129 } else {
be_bryan 0:b74591d5ab33 130 status = -1;
be_bryan 0:b74591d5ab33 131 }
be_bryan 0:b74591d5ab33 132 }
be_bryan 0:b74591d5ab33 133 } else { /* case where data is aligned, so let's avoid any copy */
be_bryan 0:b74591d5ab33 134 while ((address < (StartAddress + size)) && (status == 0)) {
be_bryan 0:b74591d5ab33 135 if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, address, *((uint32_t*) data)) == HAL_OK) {
be_bryan 0:b74591d5ab33 136 address = address + 4;
be_bryan 0:b74591d5ab33 137 data = data + 4;
be_bryan 0:b74591d5ab33 138 } else {
be_bryan 0:b74591d5ab33 139 status = -1;
be_bryan 0:b74591d5ab33 140 }
be_bryan 0:b74591d5ab33 141 }
be_bryan 0:b74591d5ab33 142 }
be_bryan 0:b74591d5ab33 143
be_bryan 0:b74591d5ab33 144 flash_lock();
be_bryan 0:b74591d5ab33 145
be_bryan 0:b74591d5ab33 146 return status;
be_bryan 0:b74591d5ab33 147 }
be_bryan 0:b74591d5ab33 148
be_bryan 0:b74591d5ab33 149 uint32_t flash_get_sector_size(const flash_t *obj, uint32_t address)
be_bryan 0:b74591d5ab33 150 {
be_bryan 0:b74591d5ab33 151 if ((address >= (FLASH_BASE + FLASH_SIZE)) || (address < FLASH_BASE)) {
be_bryan 0:b74591d5ab33 152 return MBED_FLASH_INVALID_SIZE;
be_bryan 0:b74591d5ab33 153 } else {
be_bryan 0:b74591d5ab33 154 return (NUM_PAGES_IN_SECTOR * FLASH_PAGE_SIZE);
be_bryan 0:b74591d5ab33 155 }
be_bryan 0:b74591d5ab33 156 }
be_bryan 0:b74591d5ab33 157
be_bryan 0:b74591d5ab33 158 uint32_t flash_get_page_size(const flash_t *obj)
be_bryan 0:b74591d5ab33 159 {
be_bryan 0:b74591d5ab33 160 /* Page size is the minimum programable size, which 4 bytes */
be_bryan 0:b74591d5ab33 161 return 4;
be_bryan 0:b74591d5ab33 162 }
be_bryan 0:b74591d5ab33 163
be_bryan 0:b74591d5ab33 164 uint32_t flash_get_start_address(const flash_t *obj)
be_bryan 0:b74591d5ab33 165 {
be_bryan 0:b74591d5ab33 166 return FLASH_BASE;
be_bryan 0:b74591d5ab33 167 }
be_bryan 0:b74591d5ab33 168
be_bryan 0:b74591d5ab33 169 uint32_t flash_get_size(const flash_t *obj)
be_bryan 0:b74591d5ab33 170 {
be_bryan 0:b74591d5ab33 171 return FLASH_SIZE;
be_bryan 0:b74591d5ab33 172 }
be_bryan 0:b74591d5ab33 173
be_bryan 0:b74591d5ab33 174 #endif