I've updated the code. It's not the best thing I've ever wrote, but it's not that bad either
Turns out, to make them outputs you had to write 0001001001001001001001001, setting them to all 1s will disable them.
I think it is safe to say that code below is true. The problem now is to identify the commands and I have seen already more than a hand full. For example 0x21 tells the fpga to setup for reading either 1500 or 750 bytes of data, and also a similar function where the command being written before reading is supplied by an other function where a sequence of other commands (0x6X range) each followed by a read of a data byte is done.
Quite the puzzle.
//PE0:7 Databus
//PE08 Clock
//PE09 read/write 0 = read, 1 = write
//PE10 data/command 0 = data, 1 = command
Did you try the reader.hex, to see if that gives output like I saw on windows 7?
I tried it. It also does not output anything to the com port. What connection speed of the com port should be set?
The speed of the port does not matter, there is no conversion to real serial.
Then maybe it is best to see if you can get a linux (I'm using linux mint 20) up and running. If then you still can't get it done I will improve the code for you.
edit: I used cutecom for communication, but it also works with putty, and probably with screen and other terminal programs.
I've updated the code. It's not the best thing I've ever wrote, but it's not that bad either
Turns out, to make them outputs you had to write 0001001001001001001001001, setting them to all 1s will disable them.
Totally correct, that is why I wrote the hexadecimal form of it. (0x11111111)
I've updated the code. It's not the best thing I've ever wrote, but it's not that bad either
Turns out, to make them outputs you had to write 0001001001001001001001001, setting them to all 1s will disable them.
Totally correct, that is why I wrote the hexadecimal form of it. (0x11111111)
Not right. To be 0x111.. it must be 0001
0001
0001...
That is true. I did not read it right because I thought he had 3 zero's per 1 in there. And according to the manual it needs to be so. Bit 3 is reserved, so it is 4 bits per pin.
I could not flash the touchscreen with the bluepill. I connected it to the touchscreen, there is no result - the touchscreen works in reverse. I fleshed it with the arduino (sketch from ser8989). The touchscreen now works correctly! Many thanks to ser8989 and pcprogrammer for the work done!
Update for the possible brightness. The actual brightness is most likely a second byte written after the 0xEA. This is the sequence I found with Ghidra.
FUN_800169F8 is write command to fpga
FUN_800168FC is write data to fpga
I could not flash the touchscreen with the bluepill. I connected it to the touchscreen, there is no result - the touchscreen works in reverse. I fleshed it with the arduino (sketch from ser8989). The touchscreen now works correctly! Many thanks to ser8989 and pcprogrammer for the work done!
Your welcome.
Too bad the bluepill did not work for you, but luckily you had ser8989 his solution. Glad your scope is working normally again. Have fun with it.
That is true. I did not read it right because I thought he had 3 zero's per 1 in there. And according to the manual it needs to be so. Bit 3 is reserved, so it is 4 bits per pin.
You're right! I missed the reserved bit. I've updated the code once again haha
Update for the possible brightness. The actual brightness is most likely a second byte written after the 0xEA. This is the sequence I found with Ghidra.
FUN_800169F8 is write command to fpga
FUN_800168FC is write data to fpga
Yep, in my code the brightness level is written after the EA byte, so 1 cmd byte, 2 data bytes.
Slightly modified the sketch from ser8989. Added error output (Read configuration Error!) If the touchscreen is not connected or not connected correctly. Added messages about the beginning and end of the recording. Configuration reading is performed 2 times - before writing and after writing. After switching on, there is a delay of 2 seconds. Then the read / write is restarted every 30 seconds
Another version of the sketch. Now the action is performed on a command from the com port (Read Write)
An update on the FPGA analysis. So far I already found the use of 42 different commands being written to the FPGA.
I identified 4 functions that inter-act on low level with the FPGA:
void FUN_800169f8(byte Command) //Write a byte to the command register
void FUN_800168fc(byte Data) //Write a byte to the data register
byte FUN_80016850(void) //Read a byte from the data register
void FUN_800167a0(void) //Set the databus for input
The other functions use these functions to do the communications.
The command 0x38 is used twice in the code, so either they set the brightness on two locations or it is not what we think it is.
Live tests with own written code need to be done to see what all the commands do.
There will be commands to control the relays in the analog input section, maybe control the sample speed, set trigger parameters, etc.
The command 0x38 is used twice in the code, so either they set the brightness on two locations or it is not what we think it is.
I think that you can find it in two parts of the code because one of them is the init (when you power on the scope) and the other one the user menu, where the user can adjust it. At least it makes sense to me.
I will try to boot bare-metal code and try to write some commands and see what they do.
That is a good idea.
The brightness is probably also set in the second program loader or the 1st executable, of which I think it is just used to display the initial image on the display. So a search through these parts might confirm things.
An option for testing can also be to make use of the FEL mode. With it is possible to load code to DRAM and execute it. This way you don't have to burn a SD card for every test. With the touch panel disconnected you can use UART1 for debug output.
Question:
I still, did not find where the initialization functions are being called. Found the initialization function (FUN_800168A0) for communication with the FPGA, but there is no XREF for it like for other function.
The XREF in the attached image is for the local_8 variable.
This is the same for the I2C init function for the touch panel.
So if anyone knows where these initialization functions are called please let me know.
The command 0x38 is the only command being written to the FPGA in the second program loader part. After it two data bytes are written, of which the first is 0xEA. The second byte is read from SRAM. (address 0x0000EA60)
So it most certainly will be the back-light control.
Question:
I still, did not find where the initialization functions are being called. Found the initialization function (FUN_800168A0) for communication with the FPGA, but there is no XREF for it like for other function.
The XREF in the attached image is for the local_8 variable.
This is the same for the I2C init function for the touch panel.
So if anyone knows where these initialization functions are called please let me know.
In function sub_80035320. (I labeled the funcs according to your findings)
Looking at tv84 his output the display brightness is set to 0xEA 0x60 just before displaying the SD ERROR message, which you get when you remove the SD card and start the scope. So that explains the double use of the brightness setting command.
The other one will be the brightness setting when the scope starts up normally and when the user adjusts the brightness.
Edit: The command 0x38 with data 0xEA 0x60 I found is in yet another section of the code, where it handles other errors the system might encounter. (FUN_8001c138) Apparently it can detect failure of "AD9288_1_2"
Maybe I'm using Ghidra with incorrect settings or it is not as good as the program tv84 is using. But it explains why I could not find the calls to the init functions. Ghidra does not find code at that address.
Edit: Found the option to disassemble this section and now it shows the function calls.
Maybe I'm using Ghidra with incorrect settings or it is not as good as the program tv84 is using. But it explains why I could not find the calls to the init functions. Ghidra does not find code at that address.
Sure it can. You just have to force it, in that case.
Did that and edited my previous post.
Had some idea's come up overnight and found some interesting stuff based on them. The FPGA is used to talk to the unknown I2C chip connected to it and I believe the MCU uses the FPGA commands in the range 0x6X to communicate with this unknown chip.
For the brightness setting in FUN_8001d380 a call is made to FUN_800248f8 with 0x10 and some other parameter. In this function the 0x6X commands are used. There are writes to 0x68 ~ 0x6E. This entails 7 bytes, and what did I find earlier in my quest, the communication with this unknown chip is done in bursts of 8 bytes. 1 slave address and 7 data bytes.
So I have to write an experiment to check this out.
If it is so, things become much clearer. I did notice that the scope remembers it's settings, so we have to identify what each byte used, when calling FUN_800248f8, means.
Edit: The command 0x38 with data 0xEA 0x60 I found is in yet another section of the code, where it handles other errors the system might encounter. (FUN_8001c138) Apparently it can detect failure of "AD9288_1_2"
That function is something like a Check_HW. See below:
int Check_HW()
{
int result; // r0@1
int v1; // r0@2
int v2; // r0@2
int v3; // r0@2
int v4; // r0@2
int v5; // r0@2
int v6; // r0@2
int v7; // r0@2
int v8; // r0@2
int v9; // r0@2
int v10; // r1@2
int v11; // r0@2
int v12; // r4@2
signed int v13; // r0@8
int v14; // r0@13
int v15; // r4@14
const char *v16; // r0@15
int v17; // r0@24
int v18; // r0@24
int v19; // r0@24
int v20; // r0@24
result = sub_8002330C();
if ( result != 2 )
{
v1 = sub_80027D88();
v2 = sub_8000690C(v1);
v3 = sub_80009658(v2);
v4 = sub_80001314(v3);
v5 = sub_8000689C(v4);
v6 = sub_800095E8(v5);
v7 = sub_800068D4(v6);
sub_80009620(v7);
sub_80012A4C();
v8 = sub_800267E8();
sub_80002790(v8);
sub_80026808();
sub_800267C4();
v9 = sub_80026828();
v11 = sub_8000696C(v9, v10);
sub_800096B8(v11);
FPGA_write_cmd(0x38u);
FPGA_write_data(0xEAu);
FPGA_write_data(0x60u);
sub_80017778();
sub_80019704(0);
sub_80018F6C(0);
sub_80019730(off_8018B738);
sub_800197C8(0);
FPGA_write_cmd(6u);
v12 = (FPGA_read_data() << 8) & 0xFF00; // Check_FPGA
if ( (FPGA_read_data() | v12) != 0x1432 )
{
sub_80019704(0xFF0000);
print_msg((int)"FPGA", 30, 90);
print_msg((int)"Failed", 100, 90);
while ( 1 )
;
}
sub_80019704(0xFFFFFF);
print_msg((int)"FPGA", 30, 90);
print_msg((int)"OK", 100, 90);
sub_80017CE0();
if ( Check_Encrypt() != 0x8150 )
{
sub_80019704(0xFF0000);
print_msg((int)"Encrypt", 30, 110);
print_msg((int)"Failed", 100, 110);
while ( 1 )
;
}
sub_80019704(0xFFFFFF);
print_msg((int)"Encrypt", 30, 110);
print_msg((int)"OK", 100, 110);
v13 = Check_AD9288();
if ( v13 != 3 )
{
if ( v13 != 1 )
{
if ( v13 != 2 )
{
sub_80019704(0xFF0000);
print_msg((int)"AD9288_1_2", 30, 130);
print_msg((int)"Failed", 120, 130);
while ( 1 )
;
}
sub_80019704(0xFF0000);
print_msg((int)"AD9288_1", 30, 130);
print_msg((int)"Failed", 120, 130);
while ( 1 )
;
}
sub_80019704(0xFF0000);
print_msg((int)"AD9288_2", 30, 130);
print_msg((int)"Failed", 120, 130);
while ( 1 )
;
}
sub_80019704(0xFFFFFF);
print_msg((int)"AD9288", 30, 130);
v14 = print_msg((int)"OK", 100, 130);
if ( !Check_Analog(v14) )
{
sub_80019704(0xFF0000);
print_msg((int)"Analog", 30, 150);
print_msg((int)"Failed", 100, 150);
while ( 1 )
;
}
sub_80019704(0xFFFFFF);
print_msg((int)"Analog", 30, 150);
print_msg((int)"OK", 100, 150);
sub_80019704(0xFFFFFF);
print_msg((int)"Touch", 30, 170);
print_msg((int)"...", 103, 167);
v15 = Check_Touch();
if ( v15 )
{
sub_80019704(0xFFFFFF);
v16 = "OK ";
}
else
{
sub_80019704(0xFF0000);
v16 = "Failed";
}
result = print_msg((int)v16, 100, 170);
if ( v15 )
{
sub_80019704(0xFFFFFF);
print_msg((int)"Hard Checked Successful !", 30, 190);
v8019D5A3 = 0;
v8019D5A6 = 300;
v8019D5AF = 0;
v8019D5B2 = 100;
v8019D5AA = 19;
v17 = sub_8000696C(0x8019D5A0, 0);
v18 = sub_800096B8(v17);
v19 = sub_8000689C(v18);
sub_800095E8(v19);
v20 = sub_800266C4();
sub_80025BB0(v20);
result = sub_8000BC00(500);
}
}
return result;
}
So, they check (by this order):
1 - FPGA // ID ??
2 - FPGA_Encrypt // Checksum ??
3 - AD9288
4 - Analog
5 - Touch
If all is well it returns: "Hard Checked Successful !"