Mbed Cloud example program for workshop in W27 2018.

Dependencies:   MMA7660 LM75B

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers pal_internalFlash.c Source File

pal_internalFlash.c

00001 /*
00002  * Copyright (c) 2016 ARM Limited. All rights reserved.
00003  * SPDX-License-Identifier: Apache-2.0
00004  * Licensed under the Apache License, Version 2.0 (the License); you may
00005  * not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  * http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an AS IS BASIS, WITHOUT
00012  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 #include "pal.h"
00017 #include "pal_plat_internalFlash.h"
00018 
00019 #define BITS_ALIGNED_TO_32  0x3
00020 #define PAL_MAX_PAGE_SIZE   16
00021 
00022 PAL_PRIVATE palMutexID_t g_flashMutex = NULLPTR;
00023 
00024 
00025 size_t pal_internalFlashGetPageSize(void)
00026 {
00027     size_t ret = pal_plat_internalFlashGetPageSize();
00028     if(ret > PAL_MAX_PAGE_SIZE)
00029     {
00030         ret = PAL_MAX_PAGE_SIZE;
00031     }
00032     return ret;
00033 }
00034 
00035 size_t pal_internalFlashGetSectorSize(uint32_t address)
00036 {
00037     size_t ret = pal_plat_internalFlashGetSectorSize(address);
00038     return ret;
00039 }
00040 
00041 
00042 palStatus_t pal_internalFlashInit(void)
00043 {
00044     palStatus_t ret = PAL_SUCCESS;
00045     if(NULLPTR == g_flashMutex)
00046     {
00047         ret = pal_osMutexCreate(&g_flashMutex);
00048     }
00049 
00050     if(PAL_SUCCESS == ret)
00051     {
00052         ret = pal_plat_internalFlashInit();
00053     }
00054     return ret;
00055 }
00056 
00057 palStatus_t pal_internalFlashDeInit(void)
00058 {
00059     palStatus_t ret = PAL_SUCCESS;
00060     if(NULLPTR != g_flashMutex)
00061     {
00062         ret = pal_osMutexDelete(&g_flashMutex);
00063         g_flashMutex = NULLPTR;
00064     }
00065 
00066     if(PAL_SUCCESS == ret)
00067     {
00068         ret = pal_plat_internalFlashDeInit();
00069     }
00070     return ret;
00071 }
00072 
00073 palStatus_t pal_internalFlashWrite(const size_t size, const uint32_t address, const uint32_t * buffer)
00074 {
00075     palStatus_t ret = PAL_SUCCESS;
00076     uint32_t pageSize = 0, sectorSize = 0, alignmentLeft = 0;
00077 
00078     if (buffer == NULL)
00079     {
00080         return PAL_ERR_INTERNAL_FLASH_NULL_PTR_RECEIVED;
00081     }
00082     else if (address & BITS_ALIGNED_TO_32)
00083     {
00084         return PAL_ERR_INTERNAL_FLASH_BUFFER_ADDRESS_NOT_ALIGNED;
00085     }
00086     else if (size == 0)
00087     {
00088         return PAL_ERR_INTERNAL_FLASH_WRONG_SIZE;
00089     }
00090 
00091     pageSize = pal_internalFlashGetPageSize();
00092     sectorSize = pal_internalFlashGetSectorSize(address);
00093     if ((0 == pageSize) || (sectorSize == 0))
00094     {
00095         return PAL_ERR_INTERNAL_FLASH_FLASH_ZERO_SIZE;
00096     }
00097 
00098     if (address % pageSize)
00099     {
00100         ret =  PAL_ERR_INTERNAL_FLASH_ADDRESS_NOT_ALIGNED;
00101     }
00102     else if (((address % sectorSize) + size) > sectorSize)
00103     {
00104         ret =  PAL_ERR_INTERNAL_FLASH_CROSSING_SECTORS;
00105     }
00106     else
00107     {
00108         palStatus_t mutexRet = PAL_SUCCESS;
00109         ret = pal_osMutexWait(g_flashMutex, PAL_RTOS_WAIT_FOREVER);
00110         if (ret == PAL_SUCCESS)
00111         {
00112             alignmentLeft = size % pageSize; //Keep the leftover to be copied separately
00113             if (size > pageSize)
00114             {
00115                 ret = pal_plat_internalFlashWrite(size - alignmentLeft, address, buffer);
00116             }
00117 
00118             if ((ret == PAL_SUCCESS) && (alignmentLeft != 0))
00119             {
00120                 uint32_t * pageBuffer = (uint32_t *)malloc(pageSize);
00121                 if (pageBuffer == NULL)
00122                 {
00123                     ret = PAL_ERR_NO_MEMORY ;
00124                 }
00125                 else
00126                 {
00127                     memset(pageBuffer, 0xFF, pageSize);
00128                     memcpy(pageBuffer, (uint8_t*)buffer + (size - alignmentLeft), alignmentLeft);
00129                     ret = pal_plat_internalFlashWrite(pageSize, address + (size - alignmentLeft), pageBuffer);
00130                     free(pageBuffer);
00131                 }
00132             }
00133             mutexRet = pal_osMutexRelease(g_flashMutex);
00134             if(PAL_SUCCESS != mutexRet)
00135             {
00136                 ret = PAL_ERR_INTERNAL_FLASH_MUTEX_RELEASE_ERROR;
00137             }
00138         }
00139     }
00140     return ret;
00141 }
00142 
00143 palStatus_t pal_internalFlashRead(const size_t size, const uint32_t address, uint32_t * buffer)
00144 {
00145     palStatus_t ret = PAL_SUCCESS;
00146 
00147     if (buffer == NULL)
00148     {
00149         return PAL_ERR_INTERNAL_FLASH_NULL_PTR_RECEIVED;
00150     }
00151 
00152     if (size == 0)
00153     {
00154         return PAL_ERR_INTERNAL_FLASH_WRONG_SIZE;
00155     }
00156 
00157     ret = pal_osMutexWait(g_flashMutex, PAL_RTOS_WAIT_FOREVER);
00158     if (PAL_SUCCESS == ret)
00159     {
00160         palStatus_t mutexRet = PAL_SUCCESS;
00161         ret = pal_plat_internalFlashRead(size, address, buffer);
00162         mutexRet = pal_osMutexRelease(g_flashMutex);
00163         if(PAL_SUCCESS != mutexRet)
00164         {
00165             ret = PAL_ERR_INTERNAL_FLASH_MUTEX_RELEASE_ERROR;
00166         }
00167     }
00168 
00169     return ret;
00170 }
00171 
00172 palStatus_t pal_internalFlashErase(uint32_t address, size_t size)
00173 {
00174     palStatus_t ret = PAL_SUCCESS;
00175     if (size == 0)
00176     {
00177         return PAL_ERR_INTERNAL_FLASH_WRONG_SIZE;
00178     }
00179 
00180     if (address & 0x3)
00181     {
00182         return PAL_ERR_INTERNAL_FLASH_BUFFER_ADDRESS_NOT_ALIGNED;
00183     }
00184 
00185     ret = pal_osMutexWait(g_flashMutex, PAL_RTOS_WAIT_FOREVER);
00186     if (PAL_SUCCESS == ret)
00187     {
00188         palStatus_t mutexRet = PAL_SUCCESS;
00189         ret = pal_plat_internalFlashErase(address, size);
00190         mutexRet = pal_osMutexRelease(g_flashMutex);
00191         if(PAL_SUCCESS != mutexRet)
00192         {
00193             ret = PAL_ERR_INTERNAL_FLASH_MUTEX_RELEASE_ERROR;
00194         }
00195     }
00196     return ret;
00197 }
00198 
00199 palStatus_t pal_internalFlashGetAreaInfo(bool section, palSotpAreaData_t *data)
00200 {
00201     palStatus_t ret = PAL_SUCCESS;
00202     const palSotpAreaData_t internalFlashArea[] =
00203             {
00204                     {PAL_INTERNAL_FLASH_SECTION_1_ADDRESS, PAL_INTERNAL_FLASH_SECTION_1_SIZE},
00205                     {PAL_INTERNAL_FLASH_SECTION_2_ADDRESS, PAL_INTERNAL_FLASH_SECTION_2_SIZE}
00206             };
00207 
00208     if(data == NULL)
00209     {
00210         ret = PAL_ERR_INTERNAL_FLASH_NULL_PTR_RECEIVED;
00211     }
00212     else
00213     {
00214         data->address = internalFlashArea[section].address;
00215         data->size = internalFlashArea[section].size;
00216     }
00217 
00218     return ret;
00219 }
00220