
Jag kipper ut 16 sidor av databladet. Där kan ni se hur J1939 hanterar olika adresser och EEPROM.
Och som ni ser i databladet så betyder det att 736 och 647 har antingen 0 eller 1. Men det svar jag får är att 736 har värdet 10 = 0x2 och 647 har värdet 0. Detta stämmer inte då 647 ska ha värdet 1 och 736 skall ha värdet 1const uint32_t pointers_eeprom_address[2] = {736, 647};
Kod: Markera allt
// Send a memory request for access EEPROM
static void DM14_Memory_access_request(uint32_t ID, uint16_t length, uint8_t command, uint32_t pointer, uint16_t key){
uint8_t data[8];
data[0] = length; // Length LSB
data[1] = (length >> 3) | (0 << 4) | (command << 1) | 1; // Length MSB, Pointer Type(Diagnostic message = 0), Command, 1 (Always)
data[2] = pointer; // Pointer LSB
data[3] = pointer >> 8;
data[4] = pointer >> 16; // Pointer MSB
data[5] = 0x1; // Pointer extension 1 for access EEPROM
data[6] = key; // Key LSB
data[7] = key >> 8; // Key MSB
write_CAN_message(ID, data);
}
// Request configuration parameters
void write_1939_configuration_request(J1939* j1939, uint8_t command){
uint32_t ID = (0x18D9 << 16) | (j1939->SA_ACU << 8) | j1939->SA_ECU;
HAL_Delay(1000);
/*
* Pointers:
* 646 = Sensor_Stall_Neutral_Enable
* 647 = Sensor_Stall_Normal_Enable
*
* Length:
* 1 = Sensor_Stall_Neutral_Enable
* 1 = Sensor_Stall_Normal_Enable
*/
const uint8_t length_eeprom_values[2] = {1, 1}; // Between 1 and 7 only!
const uint32_t pointers_eeprom_address[2] = {736, 647}; // Same indexing for j1939->EEPROM_values
// DM14(Ask) -> DM15(Status) -> DM16(Read/Write) -> DM14(Close)
for(uint8_t i = 0; i < 2; i++){
// Send a DM14 request
if(command == DM14_Read)
DM14_Memory_access_request(ID, length_eeprom_values[i], DM14_Read, pointers_eeprom_address[i], 0xFFFF); // 0xFFFF = No key
else if (command == DM14_Write)
DM14_Memory_access_request(ID, length_eeprom_values[i], DM14_Write, pointers_eeprom_address[i], 0x2505); // 0x2505 = Write key
// Read until we got a DM15 message response - We expecting DM15_Proceed
j1939->DM15_Status = DM15_Reserved;
while(j1939->DM15_Status == DM15_Reserved){
read_1939_message(j1939); // Will update j1939->DM15_Status
}
// What does it say
if(j1939->DM15_Status == DM15_Proceed){
if(command == DM14_Read){
// Read the EEPROM values of ECU and give them to the EEPROM_values array
memset(j1939->DM16_data, 0, 8); // j1939->DM16_data[0] will become between 1 and 7 only!
while(j1939->DM16_data[0] == 0){
read_1939_message(j1939); // As long DM16_data[0], then we have not receive our DM16 data yet
}
for(uint8_t j = 1; j <= j1939->DM16_data[0]; j++){
j1939->EEPROM_values[i] |= j1939->DM16_data[j] << 8*(j-1); // EEPROM_values are uint16_t
}
}else if (command == DM14_Write){
// Write the EEPROM_values to data and send it to the ECU EEPROM
memset(j1939->DM16_data, 0, 8);
j1939->DM16_data[0] = length_eeprom_values[i]; // Between 1 and 7 only!
for(uint8_t j = 1; j <= j1939->DM16_data[0]; j++){
j1939->DM16_data[j] = j1939->EEPROM_values[i] >> 8*(j-1); // EEPROM_values are uint16_t
}
write_CAN_message(ID, j1939->DM16_data);
}
}
// Read until we got a DM15 message response - We expecting DM15_Operation_Completed
j1939->DM15_Status = DM15_Reserved;
while(j1939->DM15_Status == DM15_Reserved){
read_1939_message(j1939); // Will update j1939->DM15_Status
}
// Close the read operation of DM14
//DM14_Memory_access_request(ID, length_eeprom_values[i], DM14_Operation_Completed, pointers_eeprom_address[i], 0xFFFF);
// Break the for-loop and return
if(j1939->DM15_Status == DM15_Busy){
break; // One single Busy status, then we cannot do anything yet
}
}
}
Jag använder alltså Pointer Type = 0 och det betyder att Pointer Extension = 1 kommer alltså vara en del utav adresseringen?If Pointer Type 0 is used, this 24-bit parameter, which has a value of 0 to 16,777,215 (0 to FFFFFF16) with no reserved ranges, is concatenated with the 8-bit Pointer Extension to form a direct memory address. The address thus formed represents the first address to be accessed within the memory in units of bytes. If Pointer Type 1 is used, the Pointer is to provide the identification of the specific OBJECT within whatever particular SPACE is being identified by the Pointer Extension. The direct memory address should be parsed as outlined below, 5.7.14.3.1, if the device memory width is other than 1 byte.
Eller hur ska man tolka detta?For all memory widths the starting address is simply the pointer extension concatenated with the pointer (the pointer being the lower 24 bits and the extension the upper. For memory widths of one byte there is a one-to-one mapping between data and the memory. Hence the first data byte goes into the memory at the starting address, while the second data byte corresponds to the memory at the starting address plus 1. For widths other than 1 byte, the data cannot map directly to the memory, but must be used to assemble the necessary width. Hence it will take as many data bytes per address as seven plus the memory width in bits all divided by 8 ((memory width + 7)/8). To maintain consistency with the rest of this standard the first data byte should be used for the byte containing bits 1 to 8 at the starting address. The second data byte should be used for bits 9 to 16. This should continue for the number of bytes required; then the address should be incremented and those bytes filled. When the memory width is less than 1 byte (as might happen when addressing a 2-bit parameter through the SPN space), a whole byte is used to contain each object's data (in other words no packing is to occur). The two bits will be placed in the least significant bits of the byte. For systems where the memory width is not an integer number of bytes, some bits in the highest byte are unused, reducing transfer efficiency, but enabling all memory widths to be handled. Examples of address calculation and byte association (see also section 5.7.16.2)
Sida 578-bit-wide memory, Pointer Extension = 1016, Pointer = 36780016 then the starting memory address is 1036780016and the first byte of Raw Binary Data would map directly into the memory at 1036780016, the second byte of Raw Binary Data would then map into memory 1036780116, and so on until completed. 16-bit-wide memory, Pointer Extension = 1016, Pointer = 36780016 then the starting memory address is 1036780016and the first byte of Raw Binary Data would map into bits 1 to 8 of the memory at 1036780016, while the second byte of Raw Binary Data would map into bits 9 to 16 of the same memory. The third byte of Raw Binary Data would then map into bits 1 to 8 of the memory at 1036780116, while the fourth byte of Raw Binary Data would map into bits 9 to 16 of the memory at 1036780116.32-bit-wide memory, Pointer Extension = 1016, Pointer = 36780016 then the starting memory address is 1036780016and the first byte of Raw Binary Data would map into bits 1 to 8 of the memory at 1036780016, while the second byte of Raw Binary Data would map into bits 9 to 16 of the memory at 1036780016, the third byte of Raw Binary Data would then map into bits 17 to 24 of the same memory and the fourth byte of Raw Binary Data would map bits 25 to 32. The fifth byte of Raw Binary Data would then map bits 1 to 8 of 1036780116, while the sixth byte of Raw Binary Data would map into bits 9 to 16 of 1036780116, the seventh byte of Raw Binary Data then mapping bits 17 to 24 and the eight byte of Raw Binary Data mapping to bits 25 to 32 of the memory. 12-bit-wide memory, Pointer Extension = 1016, Pointer = 36780016 then the starting memory address is 1036780016and the first byte of Raw Binary Data would map into bits 1 to 8 there, while bits 9 to 12 of the second byte of Raw Binary Data would map into bits 9 to 12 of 1036780016 (bits 13 to 16 are simply unused). The third byte of Raw Binary Data would then map into bits 1 to 8 of 1036780116, while bits 9 to 12 of the fourth byte of Raw Binary Data would map into bits 9 to 12 of 1036780116.
Kod: Markera allt
// Send a memory request for access EEPROM
static void DM14_Memory_access_request(uint32_t ID, uint16_t length, uint8_t command, uint32_t pointer, uint16_t key){
uint8_t data[8];
data[0] = length; // Length LSB
data[1] = (length >> 3) | (0 << 4) | (command << 1) | 1; // Length MSB, Pointer Type(Diagnostic message = 0), Command, 1 (Always)
data[2] = pointer; // Pointer LSB
data[3] = pointer >> 8;
data[4] = pointer >> 16; // Pointer MSB
data[5] = 0x1; // Pointer extension 1 for access EEPROM
data[6] = key; // Key LSB
data[7] = key >> 8; // Key MSB
write_CAN_message(ID, data);
}