| 729 | } |
| 730 | |
| 731 | uint8_t modSPIWrite(uint32_t offset, uint32_t size, const uint8_t *src) |
| 732 | { |
| 733 | uint8_t temp[512] __attribute__ ((aligned (4))); |
| 734 | uint32_t toAlign; |
| 735 | |
| 736 | xSemaphoreTake(gFlashMutex, portMAX_DELAY); |
| 737 | |
| 738 | if (!modSPIFlashInit()) { |
| 739 | xSemaphoreGive(gFlashMutex); |
| 740 | return 0; |
| 741 | } |
| 742 | |
| 743 | if (offset & 3) { // long align offset |
| 744 | toAlign = 4 - (offset & 3); |
| 745 | c_memset(temp, 0xFF, 4); |
| 746 | c_memcpy(temp + 4 - toAlign, src, (size < toAlign) ? size : toAlign); |
| 747 | if (NRF_SUCCESS != nrf_fstorage_write(&fstorage, offset & ~3, temp, 4, NULL)) { |
| 748 | xSemaphoreGive(gFlashMutex); |
| 749 | return 0; |
| 750 | } |
| 751 | wait_for_flash_ready(); |
| 752 | |
| 753 | if (size <= toAlign) { |
| 754 | xSemaphoreGive(gFlashMutex); |
| 755 | return 1; |
| 756 | } |
| 757 | |
| 758 | src += toAlign; |
| 759 | offset += toAlign; |
| 760 | size -= toAlign; |
| 761 | } |
| 762 | |
| 763 | toAlign = size & ~3; |
| 764 | if (toAlign) { |
| 765 | size -= toAlign; |
| 766 | if (3 & (uintptr_t)src) { // src is not long aligned, copy through stack |
| 767 | while (toAlign) { |
| 768 | uint32_t use = (toAlign > sizeof(temp)) ? sizeof(temp) : toAlign; |
| 769 | c_memcpy(temp, src, use); |
| 770 | if (NRF_SUCCESS != nrf_fstorage_write(&fstorage, offset, temp, use, NULL)) { |
| 771 | xSemaphoreGive(gFlashMutex); |
| 772 | return 0; |
| 773 | } |
| 774 | wait_for_flash_ready(); |
| 775 | |
| 776 | toAlign -= use; |
| 777 | src += use; |
| 778 | offset += use; |
| 779 | } |
| 780 | } |
| 781 | else { |
| 782 | if (NRF_SUCCESS != nrf_fstorage_write(&fstorage, offset, src, toAlign, NULL)) { |
| 783 | xSemaphoreGive(gFlashMutex); |
| 784 | return 0; |
| 785 | } |
| 786 | wait_for_flash_ready(); |
| 787 | |
| 788 | src += toAlign; |
no test coverage detected