@@ -374,8 +374,46 @@ where
374374 }
375375 }
376376
377- fn process_swd_sequence ( & self , _req : Request , _resp : & mut ResponseWriter ) {
378- // TODO: Needs implementing
377+ fn process_swd_sequence ( & mut self , mut req : Request , resp : & mut ResponseWriter ) {
378+ self . state . to_swd ( ) ;
379+ let swd = match & mut self . state {
380+ State :: Swd ( swd) => swd,
381+ _ => {
382+ resp. write_err ( ) ;
383+ return ;
384+ }
385+ } ;
386+
387+ resp. write_ok ( ) ; // assume ok until we finish
388+ let sequence_count = req. next_u8 ( ) ;
389+ let success = ( 0 ..sequence_count) . map ( |_| {
390+ // parse the seqnence info
391+ let sequence_info = req. next_u8 ( ) ;
392+ let nbits: usize = match sequence_info & 0x3F {
393+ // CMSIS-DAP says 0 means 64 bits
394+ 0 => 64 ,
395+ // Other integers are normal.
396+ n => n as usize ,
397+ } ;
398+ let nbytes = ( nbits + 7 ) / 8 ;
399+ let output = ( sequence_info & 0x80 ) == 0 ;
400+
401+ if output {
402+ let output_data = req. data . get ( ..nbytes) . ok_or ( ( ) ) ?;
403+ swd. write_sequence ( nbits, output_data) . or ( Err ( ( ) ) ) ?;
404+ req. consume ( nbytes) ;
405+ Ok ( 0 )
406+ } else {
407+ let input_data = resp. remaining ( ) . get_mut ( ..nbytes) . ok_or ( ( ) ) ?;
408+ swd. read_sequence ( nbits, input_data) . or ( Err ( ( ) ) ) ?;
409+ resp. skip ( nbytes) ;
410+ Ok ( nbytes)
411+ }
412+ } ) . all ( |r : Result < usize , ( ) > | r. is_ok ( ) ) ;
413+
414+ if !success {
415+ resp. write_u8_at ( 0 , 0xFF ) ;
416+ }
379417 }
380418
381419 fn process_swo_transport ( & mut self , mut req : Request , resp : & mut ResponseWriter ) {
@@ -792,3 +830,204 @@ impl<T> CheckResult<T> for swd::Result<T> {
792830 }
793831 }
794832}
833+
834+ #[ cfg( test) ]
835+ mod test {
836+ use super :: * ;
837+ use crate :: mock_device:: * ;
838+ use mockall:: predicate:: * ;
839+
840+ struct FakeLEDs { }
841+ impl DapLeds for FakeLEDs {
842+ fn react_to_host_status ( & mut self , _host_status : HostStatus ) { }
843+ }
844+
845+ struct StdDelayUs { }
846+ impl DelayNs for StdDelayUs {
847+ fn delay_ns ( & mut self , ns : u32 ) {
848+ std:: thread:: sleep ( std:: time:: Duration :: from_nanos ( ns as u64 ) ) ;
849+ }
850+ }
851+
852+ type TestDap < ' a > = Dap <
853+ ' a ,
854+ MockSwdJtagDevice ,
855+ FakeLEDs ,
856+ StdDelayUs ,
857+ MockSwdJtagDevice ,
858+ MockSwdJtagDevice ,
859+ swo:: MockSwo ,
860+ > ;
861+
862+ #[ test]
863+ fn test_swd_output_reset ( ) {
864+ let mut dap = TestDap :: new (
865+ MockSwdJtagDevice :: new ( ) ,
866+ FakeLEDs { } ,
867+ StdDelayUs { } ,
868+ None ,
869+ "test_dap" ,
870+ ) ;
871+
872+ let report = [ 0x1Du8 , 1 , 52 , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xC0 ] ;
873+ let mut rbuf = [ 0u8 ; 64 ] ;
874+ dap. state . to_swd ( ) ;
875+ match & mut dap. state {
876+ State :: Swd ( swd) => {
877+ swd. expect_write_sequence ( )
878+ . once ( )
879+ . with ( eq ( 52 ) , eq ( [ 0xFFu8 , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xC0 ] ) )
880+ . return_const ( Ok ( ( ) ) ) ;
881+ }
882+ _ => assert ! ( false , "can't switch to swd" ) ,
883+ }
884+ let rsize = dap. process_command ( & report, & mut rbuf, DapVersion :: V2 ) ;
885+ assert_eq ! ( rsize, 2 ) ;
886+ assert_eq ! ( & rbuf[ ..2 ] , & [ 0x1Du8 , 0x00 ] )
887+ }
888+
889+ #[ test]
890+ fn test_swd_output_max_size ( ) {
891+ let mut dap = TestDap :: new (
892+ MockSwdJtagDevice :: new ( ) ,
893+ FakeLEDs { } ,
894+ StdDelayUs { } ,
895+ None ,
896+ "test_dap" ,
897+ ) ;
898+
899+ let report = [ 0x1Du8 , 1 , 0 , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xC0 , 0x00 ] ;
900+ let mut rbuf = [ 0u8 ; 64 ] ;
901+ dap. state . to_swd ( ) ;
902+ match & mut dap. state {
903+ State :: Swd ( swd) => {
904+ swd. expect_write_sequence ( )
905+ . once ( )
906+ . with (
907+ eq ( 64 ) ,
908+ eq ( [ 0xFFu8 , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xC0 , 0x00 ] ) ,
909+ )
910+ . return_const ( Ok ( ( ) ) ) ;
911+ }
912+ _ => assert ! ( false , "can't switch to swd" ) ,
913+ }
914+ let rsize = dap. process_command ( & report, & mut rbuf, DapVersion :: V2 ) ;
915+ assert_eq ! ( rsize, 2 ) ;
916+ assert_eq ! ( & rbuf[ ..2 ] , & [ 0x1Du8 , 0x00 ] )
917+ }
918+
919+ #[ test]
920+ fn test_swd_input ( ) {
921+ let mut dap = TestDap :: new (
922+ MockSwdJtagDevice :: new ( ) ,
923+ FakeLEDs { } ,
924+ StdDelayUs { } ,
925+ None ,
926+ "test_dap" ,
927+ ) ;
928+
929+ let report = [ 0x1Du8 , 1 , 0x80 | 52 ] ;
930+ let mut rbuf = [ 0u8 ; 64 ] ;
931+ dap. state . to_swd ( ) ;
932+ match & mut dap. state {
933+ State :: Swd ( swd) => {
934+ swd. expect_read_sequence ( )
935+ . once ( )
936+ . withf ( |nbits, buf| buf. len ( ) >= 7 && * nbits == 52 )
937+ . returning ( |_, buf| {
938+ buf[ ..7 ] . clone_from_slice ( & [ 0xFFu8 , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xC0 ] ) ;
939+ Ok ( ( ) )
940+ } ) ;
941+ }
942+ _ => assert ! ( false , "can't switch to swd" ) ,
943+ }
944+ let rsize = dap. process_command ( & report, & mut rbuf, DapVersion :: V2 ) ;
945+ assert_eq ! ( rsize, 9 ) ;
946+ assert_eq ! (
947+ & rbuf[ ..9 ] ,
948+ & [ 0x1Du8 , 0x00 , 0xFFu8 , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xC0 ]
949+ )
950+ }
951+
952+ #[ test]
953+ fn test_swd_input_max_size ( ) {
954+ let mut dap = TestDap :: new (
955+ MockSwdJtagDevice :: new ( ) ,
956+ FakeLEDs { } ,
957+ StdDelayUs { } ,
958+ None ,
959+ "test_dap" ,
960+ ) ;
961+
962+ let report = [ 0x1Du8 , 1 , 0x80 ] ;
963+ let mut rbuf = [ 0u8 ; 64 ] ;
964+ dap. state . to_swd ( ) ;
965+ match & mut dap. state {
966+ State :: Swd ( swd) => {
967+ swd. expect_read_sequence ( )
968+ . once ( )
969+ . withf ( |nbits, buf| buf. len ( ) >= 8 && * nbits == 64 )
970+ . returning ( |_, buf| {
971+ buf[ ..8 ]
972+ . clone_from_slice ( & [ 0xFFu8 , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xC0 , 0x00 ] ) ;
973+ Ok ( ( ) )
974+ } ) ;
975+ }
976+ _ => assert ! ( false , "can't switch to swd" ) ,
977+ }
978+ let rsize = dap. process_command ( & report, & mut rbuf, DapVersion :: V2 ) ;
979+ assert_eq ! ( rsize, 10 ) ;
980+ assert_eq ! (
981+ & rbuf[ ..10 ] ,
982+ & [ 0x1Du8 , 0x00 , 0xFFu8 , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xC0 , 0x00 ]
983+ )
984+ }
985+
986+ #[ test]
987+ fn test_target_select ( ) {
988+ let mut dap = TestDap :: new (
989+ MockSwdJtagDevice :: new ( ) ,
990+ FakeLEDs { } ,
991+ StdDelayUs { } ,
992+ None ,
993+ "test_dap" ,
994+ ) ;
995+
996+ // write 8 bits, read 5 bits, write 33 bits
997+ let report = [ 0x1Du8 , 3 , 8 , 0b10111101 , 0x80 | 5 , 33 , 0x56 , 0x83 , 0xAB , 0x32 , 0x01 ] ;
998+ let mut rbuf = [ 0u8 ; 64 ] ;
999+ dap. state . to_swd ( ) ;
1000+ match & mut dap. state {
1001+ State :: Swd ( swd) => {
1002+ swd. expect_write_sequence ( )
1003+ . once ( )
1004+ . with (
1005+ eq ( 8 ) ,
1006+ eq ( [ 0b10111101u8 ] ) ,
1007+ )
1008+ . return_const ( Ok ( ( ) ) ) ;
1009+ swd. expect_read_sequence ( )
1010+ . once ( )
1011+ . withf ( |nbits, buf| buf. len ( ) >= 1 && * nbits == 5 )
1012+ . returning ( |_, buf| {
1013+ buf[ 0 ] = 0x1F ;
1014+ Ok ( ( ) )
1015+ } ) ;
1016+ swd. expect_write_sequence ( )
1017+ . once ( )
1018+ . with (
1019+ eq ( 33 ) ,
1020+ eq ( [ 0x56 , 0x83 , 0xAB , 0x32 , 0x01 ] ) ,
1021+ )
1022+ . return_const ( Ok ( ( ) ) ) ;
1023+ }
1024+ _ => assert ! ( false , "can't switch to swd" ) ,
1025+ }
1026+ let rsize = dap. process_command ( & report, & mut rbuf, DapVersion :: V2 ) ;
1027+ assert_eq ! ( rsize, 3 ) ;
1028+ assert_eq ! (
1029+ & rbuf[ ..3 ] ,
1030+ & [ 0x1Du8 , 0x00 , 0x1F ]
1031+ )
1032+ }
1033+ }
0 commit comments