Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PSU datavector parser #55

Open
kodsurf opened this issue Nov 4, 2022 · 19 comments
Open

PSU datavector parser #55

kodsurf opened this issue Nov 4, 2022 · 19 comments

Comments

@kodsurf
Copy link
Collaborator

kodsurf commented Nov 4, 2022

I made general skeleton for PSU datavector parser c4c80a3

using the same method that I applied to parsing data from thruster registers.

PSU subsustem currently does not provide any real data! Only fake rubbish bytes.

PSU datavector is uint8_t array of bytes.

But values that are "encoded" by that datavector are not uint8_t !

Example from "Communication_Procedure_OBC_to_PSU_V2.doc" at https://github.com/DominicRichter/CLIMB_PSU

image

Something called "Edge temperature" is assembled out of two uint8_t bytes (low, high) into uint16_t value.

Temperature should in the end be represented as (270.5K) double unit measured in [K]

To obtain real physical value from datavector representation there should be something like CONVERSION_FACTOR

VALUE_UINT16 = (received_data[1] <<8 )| received_data[0];
double REAL_VALUE= VALUE_UINT16_t / CONVERSION_FACTOR

Example 1 :

We want to store 270.5 K as 2705

Which is hex 0x0A91

and can be represented with two bytes 0x0A and 0x91

Example 2 :

we obtain and asseble hex 0x0A91 out of received_data[0] , received_data[1] (which are two bytes in datavector)

store it as VALUE_UINT16 = 2705

now to obtain :
ACTUAL_VALUE = 2705 /100 = 270.5

where CONVERSION_FACTOR = 100


Those conversion factors have to be documented by PSU designers !!!

@kodsurf
Copy link
Collaborator Author

kodsurf commented Nov 5, 2022

Some info that I found on registers of PSU in Pegasys project.

https://github.com/RobertK66/PEGASUS-readonly/blob/develop/OBC_FP2_FreeRTOS/Source/layer2/inc/obc_eps.h

This seems to be in accordance ..
image


This also looks like in correlation
image

@kodsurf
Copy link
Collaborator Author

kodsurf commented Nov 5, 2022

`RetVal eps_settings_set(uint8_t cc, uint8_t reg, uint8_t val)
{
/* Set the specified register (reg) of the EPS to the given value (val). */

static I2C_Data job =
{ 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 };
static uint8_t tx[2];
uint32_t counter;

if ((reg < 64) || (reg > 87))
{
	/* Register number out of bounds */
	return FAILED;
}

if ((reg >= 64) && (reg <= 72))
{
	val = (val << 1) | odd_parity_calc(val);
}

if (cc == CC1)
{
	job.device = LPC_I2C0;
}
else
{
	job.device = LPC_I2C2;
}

/*--- Set resolution --- */
tx[0] = reg;
tx[1] = val;

job.adress = I2C_ADR_EPS;
job.tx_data = tx;
job.tx_size = 2;
job.rx_data = NULL;
job.rx_size = 0;

if (i2c_add_job(&job))
{
	return FAILED;
}

/* Wait for job to finish */
counter = 0;
while ((job.job_done != 1) && (counter < 50))
{
	delay_ms_all(2);
	counter++;
};

if (counter >= (50 - 1))
{
	return FAILED; /* Timeout while waiting for job */
}

if (job.error != I2C_ERROR_NO_ERROR)
{
	return FAILED;
}

return DONE;

}`

It seems that internal registers of PSU can be changed by two byte TX message (register index, value)

@kodsurf
Copy link
Collaborator Author

kodsurf commented Nov 5, 2022

`void eps_settings_read_all(uint8_t cc)
{
static I2C_Data job_tx =
{ 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 };
static I2C_Data job_rx =
{ 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 };
static uint8_t tx[1];

if (job_rx.job_done != 1)
{
	/* Old job not finished - prevent job data from being  - please slow down */
	if (cc == CC1)
	{
		obc_error_counters.i2c0_error_counter++;
	}
	else
	{
		obc_error_counters.i2c2_error_counter++;
	}

	eps_settings_data.data_valid = 0;
	job_rx.job_done = 1; // Set for next call
	job_rx.error = I2C_ERROR_JOB_NOT_FINISHED; // Set error to mark values old
	return;
}

if (job_rx.error != I2C_ERROR_NO_ERROR || job_tx.error != I2C_ERROR_NO_ERROR)
{
	/* Transmission error */
	eps_settings_data.data_valid = 0;
}
else
{
	eps_settings_data.data_valid = 1;
}

if (cc == CC1)
{
	job_tx.device = LPC_I2C0;
	job_rx.device = LPC_I2C0;
}
else
{
	job_tx.device = LPC_I2C2;
	job_rx.device = LPC_I2C2;
}

tx[0] = 64; /* Current Limit HV ... Nr. 64 */

job_tx.adress = I2C_ADR_EPS;
job_tx.tx_data = tx;
job_tx.tx_size = 1;
job_tx.rx_data = NULL;
job_tx.rx_size = 0;

i2c_add_job(&job_tx);

job_rx.adress = I2C_ADR_EPS;
job_rx.tx_data = NULL;
job_rx.tx_size = 0;
job_rx.rx_data = &(eps_settings_data.current_lim_hv);
job_rx.rx_size = 24;

if (i2c_add_job(&job_rx))
{
	if (cc == CC1)
	{
		obc_error_counters.i2c0_error_counter++;
	}
	else
	{
		obc_error_counters.i2c2_error_counter++;
	}
}

}`


I would try to take a closer look into PEGASUS EPS functions in order to understand how it was implemented there

image

It looks like this line 386 already works as a parser

data stored in received bytearray is recorded directly into structure that is meant to keep this data.

image

it is seen that RX size is 24

image

and number of bytes within the structure is indeed 24 + 1 (data_valid, whic seems to be not used)

@RobertK66
Copy link
Owner

RobertK66 commented Nov 7, 2022

Some notes about the 'data_valid' variable. During design of PEGASUS there was an effort made to get a 'secure data layer' somehow. The idea was that most stuff was available in a redundant way (2x I2C buses to EPU, 2x STACIES as comm interface, ....).

You can find this everywhere in this code. E.g. when reading values (of this 'layer') there is always a related 'valid bit' somewhere. But as this design was not thought through very well (especially what a higher layer should really do with that additional information ....) and it was completely untested at the time I entered the project, we decided to abandon it at this stage!

@kodsurf
Copy link
Collaborator Author

kodsurf commented Nov 7, 2022

Ok ....

The bytes from PSU datavector are loaded dirrectly into the structure that should keep them. This is done in layer2 of PEGASYS

But I am really struggling to figure out what happens next ....

To convert from raw bytes of uint16 to something usefull my_val is used ?
image

Are we sure that we dont want to do it the same way as done in enpulsion thruster. (with conversion multiplier table) and all values are stored as global double -representing value in physical units ?

@kodsurf
Copy link
Collaborator Author

kodsurf commented Nov 7, 2022

Ok I see that there is a library for MATH with fix16_t type.

Assuming that we store in memory fix16_t instead of double . And use conversion function
image

In Application layer of SW (when we need to compute and take an action based on physical value)

looks like I understood idea behind it .

But what are those q2_13_to_fix16() ?

image

@kodsurf
Copy link
Collaborator Author

kodsurf commented Nov 7, 2022

How_it_works

Is this how PSU data parser supposed to work ?

@kodsurf
Copy link
Collaborator Author

kodsurf commented Nov 7, 2022

So this EPS_MVAL_HK_I_PV1_5V is stored as some strange q2_13 ? What is q2_13

image

So datavector[2] and datavector[3] is a "q2_13" representation of i_p1_5v ????
image

So there should be a table that says that

EPS_HK_I_PV1_5V is stored at register 2 as some "q2_13" representation (whatever it is)
image

@RobertK66
Copy link
Owner

yea, this was a 'strange' conversion to 'fixed format' to have floats in 16bit values, to compress them for beacon and so on....

I would leave this for one discussion point for tomorrow. This (datatypes valid to be used!) has to be decided on a general level. Exactly this kind of confusion was triggering the famous ARIANE crash (as far as I can remember this ) :-)

@kodsurf
Copy link
Collaborator Author

kodsurf commented Nov 7, 2022

Ok

image

What is the correct syntaxis with pointers ?

I want to assign bytes stored at uint8_t i2c_buffer[] to the structure of eps_hk_data_t

so that i2c_buffer[0] and i2c_buffer[1] would become :

image


The pointer to HK_DATA_PSU structure should become and address of &i2c_buffer

image

But how ?

@kodsurf
Copy link
Collaborator Author

kodsurf commented Nov 7, 2022

09b12c2

Old pegasys EPS request seem to be working correctly with CLIMB OBC and "that thing" EPS that is currently connected to it.

By "Working correctly" I mean that eps_hk_data_t structure is filled with the same values as custom parser that I made before.

If basic stuff pegasus EPS stuff works - then the rest should also be ok. Just needs to be integrated back to CLIMB.

So I see options here :

  1. Integrate existing Pegasys EPS - and make proper documentation along the process. ( detailed description of protocol, request, datastructure, parser ..etc ) (?if this docu does not exists already ?)

Because now what I do - is trying to recreate EPS docu based on reverse engineering old pegasys repo. Still this EPS thing remains a total black box mistery to me. And I am collecting bits of information about it based on C code ...

image
Basically I am trying to GUESS what EPS is supposed to do - based on name o variables ....

  1. If EPS SW was or will be redesigned -there should be separate discussion about it to clarify how to adopt OBC code for SW and HW updates of EPS

@kodsurf
Copy link
Collaborator Author

kodsurf commented Nov 10, 2022

image

q2_13

Does it mean that :
2 bits are used to encode integer
13 bits are used to encode floating point
1 -bit are used to encode + or - sign

So it can store [4] values as integer part and [8192] values as floating part ?

uq3_13 means that :

3bits are used to encode integer
13 bits floating point

So it can store [8] values as integer part and [8192] values as floating part, only positive numbers


image

to store current int16 ---> +/-[0,1,2,3].999 A

to store voltage uint16_t [0,1,2,3,4,5,6,7].999 V

image

Temperature :
q7_8 :

[0-127].[0-99] C
so maximum temperature that we are able to store is 127.99C

Is that how it is supposed to work !?!?!?!??!?!??!???!?!?!?

@kodsurf
Copy link
Collaborator Author

kodsurf commented Nov 10, 2022

image

Multiplication of value by 2 means shifting binary bit to the left by 1 position.

Mupliply by 8 means shift by 222 = 3 positions to the left

..etc

@kodsurf
Copy link
Collaborator Author

kodsurf commented Nov 10, 2022

image

for fix16_t datatype fractional part is represented by 8 bits
image

Meaning that Radix point is at 8th bit.

so if we have uq3_13 meaning that fractional part is represented with 13bits

To convert to fix16 we must shift left by remaining 3 bits which represented an integer part (which is multiply by 8)

@kodsurf
Copy link
Collaborator Author

kodsurf commented Nov 10, 2022

Lets take it in reverse order :

  1. if we convert (double) value [real physical value] into fix16_t (using libraries fix16.h)
  2. To obtain uq3_16 from fix16_t we must SHIFT LEFT by 3 bit position ?
  3. Split resulting 16bit into two uint8_t

Those two MSB, LBS uint8_t would represent how the value is stored in PSU datavector[1] ,datavector[2]

2 things left to do :

  1. GET EXAMPLE OF REAL DATAVECTOR bytes !!!!!!!! and apply what is written above to convert it into real value to verify its correct and makes sense

  2. Make a table that will indicate in which binary representation (uq3_13, uq8_8 ... etc) the data from EVERY PSU REGISTER is stored

@kodsurf
Copy link
Collaborator Author

kodsurf commented Nov 10, 2022

fix16_t is uint32_t and according to Q format it is q15_16

To convert from any other Q format into fix16_t (u15_16) do binary shift to the left so that radix point is at 17th position (from left)

image

fix16_t value of 1 = 0x10000 and binary 00000000000000010000000000000000

@RobertK66
Copy link
Owner

ok, I never dived that deep into this 'fixed_xx' binary formats of EPS. I do not know what the exact intention of this format was ('Ease of use', 'compact bitwise format', 'avoid usage of float library functions', ....)

I think we should/could ask the original EPU developer about this intentions and then we can decide together with Andi (@AndiHilftnix ?) what to do with this values in the CLIMB context - and define the Climb PSU Interface definition.

@kodsurf
Copy link
Collaborator Author

kodsurf commented Nov 11, 2022

Based on pegasys repo

<style> </style>
Software reference Register index Description Binary format
EPS_HK_I_PV2_5V 0 Current through FET3-2 between PV2-bus and 5V converter,low byte q2_13
EPS_HK_I_PV1_5V 2 Current through FET3-1 between PV1-bus and 5V converter, low byte q2_13
EPS_HK_V_PV2 4 Voltage at PV2-bus,low byte uq3_13
EPS_HK_V_5V_IN 6 Voltage at the input of the 5V converter measured at FET3-1,low byte uq3_13
EPS_HK_I_PV1_3V3 8 Current through FET5-1 between PV1-bus and 3V3 converter,low byte q2_13
EPS_HK_I_PV2_3V3 10 Current through FET5-2 between PV2-bus and 3V3 converter,low byte q2_13
EPS_HK_V_PV1 12 Voltage at PV1-bus,low byte uq3_13
EPS_HK_V_3V3_IN 14 Voltage at the input of the 3V3 converter measured at FET5-2,low byte uq3_13
EPS_HK_TEMP_BAT1SW 16 Temp near BAT1 switches low byte q7_8
EPS_HK_TEMP_5V 18 Temp near 5V converter low byte q7_8
EPS_HK_I_PV1_HV 20 Current through FET4-1 between PV1-bus and HV supply,low byte q2_13
EPS_HK_I_PV2_HV 22 Current through FET4-2 between PV2-bus and HV supply,low byte q2_13
EPS_HK_V_3V3_OUT 24 Voltage at the output of the 3V3 converter,low byte uq3_13
EPS_HK_V_HV 26 Voltage at the output of the HV supply to the PPTs measured at FET4-2,low byte uq3_13
EPS_HK_I_PV2_BAT1 28 Current through FET1-2 between PV2-bus and battery 1,low byte q2_13
EPS_HK_I_PV1_BAT1 30 Current through FET1-1 between PV1-bus and  battery 1,low byte q2_13
EPS_HK_V_5V_OUT 32 Voltage at the output of the 5V converter,low byte uq3_13
EPS_HK_V_BAT1 34 Voltage of the battery 1,low byte uq3_13
EPS_HK_I_PV2_BAT2 36 Current through FET2-2 between PV2-bus and battery 2,low byte q2_13
<style> </style> <style> </style>
EPS_HK_I_PV1_BAT2 38 Current through FET2-1 between PV1-bus and  battery 2,low byte q2_13
EPS_HK_VCC_MC 40 Supply voltage of the MC uq3_5
EPS_HK_TEMP_MC 41 Temperature of the internal sensor of the MC int
EPS_HK_V_BAT2 42 Voltage of the battery 2,low byte uq3_13
EPS_HK_TEMP_BAT1 44 Temp of BAT1 on the battery holder,low byte q7_8
EPS_HK_TEMP_BAT2 46 Temp of BAT2 on the battery holder,low byte q7_8
EPS_HK_STATUS_1 48 B7 (MSB): 3V3-1 on  B6: 3V3-2 on uint8_t
EPS_HK_STATUS_2 49 /* B7 (MSB): Power Low Warning (EPS will enter in Power Down Mode soon after this warning), B6: Bat1 connected to PV1 uint8_t
EPS_HK_STATUS_3 50 /* B7 (MSB): 3V3 Burst Mode on, B6: 5V Burst Mode on uint8_t
EPS_HK_STATUS_BAT1 51 Estimation of the remaining capacity of the Battery 1 int
EPS_HK_STATUS_BAT2 52 Estimation of the remaining capacity of the Battery 2 int
EPS_HK_REBOOT_MC 53 Number of reboots since RBF of the main controller int
EPS_HK_REBOOT_CC1 54 Number of reboots since RBF of the first communication controller int
EPS_HK_REBOOT_CC2 55 Number of reboots since RBF of the second communication controller int
EPS_HK_VCC_CC1 56 Supply voltage of CC1 uq3_5
EPS_HK_TEMP_CC1 57 Temperature of the internal sensor of CC1 int
EPS_HK_VCC_CC2 58 Supply voltage of CC2 uq3_5
EPS_HK_TEMP_CC2 59 Temperature of the internal sensor of CC2 int
EPS_HK_STATUS_CC1 60 B7 (MSB)-B6: CC Mode: 00 Boot Mode, 01 Flight Mode uint8_t
EPS_HK_STATUS_CC2 61 B7 (MSB)-B6: CC Mode: 00 Boot Mode, 01 Flight Mode uint8_t
EPS_HK_CC_ID 62 0xAB uint8_t
EPS_HK_TBD 63 Not Used  

@kodsurf
Copy link
Collaborator Author

kodsurf commented Nov 11, 2022

image

image

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants