1 /*******************************************************************************
\r
2 * (c) Copyright 2012 Microsemi SoC Products Group. All rights reserved.
\r
4 * SmartFusion2 system services.
\r
6 * SVN $Revision: 5615 $
\r
7 * SVN $Date: 2013-04-05 14:48:10 +0100 (Fri, 05 Apr 2013) $
\r
9 #include "mss_sys_services.h"
\r
10 #include "mss_comblk.h"
\r
11 #include "../../CMSIS/mss_assert.h"
\r
14 /*==============================================================================
\r
18 * Service request command opcodes:
\r
20 #define DEVICE_CERTIFICATE_REQUEST_CMD 0u
\r
21 #define SERIAL_NUMBER_REQUEST_CMD 1u
\r
22 #define FLASH_FREEZE_REQUEST_CMD 2u
\r
23 #define AES128_REQUEST_CMD 3u
\r
24 #define USERCODE_REQUEST_CMD 4u
\r
25 #define DESIGNVER_REQUEST_CMD 5u
\r
26 #define AES256_REQUEST_CMD 6u
\r
27 #define KEYTREE_REQUEST_CMD 9u
\r
28 #define SHA256_REQUEST_CMD 10u
\r
29 #define HMAC_REQUEST_CMD 12u
\r
30 #define PPUF_CHALLENGE_RESP_REQUEST_CMD 14u
\r
31 #define ISP_PROGRAMMING_REQUEST_CMD 21u
\r
32 #define DIGEST_CHECK_REQUEST_CMD 23u
\r
33 #define NRBG_SELF_TEST_REQUEST_CMD 40u
\r
34 #define NRBG_INSTANTIATE_REQUEST_CMD 41u
\r
35 #define NRBG_GENERATE_REQUEST_CMD 42u
\r
36 #define NRBG_RESEED_REQUEST_CMD 43u
\r
37 #define NRBG_UNINSTANTIATE_REQUEST_CMD 44u
\r
38 #define NRBG_RESET_REQUEST_CMD 45u
\r
39 #define FLASHFREEZE_SHUTDOWN_CMD 224u
\r
40 #define ZEROIZATION_REQUEST_CMD 240u
\r
42 #define POWER_ON_RESET_DIGEST_ERROR_CMD 241u
\r
45 * System Services requests length:
\r
47 #define FLASH_FREEZE_REQUEST_LENGTH 2u
\r
50 * Service response lengths:
\r
52 #define STANDARD_SERV_RESP_LENGTH 6u
\r
54 #define SERIAL_NUMBER_SERV_RESP_LENGTH 6u
\r
55 #define USERCODE_SERV_RESP_LENGTH 6u
\r
56 #define DESIGNVER_SERV_RESP_LENGTH 6u
\r
57 #define DEVICE_CERT_SERV_RESP_LENGTH 6u
\r
58 #define ISP_PROG_SERV_RESP_LENGTH 2u
\r
59 #define NRBG_RESET_SERV_RESP_LENGTH 2u
\r
60 #define NRBG_SELF_TEST_SERV_RESP_LENGTH 2u
\r
61 #define NRBG_UNINST_SERV_RESP_LENGTH 3u
\r
63 #define DIGEST_CHECK_SERV_RESP_LENGTH 2u
\r
64 #define FLASH_FREEZE_SERV_RESP_LENGTH 2u
\r
67 * Non Deterministic Random Bit Generator defines:
\r
69 #define INVALID_NRBG_HANDLE 0xFFu
\r
72 * RTC_WAKEUP_CR system register bit masks:
\r
74 #define RTC_WAKEUP_G4C_EN_MASK 0x00000004u
\r
75 #define RTC_WAKEUP_FAB_EN_MASK 0x00000002u
\r
77 /*==============================================================================
\r
80 static void request_completion_handler(uint8_t * p_response, uint16_t response_size);
\r
81 static void signal_request_start(void);
\r
82 static uint16_t wait_for_request_completion(void);
\r
83 static uint8_t execute_service
\r
86 uint8_t * cmd_params_ptr,
\r
88 uint16_t response_length
\r
91 static void asynchronous_event_handler(uint8_t event_opcode);
\r
93 static void write_ptr_value_into_array
\r
95 const uint8_t * pointer,
\r
96 uint8_t target_array[],
\r
97 uint32_t array_index
\r
100 /*==============================================================================
\r
103 static volatile uint8_t g_request_in_progress = 0u;
\r
104 static volatile uint16_t g_last_response_length = 0u;
\r
105 static sys_serv_async_event_handler_t g_event_handler = 0;
\r
107 /*==============================================================================
\r
110 void MSS_SYS_init(sys_serv_async_event_handler_t event_handler)
\r
112 MSS_COMBLK_init(asynchronous_event_handler);
\r
114 g_event_handler = event_handler;
\r
116 g_request_in_progress = 0u;
\r
117 g_last_response_length = 0u;
\r
120 /*==============================================================================
\r
123 static void asynchronous_event_handler(uint8_t event_opcode)
\r
125 if(g_event_handler != 0)
\r
127 switch(event_opcode)
\r
129 case FLASH_FREEZE_SHUTDOWN_OPCODE:
\r
130 case FLASH_FREEZE_EXIT_OPCODE:
\r
131 g_event_handler(event_opcode);
\r
135 /* Ignore all other events. */
\r
141 /*==============================================================================
\r
142 * See mss_sys_services.h for details.
\r
144 uint8_t MSS_SYS_get_serial_number
\r
146 uint8_t * p_serial_number
\r
149 uint8_t response[SERIAL_NUMBER_SERV_RESP_LENGTH];
\r
152 status = execute_service(SERIAL_NUMBER_REQUEST_CMD,
\r
155 SERIAL_NUMBER_SERV_RESP_LENGTH);
\r
160 /*==============================================================================
\r
161 * See mss_sys_services.h for details.
\r
163 uint8_t MSS_SYS_get_user_code
\r
165 uint8_t * p_user_code
\r
168 uint8_t response[USERCODE_SERV_RESP_LENGTH];
\r
171 status = execute_service(USERCODE_REQUEST_CMD,
\r
174 USERCODE_SERV_RESP_LENGTH);
\r
179 /*==============================================================================
\r
180 * See mss_sys_services.h for details.
\r
182 uint8_t MSS_SYS_get_design_version
\r
184 uint8_t * p_design_version
\r
187 uint8_t response[DESIGNVER_SERV_RESP_LENGTH];
\r
190 status = execute_service(DESIGNVER_REQUEST_CMD,
\r
193 DESIGNVER_SERV_RESP_LENGTH);
\r
198 /*==============================================================================
\r
199 * See mss_sys_services.h for details.
\r
201 uint8_t MSS_SYS_get_device_certificate
\r
203 uint8_t * p_device_certificate
\r
206 uint8_t response[DEVICE_CERT_SERV_RESP_LENGTH];
\r
209 status = execute_service(DEVICE_CERTIFICATE_REQUEST_CMD,
\r
210 p_device_certificate,
\r
212 DEVICE_CERT_SERV_RESP_LENGTH);
\r
217 /*==============================================================================
\r
218 * See mss_sys_services.h for details.
\r
220 uint8_t MSS_SYS_flash_freeze(uint8_t options)
\r
223 uint16_t actual_response_length;
\r
224 uint8_t flash_freeze_req[FLASH_FREEZE_REQUEST_LENGTH];
\r
225 uint8_t response[FLASH_FREEZE_SERV_RESP_LENGTH];
\r
228 * The Flash Freeze system service is not available on M2S050 rev A and rev B.
\r
230 ASSERT(0x0000F802u != SYSREG->DEVICE_VERSION);
\r
231 ASSERT(0x0001F802u != SYSREG->DEVICE_VERSION);
\r
234 * Enable RTC wake-up interrupt to System Controller and FPGA fabric.
\r
236 SYSREG->RTC_WAKEUP_CR |= (RTC_WAKEUP_G4C_EN_MASK | RTC_WAKEUP_FAB_EN_MASK);
\r
238 signal_request_start();
\r
240 flash_freeze_req[0] = FLASH_FREEZE_REQUEST_CMD;
\r
241 flash_freeze_req[1] = options;
\r
243 MSS_COMBLK_send_cmd(flash_freeze_req, /* p_cmd */
\r
244 FLASH_FREEZE_REQUEST_LENGTH, /* cmd_size */
\r
246 0u, /* data_size */
\r
247 response, /* p_response */
\r
248 FLASH_FREEZE_SERV_RESP_LENGTH, /* response_size */
\r
249 request_completion_handler); /* completion_handler */
\r
251 actual_response_length = wait_for_request_completion();
\r
253 if((FLASH_FREEZE_SERV_RESP_LENGTH == actual_response_length) &&
\r
254 (FLASH_FREEZE_REQUEST_CMD == response[0]))
\r
256 status = response[1];
\r
260 status = MSS_SYS_UNEXPECTED_ERROR;
\r
266 /*==============================================================================
\r
267 * See mss_sys_services.h for details.
\r
269 #define AES128_KEY_LENGTH 16u
\r
270 #define IV_LENGTH 16u
\r
272 #define AES256_KEY_LENGTH 32u
\r
274 #define HMAC_KEY_LENGTH 32u
\r
276 uint8_t MSS_SYS_128bit_aes
\r
278 const uint8_t * key,
\r
279 const uint8_t * iv,
\r
280 uint16_t nb_blocks,
\r
282 uint8_t * dest_addr,
\r
283 const uint8_t * src_addr)
\r
285 uint8_t response[STANDARD_SERV_RESP_LENGTH];
\r
286 uint8_t params[44];
\r
289 memcpy(¶ms[0], key, AES128_KEY_LENGTH);
\r
290 memcpy(¶ms[16], iv, IV_LENGTH);
\r
292 params[32] = (uint8_t)nb_blocks;
\r
293 params[33] = (uint8_t)(nb_blocks >> 8u);
\r
297 write_ptr_value_into_array(dest_addr, params, 36u);
\r
298 write_ptr_value_into_array(src_addr, params, 40u);
\r
300 params[36] = (uint8_t)((uint32_t)dest_addr);
\r
301 params[37] = (uint8_t)((uint32_t)dest_addr >> 8u);
\r
302 params[38] = (uint8_t)((uint32_t)dest_addr >> 16u);
\r
303 params[39] = (uint8_t)((uint32_t)dest_addr >> 24u);
\r
305 params[40] = (uint8_t)((uint32_t)src_addr);
\r
306 params[41] = (uint8_t)((uint32_t)src_addr >> 8u);
\r
307 params[42] = (uint8_t)((uint32_t)src_addr >> 16u);
\r
308 params[43] = (uint8_t)((uint32_t)src_addr >> 24u);
\r
310 status = execute_service(AES128_REQUEST_CMD,
\r
313 STANDARD_SERV_RESP_LENGTH);
\r
318 /*==============================================================================
\r
319 * See mss_sys_services.h for details.
\r
321 uint8_t MSS_SYS_256bit_aes
\r
323 const uint8_t * key,
\r
324 const uint8_t * iv,
\r
325 uint16_t nb_blocks,
\r
327 uint8_t * dest_addr,
\r
328 const uint8_t * src_addr
\r
331 uint8_t response[STANDARD_SERV_RESP_LENGTH];
\r
332 uint8_t params[60];
\r
335 memcpy(¶ms[0], key, AES256_KEY_LENGTH);
\r
336 memcpy(¶ms[32], iv, IV_LENGTH);
\r
338 params[48] = (uint8_t)nb_blocks;
\r
339 params[49] = (uint8_t)(nb_blocks >> 8u);
\r
343 write_ptr_value_into_array(dest_addr, params, 52u);
\r
344 write_ptr_value_into_array(src_addr, params, 56u);
\r
346 params[52] = (uint8_t)((uint32_t)dest_addr);
\r
347 params[53] = (uint8_t)((uint32_t)dest_addr >> 8u);
\r
348 params[54] = (uint8_t)((uint32_t)dest_addr >> 16u);
\r
349 params[55] = (uint8_t)((uint32_t)dest_addr >> 24u);
\r
351 params[56] = (uint8_t)((uint32_t)src_addr);
\r
352 params[57] = (uint8_t)((uint32_t)src_addr >> 8u);
\r
353 params[58] = (uint8_t)((uint32_t)src_addr >> 16u);
\r
354 params[59] = (uint8_t)((uint32_t)src_addr >> 24u);
\r
356 status = execute_service(AES256_REQUEST_CMD,
\r
359 STANDARD_SERV_RESP_LENGTH);
\r
364 /*==============================================================================
\r
365 * See mss_sys_services.h for details.
\r
367 uint8_t MSS_SYS_sha256
\r
369 const uint8_t * p_data_in,
\r
374 uint8_t response[STANDARD_SERV_RESP_LENGTH];
\r
375 uint8_t params[12];
\r
378 params[0] = (uint8_t)((uint32_t)length);
\r
379 params[1] = (uint8_t)((uint32_t)length >> 8u);
\r
380 params[2] = (uint8_t)((uint32_t)length >> 16u);
\r
381 params[3] = (uint8_t)((uint32_t)length >> 24u);
\r
384 write_ptr_value_into_array(result, params, 4u);
\r
385 write_ptr_value_into_array(p_data_in, params, 8u);
\r
387 params[4] = (uint8_t)((uint32_t)result);
\r
388 params[5] = (uint8_t)((uint32_t)result >> 8u);
\r
389 params[6] = (uint8_t)((uint32_t)result >> 16u);
\r
390 params[7] = (uint8_t)((uint32_t)result >> 24u);
\r
392 params[8] = (uint8_t)((uint32_t)p_data_in);
\r
393 params[9] = (uint8_t)((uint32_t)p_data_in >> 8u);
\r
394 params[10] = (uint8_t)((uint32_t)p_data_in >> 16u);
\r
395 params[11] = (uint8_t)((uint32_t)p_data_in >> 24u);
\r
397 status = execute_service(SHA256_REQUEST_CMD,
\r
400 STANDARD_SERV_RESP_LENGTH);
\r
405 /*==============================================================================
\r
406 * See mss_sys_services.h for details.
\r
408 uint8_t MSS_SYS_hmac
\r
410 const uint8_t * key,
\r
411 const uint8_t * p_data_in,
\r
416 uint8_t response[STANDARD_SERV_RESP_LENGTH];
\r
417 uint8_t params[58];
\r
420 memcpy(¶ms[0], key, HMAC_KEY_LENGTH);
\r
422 params[32] = (uint8_t)((uint32_t)length);
\r
423 params[33] = (uint8_t)((uint32_t)length >> 8u);
\r
424 params[34] = (uint8_t)((uint32_t)length >> 16u);
\r
425 params[35] = (uint8_t)((uint32_t)length >> 24u);
\r
427 write_ptr_value_into_array(p_data_in, params, 36u);
\r
428 write_ptr_value_into_array(p_result, params, 40u);
\r
430 params[36] = (uint8_t)((uint32_t)p_data_in);
\r
431 params[37] = (uint8_t)((uint32_t)p_data_in >> 8u);
\r
432 params[38] = (uint8_t)((uint32_t)p_data_in >> 16u);
\r
433 params[39] = (uint8_t)((uint32_t)p_data_in >> 24u);
\r
435 params[40] = (uint8_t)((uint32_t)p_result);
\r
436 params[41] = (uint8_t)((uint32_t)p_result >> 8u);
\r
437 params[42] = (uint8_t)((uint32_t)p_result >> 16u);
\r
438 params[43] = (uint8_t)((uint32_t)p_result >> 24u);
\r
440 status = execute_service(HMAC_REQUEST_CMD,
\r
443 STANDARD_SERV_RESP_LENGTH);
\r
448 /*==============================================================================
\r
449 * See mss_sys_services.h for details.
\r
451 uint8_t MSS_SYS_nrbg_self_test(void)
\r
454 uint16_t actual_response_length;
\r
456 uint8_t response[NRBG_SELF_TEST_SERV_RESP_LENGTH];
\r
458 signal_request_start();
\r
460 self_test = NRBG_SELF_TEST_REQUEST_CMD;
\r
462 MSS_COMBLK_send_cmd(&self_test, /* p_cmd */
\r
463 sizeof(self_test), /* cmd_size */
\r
466 response, /* p_response */
\r
467 NRBG_SELF_TEST_SERV_RESP_LENGTH, /* response_size */
\r
468 request_completion_handler); /* completion_handler */
\r
470 actual_response_length = wait_for_request_completion();
\r
472 if((NRBG_SELF_TEST_SERV_RESP_LENGTH == actual_response_length) &&
\r
473 (NRBG_SELF_TEST_REQUEST_CMD == response[0]))
\r
475 status = response[1];
\r
479 status = MSS_SYS_UNEXPECTED_ERROR;
\r
485 /*==============================================================================
\r
486 * See mss_sys_services.h for details.
\r
488 uint8_t MSS_SYS_nrbg_instantiate
\r
490 const uint8_t * personalization_str,
\r
491 uint16_t personalization_str_length,
\r
492 uint8_t * p_nrbg_handle
\r
495 uint8_t response[STANDARD_SERV_RESP_LENGTH];
\r
496 uint8_t intantiate_params[7];
\r
499 write_ptr_value_into_array(personalization_str, intantiate_params, 0u);
\r
501 intantiate_params[0] = (uint8_t)((uint32_t)personalization_str);
\r
502 intantiate_params[1] = (uint8_t)((uint32_t)personalization_str >> 8u);
\r
503 intantiate_params[2] = (uint8_t)((uint32_t)personalization_str >> 16u);
\r
504 intantiate_params[3] = (uint8_t)((uint32_t)personalization_str >> 24u);
\r
506 intantiate_params[4] = (uint8_t)personalization_str_length;
\r
507 intantiate_params[5] = (uint8_t)(personalization_str_length >> 8u);
\r
508 intantiate_params[6] = INVALID_NRBG_HANDLE;
\r
510 status = execute_service(NRBG_INSTANTIATE_REQUEST_CMD,
\r
513 STANDARD_SERV_RESP_LENGTH);
\r
515 if(MSS_SYS_SUCCESS == status)
\r
517 *p_nrbg_handle = intantiate_params[6];
\r
523 /*==============================================================================
\r
524 * See mss_sys_services.h for details.
\r
526 uint8_t MSS_SYS_nrbg_generate
\r
528 const uint8_t * p_requested_data,
\r
529 const uint8_t * p_additional_input,
\r
530 uint8_t requested_length,
\r
531 uint8_t additional_input_length,
\r
533 uint8_t nrbg_handle
\r
536 uint8_t response[STANDARD_SERV_RESP_LENGTH];
\r
537 uint8_t generate_params[12];
\r
540 write_ptr_value_into_array(p_requested_data, generate_params, 0u);
\r
541 write_ptr_value_into_array(p_additional_input, generate_params, 4u);
\r
543 generate_params[0] = (uint8_t)((uint32_t)p_requested_data);
\r
544 generate_params[1] = (uint8_t)((uint32_t)p_requested_data >> 8u);
\r
545 generate_params[2] = (uint8_t)((uint32_t)p_requested_data >> 16u);
\r
546 generate_params[3] = (uint8_t)((uint32_t)p_requested_data >> 24u);
\r
547 generate_params[4] = (uint8_t)((uint32_t)p_additional_input);
\r
548 generate_params[5] = (uint8_t)((uint32_t)p_additional_input >> 8u);
\r
549 generate_params[6] = (uint8_t)((uint32_t)p_additional_input >> 16u);
\r
550 generate_params[7] = (uint8_t)((uint32_t)p_additional_input >> 24u);
\r
552 generate_params[8] = requested_length;
\r
553 generate_params[9] = additional_input_length;
\r
554 generate_params[10] = pr_req;
\r
555 generate_params[11] = nrbg_handle;
\r
557 status = execute_service(NRBG_GENERATE_REQUEST_CMD,
\r
560 STANDARD_SERV_RESP_LENGTH);
\r
565 /*==============================================================================
\r
566 * See mss_sys_services.h for details.
\r
568 uint8_t MSS_SYS_nrbg_reseed
\r
570 const uint8_t * p_additional_input,
\r
571 uint8_t additional_input_length,
\r
572 uint8_t nrbg_handle
\r
575 uint8_t response[STANDARD_SERV_RESP_LENGTH];
\r
579 write_ptr_value_into_array(p_additional_input, params, 0u);
\r
581 params[0] = (uint8_t)((uint32_t)p_additional_input);
\r
582 params[1] = (uint8_t)((uint32_t)p_additional_input >> 8u);
\r
583 params[2] = (uint8_t)((uint32_t)p_additional_input >> 16u);
\r
584 params[3] = (uint8_t)((uint32_t)p_additional_input >> 24u);
\r
586 params[4] = (uint8_t)additional_input_length;
\r
587 params[5] = nrbg_handle;
\r
589 status = execute_service(NRBG_RESEED_REQUEST_CMD,
\r
592 STANDARD_SERV_RESP_LENGTH);
\r
597 /*==============================================================================
\r
598 * See mss_sys_services.h for details.
\r
600 uint8_t MSS_SYS_nrbg_uninstantiate
\r
602 uint8_t nrbg_handle
\r
606 uint16_t actual_response_length;
\r
607 uint8_t uninstantiate_req[2];
\r
608 uint8_t response[NRBG_UNINST_SERV_RESP_LENGTH];
\r
610 signal_request_start();
\r
612 uninstantiate_req[0] = NRBG_UNINSTANTIATE_REQUEST_CMD;
\r
613 uninstantiate_req[1] = nrbg_handle;
\r
615 MSS_COMBLK_send_cmd(uninstantiate_req, /* p_cmd */
\r
616 sizeof(uninstantiate_req), /* cmd_size */
\r
619 response, /* p_response */
\r
620 NRBG_UNINST_SERV_RESP_LENGTH, /* response_size */
\r
621 request_completion_handler); /* completion_handler */
\r
623 actual_response_length = wait_for_request_completion();
\r
625 if((NRBG_UNINST_SERV_RESP_LENGTH == actual_response_length) &&
\r
626 (NRBG_UNINSTANTIATE_REQUEST_CMD == response[0]))
\r
628 status = response[1];
\r
632 status = MSS_SYS_UNEXPECTED_ERROR;
\r
638 /*==============================================================================
\r
639 * See mss_sys_services.h for details.
\r
641 static uint8_t g_isp_response[ISP_PROG_SERV_RESP_LENGTH];
\r
642 void (*g_isp_completion_handler)(uint32_t) = 0;
\r
644 static void isp_sys_completion_handler
\r
646 uint8_t * p_response,
\r
650 if(g_isp_completion_handler != 0)
\r
652 g_isp_completion_handler(p_response[1]);
\r
656 void MSS_SYS_start_isp
\r
659 uint32_t (*page_read_handler)(uint8_t const **),
\r
660 void (*isp_completion_handler)(uint32_t)
\r
663 uint8_t isp_prog_request[2];
\r
665 signal_request_start();
\r
667 isp_prog_request[0] = ISP_PROGRAMMING_REQUEST_CMD;
\r
668 isp_prog_request[1] = mode;
\r
670 g_isp_completion_handler = isp_completion_handler;
\r
672 MSS_COMBLK_send_paged_cmd(isp_prog_request, /* p_cmd */
\r
673 sizeof(isp_prog_request), /* cmd_size */
\r
674 g_isp_response, /* p_response */
\r
675 ISP_PROG_SERV_RESP_LENGTH, /* response_size */
\r
676 page_read_handler, /* page_handler */
\r
677 isp_sys_completion_handler); /* completion_handler */
\r
680 /*==============================================================================
\r
681 * See mss_sys_services.h for details.
\r
683 uint8_t MSS_SYS_check_digest
\r
689 uint16_t actual_response_length;
\r
690 uint8_t digest_check_req[2];
\r
691 uint8_t response[DIGEST_CHECK_SERV_RESP_LENGTH];
\r
693 signal_request_start();
\r
695 digest_check_req[0] = DIGEST_CHECK_REQUEST_CMD;
\r
696 digest_check_req[1] = options;
\r
698 MSS_COMBLK_send_cmd(digest_check_req, /* p_cmd */
\r
699 sizeof(digest_check_req), /* cmd_size */
\r
701 0u, /* data_size */
\r
702 response, /* p_response */
\r
703 DIGEST_CHECK_SERV_RESP_LENGTH, /* response_size */
\r
704 request_completion_handler); /* completion_handler */
\r
706 actual_response_length = wait_for_request_completion();
\r
708 if((DIGEST_CHECK_SERV_RESP_LENGTH == actual_response_length) &&
\r
709 (DIGEST_CHECK_REQUEST_CMD == response[0]))
\r
711 status = response[1];
\r
715 status = MSS_SYS_UNEXPECTED_ERROR;
\r
721 /*==============================================================================
\r
724 static uint8_t execute_service
\r
726 uint8_t cmd_opcode,
\r
727 uint8_t * cmd_params_ptr,
\r
728 uint8_t * response,
\r
729 uint16_t response_length
\r
733 uint16_t actual_response_length;
\r
735 signal_request_start();
\r
737 MSS_COMBLK_send_cmd_with_ptr(cmd_opcode, /* cmd_opcode */
\r
738 (uint32_t)cmd_params_ptr, /* cmd_params_ptr */
\r
739 response, /* p_response */
\r
740 response_length, /* response_size */
\r
741 request_completion_handler); /* completion_handler */
\r
743 actual_response_length = wait_for_request_completion();
\r
745 if((response_length == actual_response_length) && (cmd_opcode == response[0]))
\r
747 status = response[1];
\r
751 status = MSS_SYS_UNEXPECTED_ERROR;
\r
757 /*==============================================================================
\r
760 static void request_completion_handler
\r
762 uint8_t * p_response,
\r
763 uint16_t response_size
\r
766 g_request_in_progress = 0u;
\r
767 g_last_response_length = response_size;
\r
770 /*==============================================================================
\r
773 static void signal_request_start(void)
\r
775 /* Wait for current request to complete. */
\r
776 while(g_request_in_progress)
\r
781 g_request_in_progress = 1u;
\r
782 g_last_response_length = 0u;
\r
785 /*==============================================================================
\r
788 static uint16_t wait_for_request_completion(void)
\r
790 while(g_request_in_progress)
\r
795 return g_last_response_length;
\r
798 /*==============================================================================
\r
801 static void write_ptr_value_into_array
\r
803 const uint8_t * pointer,
\r
804 uint8_t target_array[],
\r
805 uint32_t array_index
\r
808 target_array[array_index] = (uint8_t)((uint32_t)pointer);
\r
809 target_array[array_index + 1] = (uint8_t)((uint32_t)pointer >> 8u);
\r
810 target_array[array_index + 2] = (uint8_t)((uint32_t)pointer >> 16u);
\r
811 target_array[array_index + 3] = (uint8_t)((uint32_t)pointer >> 24u);
\r