| 630 | } |
| 631 | |
| 632 | uint8_t modSPIWrite(uint32_t offset, uint32_t size, const uint8_t *src) |
| 633 | { |
| 634 | uint8_t temp[512] __attribute__ ((aligned (4))); |
| 635 | uint32_t toAlign; |
| 636 | |
| 637 | if (!modSPIFlashInit()) { |
| 638 | return 0; |
| 639 | } |
| 640 | |
| 641 | if (offset & 255) { // long align offset |
| 642 | toAlign = 256 - (offset & 255); |
| 643 | c_memset(temp, 0xFF, 256); |
| 644 | c_memcpy(temp + 256 - toAlign, src, (size < toAlign) ? size : toAlign); |
| 645 | |
| 646 | uint32_t status = save_and_disable_interrupts(); |
| 647 | flash_range_program(offset & ~255, temp, 256); |
| 648 | restore_interrupts(status); |
| 649 | |
| 650 | if (size <= toAlign) { |
| 651 | return 1; |
| 652 | } |
| 653 | |
| 654 | src += toAlign; |
| 655 | offset += toAlign; |
| 656 | size -= toAlign; |
| 657 | } |
| 658 | |
| 659 | toAlign = size & ~255; |
| 660 | if (toAlign) { |
| 661 | size -= toAlign; |
| 662 | if (255 & (uintptr_t)src) { // src is not long aligned, copy through stack |
| 663 | while (toAlign) { |
| 664 | uint32_t use = (toAlign > sizeof(temp)) ? sizeof(temp) : toAlign; |
| 665 | c_memcpy(temp, src, use); |
| 666 | uint32_t status = save_and_disable_interrupts(); |
| 667 | flash_range_program(offset, temp, use); |
| 668 | restore_interrupts(status); |
| 669 | |
| 670 | toAlign -= use; |
| 671 | src += use; |
| 672 | offset += use; |
| 673 | } |
| 674 | } |
| 675 | else { |
| 676 | uint32_t status = save_and_disable_interrupts(); |
| 677 | flash_range_program(offset, src, toAlign); |
| 678 | restore_interrupts(status); |
| 679 | |
| 680 | src += toAlign; |
| 681 | offset += toAlign; |
| 682 | } |
| 683 | } |
| 684 | |
| 685 | if (size) { // long align tail |
| 686 | c_memset(temp, 0xFF, 256); |
| 687 | c_memcpy(temp, src, size); |
| 688 | uint32_t status = save_and_disable_interrupts(); |
| 689 | flash_range_program(offset, temp, 256); |
no test coverage detected