diff options
| author | Brian Schwind <[email protected]> | 2025-10-04 13:26:11 +0900 |
|---|---|---|
| committer | Brian Schwind <[email protected]> | 2025-10-04 16:52:20 +0900 |
| commit | b0a62ddaaaa3e8d89b7af47d904365e6285f97cb (patch) | |
| tree | 2f70aef14ede7538db9e1c64b070aa009e69a1cb | |
| parent | 7e3ca6067be7e2361ccd75f9712a0d08fa7d2d6a (diff) | |
hspi: properly respect the max DMA transfer size when reading and writing
| -rw-r--r-- | embassy-stm32/src/hspi/mod.rs | 73 |
1 files changed, 41 insertions, 32 deletions
diff --git a/embassy-stm32/src/hspi/mod.rs b/embassy-stm32/src/hspi/mod.rs index b64a6b62c..59dd7ca16 100644 --- a/embassy-stm32/src/hspi/mod.rs +++ b/embassy-stm32/src/hspi/mod.rs | |||
| @@ -785,16 +785,18 @@ impl<'d, T: Instance> Hspi<'d, T, Async> { | |||
| 785 | T::REGS.ar().write(|v| v.set_address(current_address)); | 785 | T::REGS.ar().write(|v| v.set_address(current_address)); |
| 786 | } | 786 | } |
| 787 | 787 | ||
| 788 | let transfer = unsafe { | 788 | for chunk in buf.chunks_mut(0xFFFF / W::size().bytes()) { |
| 789 | self.dma | 789 | let transfer = unsafe { |
| 790 | .as_mut() | 790 | self.dma |
| 791 | .unwrap() | 791 | .as_mut() |
| 792 | .read(T::REGS.dr().as_ptr() as *mut W, buf, Default::default()) | 792 | .unwrap() |
| 793 | }; | 793 | .read(T::REGS.dr().as_ptr() as *mut W, chunk, Default::default()) |
| 794 | }; | ||
| 794 | 795 | ||
| 795 | T::REGS.cr().modify(|w| w.set_dmaen(true)); | 796 | T::REGS.cr().modify(|w| w.set_dmaen(true)); |
| 796 | 797 | ||
| 797 | transfer.blocking_wait(); | 798 | transfer.blocking_wait(); |
| 799 | } | ||
| 798 | 800 | ||
| 799 | finish_dma(T::REGS); | 801 | finish_dma(T::REGS); |
| 800 | 802 | ||
| @@ -816,16 +818,18 @@ impl<'d, T: Instance> Hspi<'d, T, Async> { | |||
| 816 | .cr() | 818 | .cr() |
| 817 | .modify(|v| v.set_fmode(FunctionalMode::IndirectWrite.into())); | 819 | .modify(|v| v.set_fmode(FunctionalMode::IndirectWrite.into())); |
| 818 | 820 | ||
| 819 | let transfer = unsafe { | 821 | for chunk in buf.chunks(0xFFFF / W::size().bytes()) { |
| 820 | self.dma | 822 | let transfer = unsafe { |
| 821 | .as_mut() | 823 | self.dma |
| 822 | .unwrap() | 824 | .as_mut() |
| 823 | .write(buf, T::REGS.dr().as_ptr() as *mut W, Default::default()) | 825 | .unwrap() |
| 824 | }; | 826 | .write(chunk, T::REGS.dr().as_ptr() as *mut W, Default::default()) |
| 827 | }; | ||
| 825 | 828 | ||
| 826 | T::REGS.cr().modify(|w| w.set_dmaen(true)); | 829 | T::REGS.cr().modify(|w| w.set_dmaen(true)); |
| 827 | 830 | ||
| 828 | transfer.blocking_wait(); | 831 | transfer.blocking_wait(); |
| 832 | } | ||
| 829 | 833 | ||
| 830 | finish_dma(T::REGS); | 834 | finish_dma(T::REGS); |
| 831 | 835 | ||
| @@ -857,16 +861,18 @@ impl<'d, T: Instance> Hspi<'d, T, Async> { | |||
| 857 | T::REGS.ar().write(|v| v.set_address(current_address)); | 861 | T::REGS.ar().write(|v| v.set_address(current_address)); |
| 858 | } | 862 | } |
| 859 | 863 | ||
| 860 | let transfer = unsafe { | 864 | for chunk in buf.chunks_mut(0xFFFF / W::size().bytes()) { |
| 861 | self.dma | 865 | let transfer = unsafe { |
| 862 | .as_mut() | 866 | self.dma |
| 863 | .unwrap() | 867 | .as_mut() |
| 864 | .read(T::REGS.dr().as_ptr() as *mut W, buf, Default::default()) | 868 | .unwrap() |
| 865 | }; | 869 | .read(T::REGS.dr().as_ptr() as *mut W, chunk, Default::default()) |
| 870 | }; | ||
| 866 | 871 | ||
| 867 | T::REGS.cr().modify(|w| w.set_dmaen(true)); | 872 | T::REGS.cr().modify(|w| w.set_dmaen(true)); |
| 868 | 873 | ||
| 869 | transfer.await; | 874 | transfer.await; |
| 875 | } | ||
| 870 | 876 | ||
| 871 | finish_dma(T::REGS); | 877 | finish_dma(T::REGS); |
| 872 | 878 | ||
| @@ -888,16 +894,19 @@ impl<'d, T: Instance> Hspi<'d, T, Async> { | |||
| 888 | .cr() | 894 | .cr() |
| 889 | .modify(|v| v.set_fmode(FunctionalMode::IndirectWrite.into())); | 895 | .modify(|v| v.set_fmode(FunctionalMode::IndirectWrite.into())); |
| 890 | 896 | ||
| 891 | let transfer = unsafe { | 897 | // TODO: implement this using a LinkedList DMA to offload the whole transfer off the CPU. |
| 892 | self.dma | 898 | for chunk in buf.chunks(0xFFFF / W::size().bytes()) { |
| 893 | .as_mut() | 899 | let transfer = unsafe { |
| 894 | .unwrap() | 900 | self.dma |
| 895 | .write(buf, T::REGS.dr().as_ptr() as *mut W, Default::default()) | 901 | .as_mut() |
| 896 | }; | 902 | .unwrap() |
| 903 | .write(chunk, T::REGS.dr().as_ptr() as *mut W, Default::default()) | ||
| 904 | }; | ||
| 897 | 905 | ||
| 898 | T::REGS.cr().modify(|w| w.set_dmaen(true)); | 906 | T::REGS.cr().modify(|w| w.set_dmaen(true)); |
| 899 | 907 | ||
| 900 | transfer.await; | 908 | transfer.await; |
| 909 | } | ||
| 901 | 910 | ||
| 902 | finish_dma(T::REGS); | 911 | finish_dma(T::REGS); |
| 903 | 912 | ||
