WORKS

Dependencies:   MAX44000 PWM_Tone_Library nexpaq_mdk

Fork of LED_Demo by Maxim nexpaq

Committer:
cyberjoey
Date:
Sat Oct 22 01:31:58 2016 +0000
Revision:
9:6bb35cef007d
Parent:
1:55a6170b404f
WORKING

Who changed what in which revision?

UserRevisionLine numberNew contents of line
nexpaq 1:55a6170b404f 1 /*
nexpaq 1:55a6170b404f 2 * Copyright (c) 2016 ARM Limited. All rights reserved.
nexpaq 1:55a6170b404f 3 */
nexpaq 1:55a6170b404f 4
nexpaq 1:55a6170b404f 5 #include <string.h>
nexpaq 1:55a6170b404f 6 #include <ns_types.h>
nexpaq 1:55a6170b404f 7 #include <nsdynmemLIB.h>
nexpaq 1:55a6170b404f 8 #define HAVE_DEBUG
nexpaq 1:55a6170b404f 9 #include "ns_trace.h"
nexpaq 1:55a6170b404f 10 #include "ns_list.h"
nexpaq 1:55a6170b404f 11 #include "platform/arm_hal_nvm.h"
nexpaq 1:55a6170b404f 12 #include "ns_nvm_helper.h"
nexpaq 1:55a6170b404f 13
nexpaq 1:55a6170b404f 14 #define TRACE_GROUP "nnvm"
nexpaq 1:55a6170b404f 15
nexpaq 1:55a6170b404f 16 /* NVM operations */
nexpaq 1:55a6170b404f 17 #define NS_NVM_NONE 0x00
nexpaq 1:55a6170b404f 18 #define NS_NVM_INIT 0x01
nexpaq 1:55a6170b404f 19 #define NS_NVM_KEY_CREATE 0x02
nexpaq 1:55a6170b404f 20 #define NS_NVM_KEY_READ 0x03
nexpaq 1:55a6170b404f 21 #define NS_NVM_KEY_WRITE 0x04
nexpaq 1:55a6170b404f 22 #define NS_NVM_FLUSH 0x05
nexpaq 1:55a6170b404f 23 #define NS_NVM_KEY_DELETE 0x06
nexpaq 1:55a6170b404f 24
nexpaq 1:55a6170b404f 25 typedef struct {
nexpaq 1:55a6170b404f 26 ns_nvm_callback *callback;
nexpaq 1:55a6170b404f 27 const char *client_key_name;
nexpaq 1:55a6170b404f 28 void *client_context;
nexpaq 1:55a6170b404f 29 int operation;
nexpaq 1:55a6170b404f 30 uint8_t *buffer;
nexpaq 1:55a6170b404f 31 uint16_t *buffer_len;
nexpaq 1:55a6170b404f 32 void *original_request;
nexpaq 1:55a6170b404f 33 ns_list_link_t link;
nexpaq 1:55a6170b404f 34 } ns_nvm_request_t;
nexpaq 1:55a6170b404f 35
nexpaq 1:55a6170b404f 36 static bool ns_nvm_initialized = false;
nexpaq 1:55a6170b404f 37 static bool ns_nvm_operation_in_progress = false;
nexpaq 1:55a6170b404f 38
nexpaq 1:55a6170b404f 39 static ns_nvm_request_t *ns_nvm_create_request(ns_nvm_callback *callback, void *context, const char *key_name, uint8_t *buf, uint16_t *buf_len, uint8_t operation);
nexpaq 1:55a6170b404f 40 static int ns_nvm_operation_start(ns_nvm_request_t *request);
nexpaq 1:55a6170b404f 41 static int ns_nvm_operation_continue(ns_nvm_request_t *request, bool free_request);
nexpaq 1:55a6170b404f 42 static void ns_nvm_operation_end(ns_nvm_request_t *ns_nvm_request_ptr, int client_retval);
nexpaq 1:55a6170b404f 43
nexpaq 1:55a6170b404f 44 static NS_LIST_DEFINE(ns_nvm_request_list, ns_nvm_request_t, link);
nexpaq 1:55a6170b404f 45
nexpaq 1:55a6170b404f 46 /*
nexpaq 1:55a6170b404f 47 * Callback from platform NVM adaptation
nexpaq 1:55a6170b404f 48 */
nexpaq 1:55a6170b404f 49 void ns_nvm_callback_func(platform_nvm_status status, void *args)
nexpaq 1:55a6170b404f 50 {
nexpaq 1:55a6170b404f 51 ns_nvm_request_t *ns_nvm_request_ptr = (ns_nvm_request_t*)args;
nexpaq 1:55a6170b404f 52 int client_retval = NS_NVM_OK;
nexpaq 1:55a6170b404f 53
nexpaq 1:55a6170b404f 54 if (status == PLATFORM_NVM_ERROR) {
nexpaq 1:55a6170b404f 55 client_retval = NS_NVM_ERROR;
nexpaq 1:55a6170b404f 56 } else if (status == PLATFORM_NVM_KEY_NOT_FOUND) {
nexpaq 1:55a6170b404f 57 client_retval = NS_NVM_DATA_NOT_FOUND;
nexpaq 1:55a6170b404f 58 }
nexpaq 1:55a6170b404f 59
nexpaq 1:55a6170b404f 60 switch(ns_nvm_request_ptr->operation) {
nexpaq 1:55a6170b404f 61 case NS_NVM_INIT:
nexpaq 1:55a6170b404f 62 ns_nvm_operation_continue(ns_nvm_request_ptr->original_request, true);
nexpaq 1:55a6170b404f 63 ns_dyn_mem_free(ns_nvm_request_ptr);
nexpaq 1:55a6170b404f 64 break;
nexpaq 1:55a6170b404f 65 case NS_NVM_FLUSH:
nexpaq 1:55a6170b404f 66 case NS_NVM_KEY_READ:
nexpaq 1:55a6170b404f 67 ns_nvm_operation_end(ns_nvm_request_ptr, client_retval);
nexpaq 1:55a6170b404f 68 break;
nexpaq 1:55a6170b404f 69 case NS_NVM_KEY_CREATE:
nexpaq 1:55a6170b404f 70 if (status == PLATFORM_NVM_OK) {
nexpaq 1:55a6170b404f 71 ns_nvm_request_ptr->operation = NS_NVM_KEY_WRITE;
nexpaq 1:55a6170b404f 72 platform_nvm_write(ns_nvm_callback_func, ns_nvm_request_ptr->client_key_name, ns_nvm_request_ptr->buffer, ns_nvm_request_ptr->buffer_len, ns_nvm_request_ptr);
nexpaq 1:55a6170b404f 73 } else {
nexpaq 1:55a6170b404f 74 ns_nvm_operation_end(ns_nvm_request_ptr, client_retval);
nexpaq 1:55a6170b404f 75 }
nexpaq 1:55a6170b404f 76 break;
nexpaq 1:55a6170b404f 77 case NS_NVM_KEY_DELETE:
nexpaq 1:55a6170b404f 78 case NS_NVM_KEY_WRITE:
nexpaq 1:55a6170b404f 79 if (status == PLATFORM_NVM_OK) {
nexpaq 1:55a6170b404f 80 // write ok, flush the changes
nexpaq 1:55a6170b404f 81 ns_nvm_request_ptr->operation = NS_NVM_FLUSH;
nexpaq 1:55a6170b404f 82 platform_nvm_flush(ns_nvm_callback_func, ns_nvm_request_ptr);
nexpaq 1:55a6170b404f 83 } else {
nexpaq 1:55a6170b404f 84 // write failed, inform client
nexpaq 1:55a6170b404f 85 ns_nvm_operation_end(ns_nvm_request_ptr, client_retval);
nexpaq 1:55a6170b404f 86 }
nexpaq 1:55a6170b404f 87 break;
nexpaq 1:55a6170b404f 88 }
nexpaq 1:55a6170b404f 89 }
nexpaq 1:55a6170b404f 90
nexpaq 1:55a6170b404f 91 int ns_nvm_key_delete(ns_nvm_callback *callback, const char *key_name, void *context)
nexpaq 1:55a6170b404f 92 {
nexpaq 1:55a6170b404f 93 if (!callback || !key_name) {
nexpaq 1:55a6170b404f 94 return NS_NVM_ERROR;
nexpaq 1:55a6170b404f 95 }
nexpaq 1:55a6170b404f 96 tr_debug("ns_nvm_key_delete() key=%s, ctx=%p", key_name, context);
nexpaq 1:55a6170b404f 97 ns_nvm_request_t *ns_nvm_request_ptr = ns_nvm_create_request(callback, context, key_name, NULL, NULL, NS_NVM_KEY_DELETE);
nexpaq 1:55a6170b404f 98 return ns_nvm_operation_start(ns_nvm_request_ptr);
nexpaq 1:55a6170b404f 99 }
nexpaq 1:55a6170b404f 100
nexpaq 1:55a6170b404f 101 int ns_nvm_data_read(ns_nvm_callback *callback, const char *key_name, uint8_t *buf, uint16_t *buf_len, void *context)
nexpaq 1:55a6170b404f 102 {
nexpaq 1:55a6170b404f 103 if (!callback || !key_name || !buf || !buf_len) {
nexpaq 1:55a6170b404f 104 return NS_NVM_ERROR;
nexpaq 1:55a6170b404f 105 }
nexpaq 1:55a6170b404f 106 tr_debug("ns_nvm_data_read() key=%s, len=%d, ctx=%p", key_name, (int)*buf_len, context);
nexpaq 1:55a6170b404f 107 ns_nvm_request_t *ns_nvm_request_ptr = ns_nvm_create_request(callback, context, key_name, buf, buf_len, NS_NVM_KEY_READ);
nexpaq 1:55a6170b404f 108 return ns_nvm_operation_start(ns_nvm_request_ptr);
nexpaq 1:55a6170b404f 109 }
nexpaq 1:55a6170b404f 110
nexpaq 1:55a6170b404f 111 int ns_nvm_data_write(ns_nvm_callback *callback, const char *key_name, uint8_t *buf, uint16_t *buf_len, void *context)
nexpaq 1:55a6170b404f 112 {
nexpaq 1:55a6170b404f 113 if (!callback || !key_name || !buf || !buf_len) {
nexpaq 1:55a6170b404f 114 return NS_NVM_ERROR;
nexpaq 1:55a6170b404f 115 }
nexpaq 1:55a6170b404f 116 tr_debug("ns_nvm_data_write() key=%s, len=%d, ctx=%p", key_name, (int)*buf_len, context);
nexpaq 1:55a6170b404f 117 ns_nvm_request_t *ns_nvm_request_ptr = ns_nvm_create_request(callback, context, key_name, buf, buf_len, NS_NVM_KEY_WRITE);
nexpaq 1:55a6170b404f 118 return ns_nvm_operation_start(ns_nvm_request_ptr);
nexpaq 1:55a6170b404f 119 }
nexpaq 1:55a6170b404f 120
nexpaq 1:55a6170b404f 121 static int ns_nvm_operation_start(ns_nvm_request_t *nvm_request)
nexpaq 1:55a6170b404f 122 {
nexpaq 1:55a6170b404f 123 int ret = NS_NVM_OK;
nexpaq 1:55a6170b404f 124 platform_nvm_status pnvm_status;
nexpaq 1:55a6170b404f 125
nexpaq 1:55a6170b404f 126 if (!nvm_request) {
nexpaq 1:55a6170b404f 127 return NS_NVM_MEMORY;
nexpaq 1:55a6170b404f 128 }
nexpaq 1:55a6170b404f 129 if (ns_nvm_initialized == true) {
nexpaq 1:55a6170b404f 130 // NVM already initialized, continue directly
nexpaq 1:55a6170b404f 131 if (!ns_nvm_operation_in_progress) {
nexpaq 1:55a6170b404f 132 ret = ns_nvm_operation_continue(nvm_request, true);
nexpaq 1:55a6170b404f 133 } else {
nexpaq 1:55a6170b404f 134 // add request to list and handle when existing calls has been handled.
nexpaq 1:55a6170b404f 135 ns_list_add_to_end(&ns_nvm_request_list, nvm_request);
nexpaq 1:55a6170b404f 136 }
nexpaq 1:55a6170b404f 137 } else {
nexpaq 1:55a6170b404f 138 ns_nvm_request_t *ns_nvm_request_ptr = ns_nvm_create_request(NULL, NULL, NULL, NULL, NULL, NS_NVM_INIT);
nexpaq 1:55a6170b404f 139 if (!ns_nvm_request_ptr) {
nexpaq 1:55a6170b404f 140 ns_dyn_mem_free(nvm_request);
nexpaq 1:55a6170b404f 141 ns_dyn_mem_free(ns_nvm_request_ptr);
nexpaq 1:55a6170b404f 142 return NS_NVM_MEMORY;
nexpaq 1:55a6170b404f 143 }
nexpaq 1:55a6170b404f 144 ns_nvm_request_ptr->original_request = nvm_request;
nexpaq 1:55a6170b404f 145 pnvm_status = platform_nvm_init(ns_nvm_callback_func, ns_nvm_request_ptr);
nexpaq 1:55a6170b404f 146 if (pnvm_status != PLATFORM_NVM_OK) {
nexpaq 1:55a6170b404f 147 ns_dyn_mem_free(nvm_request);
nexpaq 1:55a6170b404f 148 ns_dyn_mem_free(ns_nvm_request_ptr);
nexpaq 1:55a6170b404f 149 return NS_NVM_ERROR;
nexpaq 1:55a6170b404f 150 }
nexpaq 1:55a6170b404f 151 ns_list_init(&ns_nvm_request_list);
nexpaq 1:55a6170b404f 152 ns_nvm_initialized = true;
nexpaq 1:55a6170b404f 153 ns_nvm_operation_in_progress = true;
nexpaq 1:55a6170b404f 154 }
nexpaq 1:55a6170b404f 155 return ret;
nexpaq 1:55a6170b404f 156 }
nexpaq 1:55a6170b404f 157
nexpaq 1:55a6170b404f 158 static ns_nvm_request_t *ns_nvm_create_request(ns_nvm_callback *callback, void *context, const char *key_name, uint8_t *buf, uint16_t *buf_len, uint8_t operation)
nexpaq 1:55a6170b404f 159 {
nexpaq 1:55a6170b404f 160 ns_nvm_request_t *ns_nvm_request_ptr = ns_dyn_mem_temporary_alloc(sizeof(ns_nvm_request_t));
nexpaq 1:55a6170b404f 161 if (!ns_nvm_request_ptr) {
nexpaq 1:55a6170b404f 162 return NULL;
nexpaq 1:55a6170b404f 163 }
nexpaq 1:55a6170b404f 164 ns_nvm_request_ptr->client_context = context;
nexpaq 1:55a6170b404f 165 ns_nvm_request_ptr->callback = callback;
nexpaq 1:55a6170b404f 166 ns_nvm_request_ptr->client_key_name = key_name;
nexpaq 1:55a6170b404f 167 ns_nvm_request_ptr->operation = operation;
nexpaq 1:55a6170b404f 168 ns_nvm_request_ptr->buffer = buf;
nexpaq 1:55a6170b404f 169 ns_nvm_request_ptr->buffer_len = buf_len;
nexpaq 1:55a6170b404f 170
nexpaq 1:55a6170b404f 171 return ns_nvm_request_ptr;
nexpaq 1:55a6170b404f 172 }
nexpaq 1:55a6170b404f 173
nexpaq 1:55a6170b404f 174 static int ns_nvm_operation_continue(ns_nvm_request_t *request, bool free_request)
nexpaq 1:55a6170b404f 175 {
nexpaq 1:55a6170b404f 176 platform_nvm_status ret = PLATFORM_NVM_OK;
nexpaq 1:55a6170b404f 177
nexpaq 1:55a6170b404f 178 ns_nvm_operation_in_progress = true;
nexpaq 1:55a6170b404f 179 switch(request->operation) {
nexpaq 1:55a6170b404f 180 case NS_NVM_KEY_WRITE:
nexpaq 1:55a6170b404f 181 request->operation = NS_NVM_KEY_CREATE;
nexpaq 1:55a6170b404f 182 ret = platform_nvm_key_create(ns_nvm_callback_func, request->client_key_name, *request->buffer_len, 0, request);
nexpaq 1:55a6170b404f 183 break;
nexpaq 1:55a6170b404f 184 case NS_NVM_KEY_READ:
nexpaq 1:55a6170b404f 185 ret = platform_nvm_read(ns_nvm_callback_func, request->client_key_name, request->buffer, request->buffer_len, request);
nexpaq 1:55a6170b404f 186 break;
nexpaq 1:55a6170b404f 187 case NS_NVM_KEY_DELETE:
nexpaq 1:55a6170b404f 188 ret = platform_nvm_key_delete(ns_nvm_callback_func, request->client_key_name, request);
nexpaq 1:55a6170b404f 189 break;
nexpaq 1:55a6170b404f 190 }
nexpaq 1:55a6170b404f 191
nexpaq 1:55a6170b404f 192 if (ret != PLATFORM_NVM_OK) {
nexpaq 1:55a6170b404f 193 if (free_request == true) {
nexpaq 1:55a6170b404f 194 // free request if requested
nexpaq 1:55a6170b404f 195 ns_dyn_mem_free(request);
nexpaq 1:55a6170b404f 196 }
nexpaq 1:55a6170b404f 197 ns_nvm_operation_in_progress = false;
nexpaq 1:55a6170b404f 198 return NS_NVM_ERROR;
nexpaq 1:55a6170b404f 199 }
nexpaq 1:55a6170b404f 200
nexpaq 1:55a6170b404f 201 return NS_NVM_OK;
nexpaq 1:55a6170b404f 202 }
nexpaq 1:55a6170b404f 203
nexpaq 1:55a6170b404f 204 static void ns_nvm_operation_end(ns_nvm_request_t *ns_nvm_request_ptr, int client_retval)
nexpaq 1:55a6170b404f 205 {
nexpaq 1:55a6170b404f 206 ns_nvm_request_ptr->callback(client_retval, ns_nvm_request_ptr->client_context);
nexpaq 1:55a6170b404f 207 ns_dyn_mem_free(ns_nvm_request_ptr);
nexpaq 1:55a6170b404f 208 ns_nvm_operation_in_progress = false;
nexpaq 1:55a6170b404f 209
nexpaq 1:55a6170b404f 210 ns_list_foreach_safe(ns_nvm_request_t, pending_req, &ns_nvm_request_list) {
nexpaq 1:55a6170b404f 211 // there are pending requests to be processed
nexpaq 1:55a6170b404f 212 ns_list_remove(&ns_nvm_request_list, pending_req);
nexpaq 1:55a6170b404f 213 int ret = ns_nvm_operation_continue(pending_req, false);
nexpaq 1:55a6170b404f 214 if (ret != NS_NVM_OK) {
nexpaq 1:55a6170b404f 215 ns_nvm_operation_end(pending_req, ret);
nexpaq 1:55a6170b404f 216 } else {
nexpaq 1:55a6170b404f 217 break;
nexpaq 1:55a6170b404f 218 }
nexpaq 1:55a6170b404f 219 }
nexpaq 1:55a6170b404f 220 }