diff options
Diffstat (limited to 'embassy-stm32/src/hspi/mod.rs')
| -rw-r--r-- | embassy-stm32/src/hspi/mod.rs | 95 |
1 files changed, 55 insertions, 40 deletions
diff --git a/embassy-stm32/src/hspi/mod.rs b/embassy-stm32/src/hspi/mod.rs index 95d9e5099..1d3560678 100644 --- a/embassy-stm32/src/hspi/mod.rs +++ b/embassy-stm32/src/hspi/mod.rs | |||
| @@ -16,7 +16,7 @@ use embassy_embedded_hal::{GetConfig, SetConfig}; | |||
| 16 | use embassy_hal_internal::{Peri, PeripheralType}; | 16 | use embassy_hal_internal::{Peri, PeripheralType}; |
| 17 | pub use enums::*; | 17 | pub use enums::*; |
| 18 | 18 | ||
| 19 | use crate::dma::{word, ChannelAndRequest}; | 19 | use crate::dma::{ChannelAndRequest, word}; |
| 20 | use crate::gpio::{AfType, AnyPin, OutputType, Pull, SealedPin as _, Speed}; | 20 | use crate::gpio::{AfType, AnyPin, OutputType, Pull, SealedPin as _, Speed}; |
| 21 | use crate::mode::{Async, Blocking, Mode as PeriMode}; | 21 | use crate::mode::{Async, Blocking, Mode as PeriMode}; |
| 22 | use crate::pac::hspi::Hspi as Regs; | 22 | use crate::pac::hspi::Hspi as Regs; |
| @@ -391,7 +391,7 @@ impl<'d, T: Instance, M: PeriMode> Hspi<'d, T, M> { | |||
| 391 | while T::REGS.sr().read().busy() {} | 391 | while T::REGS.sr().read().busy() {} |
| 392 | 392 | ||
| 393 | T::REGS.cr().modify(|w| { | 393 | T::REGS.cr().modify(|w| { |
| 394 | w.set_fmode(0.into()); | 394 | w.set_fmode(FunctionalMode::IndirectWrite.into()); |
| 395 | }); | 395 | }); |
| 396 | 396 | ||
| 397 | // Configure alternate bytes | 397 | // Configure alternate bytes |
| @@ -498,7 +498,8 @@ impl<'d, T: Instance, M: PeriMode> Hspi<'d, T, M> { | |||
| 498 | w.set_dmaen(false); | 498 | w.set_dmaen(false); |
| 499 | }); | 499 | }); |
| 500 | 500 | ||
| 501 | self.configure_command(&transaction, Some(buf.len()))?; | 501 | let transfer_size_bytes = buf.len() * W::size().bytes(); |
| 502 | self.configure_command(&transaction, Some(transfer_size_bytes))?; | ||
| 502 | 503 | ||
| 503 | let current_address = T::REGS.ar().read().address(); | 504 | let current_address = T::REGS.ar().read().address(); |
| 504 | let current_instruction = T::REGS.ir().read().instruction(); | 505 | let current_instruction = T::REGS.ir().read().instruction(); |
| @@ -537,7 +538,8 @@ impl<'d, T: Instance, M: PeriMode> Hspi<'d, T, M> { | |||
| 537 | w.set_dmaen(false); | 538 | w.set_dmaen(false); |
| 538 | }); | 539 | }); |
| 539 | 540 | ||
| 540 | self.configure_command(&transaction, Some(buf.len()))?; | 541 | let transfer_size_bytes = buf.len() * W::size().bytes(); |
| 542 | self.configure_command(&transaction, Some(transfer_size_bytes))?; | ||
| 541 | 543 | ||
| 542 | T::REGS | 544 | T::REGS |
| 543 | .cr() | 545 | .cr() |
| @@ -767,7 +769,8 @@ impl<'d, T: Instance> Hspi<'d, T, Async> { | |||
| 767 | // Wait for peripheral to be free | 769 | // Wait for peripheral to be free |
| 768 | while T::REGS.sr().read().busy() {} | 770 | while T::REGS.sr().read().busy() {} |
| 769 | 771 | ||
| 770 | self.configure_command(&transaction, Some(buf.len()))?; | 772 | let transfer_size_bytes = buf.len() * W::size().bytes(); |
| 773 | self.configure_command(&transaction, Some(transfer_size_bytes))?; | ||
| 771 | 774 | ||
| 772 | let current_address = T::REGS.ar().read().address(); | 775 | let current_address = T::REGS.ar().read().address(); |
| 773 | let current_instruction = T::REGS.ir().read().instruction(); | 776 | let current_instruction = T::REGS.ir().read().instruction(); |
| @@ -782,16 +785,18 @@ impl<'d, T: Instance> Hspi<'d, T, Async> { | |||
| 782 | T::REGS.ar().write(|v| v.set_address(current_address)); | 785 | T::REGS.ar().write(|v| v.set_address(current_address)); |
| 783 | } | 786 | } |
| 784 | 787 | ||
| 785 | let transfer = unsafe { | 788 | for chunk in buf.chunks_mut(0xFFFF / W::size().bytes()) { |
| 786 | self.dma | 789 | let transfer = unsafe { |
| 787 | .as_mut() | 790 | self.dma |
| 788 | .unwrap() | 791 | .as_mut() |
| 789 | .read(T::REGS.dr().as_ptr() as *mut W, buf, Default::default()) | 792 | .unwrap() |
| 790 | }; | 793 | .read(T::REGS.dr().as_ptr() as *mut W, chunk, Default::default()) |
| 794 | }; | ||
| 791 | 795 | ||
| 792 | T::REGS.cr().modify(|w| w.set_dmaen(true)); | 796 | T::REGS.cr().modify(|w| w.set_dmaen(true)); |
| 793 | 797 | ||
| 794 | transfer.blocking_wait(); | 798 | transfer.blocking_wait(); |
| 799 | } | ||
| 795 | 800 | ||
| 796 | finish_dma(T::REGS); | 801 | finish_dma(T::REGS); |
| 797 | 802 | ||
| @@ -807,21 +812,24 @@ impl<'d, T: Instance> Hspi<'d, T, Async> { | |||
| 807 | // Wait for peripheral to be free | 812 | // Wait for peripheral to be free |
| 808 | while T::REGS.sr().read().busy() {} | 813 | while T::REGS.sr().read().busy() {} |
| 809 | 814 | ||
| 810 | self.configure_command(&transaction, Some(buf.len()))?; | 815 | let transfer_size_bytes = buf.len() * W::size().bytes(); |
| 816 | self.configure_command(&transaction, Some(transfer_size_bytes))?; | ||
| 811 | T::REGS | 817 | T::REGS |
| 812 | .cr() | 818 | .cr() |
| 813 | .modify(|v| v.set_fmode(FunctionalMode::IndirectWrite.into())); | 819 | .modify(|v| v.set_fmode(FunctionalMode::IndirectWrite.into())); |
| 814 | 820 | ||
| 815 | let transfer = unsafe { | 821 | for chunk in buf.chunks(0xFFFF / W::size().bytes()) { |
| 816 | self.dma | 822 | let transfer = unsafe { |
| 817 | .as_mut() | 823 | self.dma |
| 818 | .unwrap() | 824 | .as_mut() |
| 819 | .write(buf, T::REGS.dr().as_ptr() as *mut W, Default::default()) | 825 | .unwrap() |
| 820 | }; | 826 | .write(chunk, T::REGS.dr().as_ptr() as *mut W, Default::default()) |
| 827 | }; | ||
| 821 | 828 | ||
| 822 | T::REGS.cr().modify(|w| w.set_dmaen(true)); | 829 | T::REGS.cr().modify(|w| w.set_dmaen(true)); |
| 823 | 830 | ||
| 824 | transfer.blocking_wait(); | 831 | transfer.blocking_wait(); |
| 832 | } | ||
| 825 | 833 | ||
| 826 | finish_dma(T::REGS); | 834 | finish_dma(T::REGS); |
| 827 | 835 | ||
| @@ -837,7 +845,8 @@ impl<'d, T: Instance> Hspi<'d, T, Async> { | |||
| 837 | // Wait for peripheral to be free | 845 | // Wait for peripheral to be free |
| 838 | while T::REGS.sr().read().busy() {} | 846 | while T::REGS.sr().read().busy() {} |
| 839 | 847 | ||
| 840 | self.configure_command(&transaction, Some(buf.len()))?; | 848 | let transfer_size_bytes = buf.len() * W::size().bytes(); |
| 849 | self.configure_command(&transaction, Some(transfer_size_bytes))?; | ||
| 841 | 850 | ||
| 842 | let current_address = T::REGS.ar().read().address(); | 851 | let current_address = T::REGS.ar().read().address(); |
| 843 | let current_instruction = T::REGS.ir().read().instruction(); | 852 | let current_instruction = T::REGS.ir().read().instruction(); |
| @@ -852,16 +861,18 @@ impl<'d, T: Instance> Hspi<'d, T, Async> { | |||
| 852 | T::REGS.ar().write(|v| v.set_address(current_address)); | 861 | T::REGS.ar().write(|v| v.set_address(current_address)); |
| 853 | } | 862 | } |
| 854 | 863 | ||
| 855 | let transfer = unsafe { | 864 | for chunk in buf.chunks_mut(0xFFFF / W::size().bytes()) { |
| 856 | self.dma | 865 | let transfer = unsafe { |
| 857 | .as_mut() | 866 | self.dma |
| 858 | .unwrap() | 867 | .as_mut() |
| 859 | .read(T::REGS.dr().as_ptr() as *mut W, buf, Default::default()) | 868 | .unwrap() |
| 860 | }; | 869 | .read(T::REGS.dr().as_ptr() as *mut W, chunk, Default::default()) |
| 870 | }; | ||
| 861 | 871 | ||
| 862 | T::REGS.cr().modify(|w| w.set_dmaen(true)); | 872 | T::REGS.cr().modify(|w| w.set_dmaen(true)); |
| 863 | 873 | ||
| 864 | transfer.await; | 874 | transfer.await; |
| 875 | } | ||
| 865 | 876 | ||
| 866 | finish_dma(T::REGS); | 877 | finish_dma(T::REGS); |
| 867 | 878 | ||
| @@ -877,21 +888,25 @@ impl<'d, T: Instance> Hspi<'d, T, Async> { | |||
| 877 | // Wait for peripheral to be free | 888 | // Wait for peripheral to be free |
| 878 | while T::REGS.sr().read().busy() {} | 889 | while T::REGS.sr().read().busy() {} |
| 879 | 890 | ||
| 880 | self.configure_command(&transaction, Some(buf.len()))?; | 891 | let transfer_size_bytes = buf.len() * W::size().bytes(); |
| 892 | self.configure_command(&transaction, Some(transfer_size_bytes))?; | ||
| 881 | T::REGS | 893 | T::REGS |
| 882 | .cr() | 894 | .cr() |
| 883 | .modify(|v| v.set_fmode(FunctionalMode::IndirectWrite.into())); | 895 | .modify(|v| v.set_fmode(FunctionalMode::IndirectWrite.into())); |
| 884 | 896 | ||
| 885 | let transfer = unsafe { | 897 | // TODO: implement this using a LinkedList DMA to offload the whole transfer off the CPU. |
| 886 | self.dma | 898 | for chunk in buf.chunks(0xFFFF / W::size().bytes()) { |
| 887 | .as_mut() | 899 | let transfer = unsafe { |
| 888 | .unwrap() | 900 | self.dma |
| 889 | .write(buf, T::REGS.dr().as_ptr() as *mut W, Default::default()) | 901 | .as_mut() |
| 890 | }; | 902 | .unwrap() |
| 903 | .write(chunk, T::REGS.dr().as_ptr() as *mut W, Default::default()) | ||
| 904 | }; | ||
| 891 | 905 | ||
| 892 | T::REGS.cr().modify(|w| w.set_dmaen(true)); | 906 | T::REGS.cr().modify(|w| w.set_dmaen(true)); |
| 893 | 907 | ||
| 894 | transfer.await; | 908 | transfer.await; |
| 909 | } | ||
| 895 | 910 | ||
| 896 | finish_dma(T::REGS); | 911 | finish_dma(T::REGS); |
| 897 | 912 | ||
