@@ -907,6 +907,191 @@ static void cmd_cpld_read(BaseSequentialStream* chp, int argc, char* argv[]) {
907
907
}
908
908
}
909
909
910
+ static uint32_t reverse (uint32_t x) {
911
+ x = ((x >> 1 ) & 0x55555555u ) | ((x & 0x55555555u ) << 1 );
912
+ x = ((x >> 2 ) & 0x33333333u ) | ((x & 0x33333333u ) << 2 );
913
+ x = ((x >> 4 ) & 0x0f0f0f0fu ) | ((x & 0x0f0f0f0fu ) << 4 );
914
+ x = ((x >> 8 ) & 0x00ff00ffu ) | ((x & 0x00ff00ffu ) << 8 );
915
+ x = ((x >> 16 ) & 0xffffu ) | ((x & 0xffffu ) << 16 );
916
+ return x;
917
+ }
918
+
919
+ static void cmd_cpld_write (BaseSequentialStream* chp, int argc, char * argv[]) {
920
+ const char * usage =
921
+ " usage: cpld_write <device> <target> <file>\r\n "
922
+ " device can be: hackrf, portapack\r\n "
923
+ " target can be: sram (hackrf only), eeprom\r\n "
924
+ " currently only \" cpld_write portapack eeprom <file>\" is supported\r\n " ;
925
+
926
+ if (argc != 3 ) {
927
+ chprintf (chp, usage);
928
+ return ;
929
+ }
930
+
931
+ if (strncmp (argv[0 ], " hackrf" , 5 ) == 0 ) {
932
+ chprintf (chp, usage);
933
+ } else if (strncmp (argv[0 ], " portapack" , 5 ) == 0 ) {
934
+ if (strncmp (argv[1 ], " eeprom" , 5 ) == 0 ) {
935
+ jtag::GPIOTarget target{
936
+ portapack::gpio_cpld_tck,
937
+ portapack::gpio_cpld_tms,
938
+ portapack::gpio_cpld_tdi,
939
+ portapack::gpio_cpld_tdo};
940
+ jtag::JTAG jtag{target};
941
+ portapack::cpld::CPLD cpld{jtag};
942
+
943
+ cpld.reset ();
944
+ cpld.run_test_idle ();
945
+ uint32_t idcode = cpld.get_idcode ();
946
+
947
+ chprintf (chp, " CPLD IDCODE: 0x%08X\r\n " , idcode);
948
+
949
+ if (idcode == 0x00025610 ) {
950
+ chprintf (chp, " CPLD Model: AGM AG256SL100\r\n " );
951
+
952
+ if (cpld.AGM_enter_maintenance_mode () == false ) {
953
+ return ;
954
+ }
955
+
956
+ File* file = new File ();
957
+ auto path = path_from_string8 (argv[2 ]);
958
+ auto error = file->open (path);
959
+
960
+ if (error.is_valid ()) {
961
+ chprintf (chp, " Error opening file: %s %d %s\r\n " , argv[2 ], error.value ().code (), error.value ().what ().c_str ());
962
+ delete file;
963
+ cpld.AGM_exit_maintenance_mode ();
964
+ return ;
965
+ }
966
+
967
+ auto data = std::make_unique<std::array<uint32_t , 1801 >>();
968
+ uint32_t magic = 0 ;
969
+ bool magic_found = false ;
970
+ uint32_t expected_address = 0 ;
971
+
972
+ auto readData = std::vector<uint8_t >();
973
+
974
+ chprintf (chp, " Reading file...\r\n " );
975
+ file->seek (0 );
976
+
977
+ while (!file->eof ().value ()) {
978
+ uint32_t remainingData = readData.size ();
979
+ uint32_t bytesToRead = 512 - remainingData;
980
+
981
+ readData.resize (512 );
982
+
983
+ auto result = file->read (readData.data () + remainingData, bytesToRead);
984
+
985
+ if (result.is_error ()) {
986
+ chprintf (chp, " Error reading file: %d %s\r\n " , result.error ().code (), result.error ().what ().c_str ());
987
+ cpld.AGM_exit_maintenance_mode ();
988
+ file->close ();
989
+ delete file;
990
+ return ;
991
+ }
992
+
993
+ if (result.value () != 512 )
994
+ readData.resize (remainingData + result.value ());
995
+
996
+ do {
997
+ auto it = std::find (readData.begin (), readData.end (), ' \n ' );
998
+ if (it != readData.end ()) {
999
+ std::string line (readData.begin (), it);
1000
+ readData.erase (readData.begin (), it + 1 );
1001
+
1002
+ line.erase (std::remove (line.begin (), line.end (), ' \r ' ), line.end ());
1003
+ line.erase (std::remove (line.begin (), line.end (), ' \n ' ), line.end ());
1004
+
1005
+ auto prefix = line.find (" sdr 64 -tdi " , 0 );
1006
+ auto suffix = line.find (" 0040" , line.size () - 4 );
1007
+
1008
+ if (prefix == 0 && suffix == line.size () - 4 ) {
1009
+ std::string dataString = line.substr (line.size () - 16 , 16 );
1010
+
1011
+ uint32_t address = reverse (std::stoul (dataString.substr (8 , 8 ), nullptr , 16 ) - 64 ) / 4 ;
1012
+ uint32_t value = std::stoul (dataString.substr (0 , 8 ), nullptr , 16 );
1013
+
1014
+ if (expected_address == 299 && address == 0 ) {
1015
+ magic = value;
1016
+ magic_found = true ;
1017
+ chprintf (chp, " Magic found: %08X\r\n " , magic);
1018
+ continue ;
1019
+ }
1020
+
1021
+ if (expected_address != address) {
1022
+ chprintf (chp, " Error: expected address %d, got %d\r\n " , expected_address, address);
1023
+ cpld.AGM_exit_maintenance_mode ();
1024
+ file->close ();
1025
+ delete file;
1026
+ return ;
1027
+ }
1028
+
1029
+ (*data)[expected_address] = value;
1030
+ expected_address++;
1031
+
1032
+ if (expected_address == 1801 ) {
1033
+ if (!magic_found) {
1034
+ chprintf (chp, " Error: magic not found\r\n " );
1035
+ cpld.AGM_exit_maintenance_mode ();
1036
+ file->close ();
1037
+ delete file;
1038
+ return ;
1039
+ }
1040
+
1041
+ chprintf (chp, " Writing data to CPLD...\r\n " );
1042
+ file->close ();
1043
+ delete file;
1044
+
1045
+ cpld.AGM_write (*data, magic);
1046
+
1047
+ cpld.AGM_enter_read_mode ();
1048
+
1049
+ CRC<32 > crc{0x04c11db7 , 0xffffffff , 0xffffffff };
1050
+ for (size_t i = 0 ; i < 2048 ; i++) {
1051
+ uint32_t data = cpld.AGM_read (i);
1052
+ crc.process_byte ((data >> 0 ) & 0xff );
1053
+ crc.process_byte ((data >> 8 ) & 0xff );
1054
+ crc.process_byte ((data >> 16 ) & 0xff );
1055
+ crc.process_byte ((data >> 24 ) & 0xff );
1056
+ }
1057
+
1058
+ cpld.AGM_exit_maintenance_mode ();
1059
+
1060
+ chprintf (chp, " New CPLD firmware checksum: 0x%08X\r\n " , crc.checksum ());
1061
+
1062
+ m4_request_shutdown ();
1063
+ chThdSleepMilliseconds (1000 );
1064
+
1065
+ WWDT_MOD = WWDT_MOD_WDEN | WWDT_MOD_WDRESET;
1066
+ WWDT_TC = 100000 & 0xFFFFFF ;
1067
+ WWDT_FEED_SEQUENCE;
1068
+
1069
+ return ;
1070
+ break ;
1071
+ }
1072
+ }
1073
+ } else {
1074
+ break ;
1075
+ }
1076
+ } while (true );
1077
+ }
1078
+
1079
+ file->close ();
1080
+ delete file;
1081
+
1082
+ cpld.AGM_exit_maintenance_mode ();
1083
+
1084
+ } else {
1085
+ chprintf (chp, " CPLD Model: unknown\r\n " );
1086
+ }
1087
+ } else {
1088
+ chprintf (chp, usage);
1089
+ }
1090
+ } else {
1091
+ chprintf (chp, usage);
1092
+ }
1093
+ }
1094
+
910
1095
static void cmd_gotgps (BaseSequentialStream* chp, int argc, char * argv[]) {
911
1096
const char * usage = " usage: gotgps <lat> <lon> [altitude] [speed] [satinuse]\r\n " ;
912
1097
if (argc < 2 || argc > 5 ) {
@@ -1203,6 +1388,7 @@ static const ShellCommand commands[] = {
1203
1388
{" rtcset" , cmd_rtcset},
1204
1389
{" cpld_info" , cpld_info},
1205
1390
{" cpld_read" , cmd_cpld_read},
1391
+ {" cpld_write" , cmd_cpld_write},
1206
1392
{" accessibility_readall" , cmd_accessibility_readall},
1207
1393
{" accessibility_readcurr" , cmd_accessibility_readcurr},
1208
1394
{" applist" , cmd_applist},
0 commit comments