Addressing PDO with different size. APPL_InputMapping & APPL_OutputMapping

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
User16529
Level 4
Level 4
First solution authored
Hello everybody!
I have some problems collecting data from outputs. In the object dictionary i have several PDO's: from 0x1600 to 0x1609 i'm mapping record output objects with 16 entries of 1bit each, from 0x1610 to 0x1619 i'm mapping objects with 8 entries of 1bit each.
I need to switch from one PDO to another depending on the object i'm addressing, so my APPL_OutputMapping is the following


void APPL_OutputMapping(UINT16* pData)
{
uint16_t j = 0;
for(j = 0; j < sRxPDOassign.u16SubIndex0; j++)
{
switch(sRxPDOassign.aEntries)
{
case 0x1600:
memcpy(&(((UINT16 *)&Output10x7100)[1]), pData, SIZEOF(Output10x7100)-2);
pData++;
break;

case 0x1601:
memcpy(&(((UINT16 *)&Output20x7110)[1]), pData, SIZEOF(Output20x7110)-2);
pData++;
break;

case 0x1602:
memcpy(&(((UINT16 *)&Output30x7120)[1]), pData, SIZEOF(Output30x7120)-2);
pData++;
break;

case 0x1603:
memcpy(&(((UINT16 *)&Output40x7130)[1]), pData, SIZEOF(Output40x7130)-2);
pData++;
break;

case 0x1604:
memcpy(&(((UINT16 *)&Output50x7140)[1]), pData, SIZEOF(Output50x7140)-2);
pData++;
break;

case 0x1605:
memcpy(&(((UINT16 *)&Output60x7150)[1]), pData, SIZEOF(Output60x7150)-2);
pData++;
break;

case 0x1606:
memcpy(&(((UINT16 *)&Output70x7160)[1]), pData, SIZEOF(Output70x7160)-2);
pData++;
break;

case 0x1607:
memcpy(&(((UINT16 *)&Output80x7170)[1]), pData, SIZEOF(Output80x7170)-2);
pData++;
break;

case 0x1608:
memcpy(&(((UINT16 *)&Output90x7180)[1]), pData, SIZEOF(Output90x7180)-2);
pData++;
break;

case 0x1609:
memcpy(&(((UINT16 *)&Output100x7190)[1]), pData, SIZEOF(Output100x7190)-2);
pData++;
break;

case 0x1610:
memcpy(&(((UINT16 *)&Out810x7300)[1]), pData, SIZEOF(Out810x7300)-2);
pData++;
break;

case 0x1611:
memcpy(&(((UINT16 *)&Out820x7310)[1]), pData, SIZEOF(Out820x7310)-2);
pData++;
break;

case 0x1612:
memcpy(&(((UINT16 *)&Out830x7320)[1]), pData, SIZEOF(Out830x7320)-2);
pData++;
break;

case 0x1613:
memcpy(&(((UINT16 *)&Out840x7330)[1]), pData, SIZEOF(Out840x7330)-2);
pData++;
break;

case 0x1614:
memcpy(&(((UINT16 *)&Out850x7340)[1]), pData, SIZEOF(Out850x7340)-2);
pData++;
break;

case 0x1615:
memcpy(&(((UINT16 *)&Out860x7350)[1]), pData, SIZEOF(Out860x7350)-2);
pData++;
break;

case 0x1616:
memcpy(&(((UINT16 *)&Out870x7360)[1]), pData, SIZEOF(Out870x7360)-2);
pData++;
break;

case 0x1618:
memcpy(&(((UINT16 *)&Out890x7380)[1]), pData, SIZEOF(Out890x7380)-2);
pData++;
break;

case 0x1619:
memcpy(&(((UINT16 *)&Out8100x7390)[1]), pData, SIZEOF(Out8100x7390)-2);
pData++;
break;
}
}
}


It's the same for the input PDO's


void APPL_InputMapping(UINT16* pData)
{
uint16_t j = 0;

for(j = 0; j < sTxPDOassign.u16SubIndex0; j++)
{
switch(sTxPDOassign.aEntries)
{

case 0x1A00:
memcpy(pData, &(((UINT16 *)&Input10x6100)[1]), SIZEOF(Input10x6100)-2);
pData++;
break;

case 0x1A01:
memcpy(pData, &(((UINT16 *)&Input20x6110)[1]), SIZEOF(Input20x6110)-2);
pData++;
break;

case 0x1A02:
memcpy(pData, &(((UINT16 *)&Input30x6120)[1]), SIZEOF(Input30x6120)-2);
pData++;
break;

case 0x1A03:
memcpy(pData, &(((UINT16 *)&Input40x6130)[1]), SIZEOF(Input40x6130)-2);
pData++;
break;

case 0x1A04:
memcpy(pData, &(((UINT16 *)&Input50x6140)[1]), SIZEOF(Input50x6140)-2);
pData++;
break;

case 0x1A05:
memcpy(pData, &(((UINT16 *)&Input60x6150)[1]), SIZEOF(Input60x6150)-2);
pData++;
break;

case 0x1A06:
memcpy(pData, &(((UINT16 *)&Input70x6160)[1]), SIZEOF(Input70x6160)-2);
pData++;
break;

case 0x1A07:
memcpy(pData, &(((UINT16 *)&Input80x6170)[1]), SIZEOF(Input80x6170)-2);
pData++;
break;

case 0x1A08:
memcpy(pData, &(((UINT16 *)&Input90x6180)[1]), SIZEOF(Input90x6180)-2);
pData++;
break;

case 0x1A09:
memcpy(pData, &(((UINT16 *)&Input100x6190)[1]), SIZEOF(Input100x6190)-2);
pData++;
break;

case 0x1A10:
memcpy(pData, &(((UINT16 *)&In810x6300)[1]), SIZEOF(In810x6300)-2);
pData++;
break;

case 0x1A11:
memcpy(pData, &(((UINT16 *)&In820x6310)[1]), SIZEOF(In820x6310)-2);
pData++;
break;

case 0x1A12:
memcpy(pData, &(((UINT16 *)&In830x6320)[1]), SIZEOF(In830x6320)-2);
pData++;
break;

case 0x1A13:
memcpy(pData, &(((UINT16 *)&In840x6330)[1]), SIZEOF(In840x6330)-2);
pData++;
break;

case 0x1A14:
memcpy(pData, &(((UINT16 *)&In850x6340)[1]), SIZEOF(In850x6340)-2);
pData++;
break;

case 0x1A15:
memcpy(pData, &(((UINT16 *)&In860x6350)[1]), SIZEOF(In860x6350)-2);
pData++;
break;

case 0x1A16:
memcpy(pData, &(((UINT16 *)&In870x6360)[1]), SIZEOF(In870x6360)-2);
pData++;
break;

case 0x1A17:
memcpy(pData, &(((UINT16 *)&In880x6370)[1]), SIZEOF(In880x6370)-2);
pData++;
break;

case 0x1A18:
memcpy(pData, &(((UINT16 *)&In890x6380)[1]), SIZEOF(In890x6380)-2);
pData++;
break;

case 0x1A19:
memcpy(pData, &(((UINT16 *)&In8100x6390)[1]), SIZEOF(In8100x6390)-2);
pData++;
break;

case 0x1AFF:
memcpy(pData, &(((UINT16 *)&DeviceInput0x6000)[1]), SIZEOF(DeviceInput0x6000)-2);
pData++;
break;

}
}

}


I collect data from output and put them into an array.
My problem is that when i collect data from outputs they came in a wierd form. For example, when i want a word like 0x0101 from the first 16bit object i get array[0] = 0x0100 (where 01 are the LSBs) and array[1] = 0x0001 (where 01 are the MSBs). But i expected to get array[0] = 0x0101.
I think i'm doing something wrong in the APPL_OutputMapping and APPL_InputMapping functions, but i can't find out what it is.

Any advise would be appriciate.
Thank you!
0 Likes
10 Replies
User16529
Level 4
Level 4
First solution authored
Is there someone that could help me, please?
0 Likes
MichaelIFX
Employee
Employee
50 replies posted 25 replies posted 10 replies posted
I'm not sure but I feel you have an issue with padding.
See also:
https://download.beckhoff.com/download/document/io/ethercat-development-products/an_et9300_v1i8.pdf

7.1. Structure/Alignment Rules

In regard to SSC specific issues you can also use the ETG forum.
0 Likes
User15738
Level 1
Level 1
Some thoughts on this to validate:
- Is the data as expected in teh memory referenced by pData?
- Are the entries stored in the 0x7nnn structures stored without any implicit memory paddings? A straight forward check on this could be to set all entry variables to 1 and check the structure memory
- The mapping won't work for your 8entry objects because pData is shifted by 16Bit so you would get invalid data/or accessing invalid memeory ranges. One solution could be to handle pData as an 8Bit pointer.
0 Likes
User16529
Level 4
Level 4
First solution authored
RainerHoffmann wrote:
Some thoughts on this to validate:
- Is the data as expected in teh memory referenced by pData?
- Are the entries stored in the 0x7nnn structures stored without any implicit memory paddings? A straight forward check on this could be to set all entry variables to 1 and check the structure memory
- The mapping won't work for your 8entry objects because pData is shifted by 16Bit so you would get invalid data/or accessing invalid memeory ranges. One solution could be to handle pData as an 8Bit pointer.


Thank you both. I think RainerHoffmann guessed the problem with the shifted pData
0 Likes
User16529
Level 4
Level 4
First solution authored
Hello again! I'm trying to solve the problem using the padding subindex in the object dictionary. The 16bit output object now is


typedef struct OBJ_STRUCT_PACKED_START {
UINT16 u16SubIndex0;
BOOLEAN(Out1); /* Subindex1 - Out1 */
ALIGN15(SI2) /* Subindex2 */
BOOLEAN(Out2); /* Subindex3 - Out2 */
ALIGN14(SI4) /* Subindex4 */
BOOLEAN(Out3); /* Subindex5 - Out3 */
ALIGN13(SI6) /* Subindex6 */
BOOLEAN(Out4); /* Subindex7 - Out4 */
ALIGN12(SI8) /* Subindex8 */
BOOLEAN(Out5); /* Subindex9 - Out5 */
ALIGN11(SI10) /* Subindex10 */
BOOLEAN(Out6); /* Subindex11 - Out6 */
ALIGN10(SI12) /* Subindex12 */
BOOLEAN(Out7); /* Subindex13 - Out7 */
ALIGN9(SI14) /* Subindex14 */
BOOLEAN(Out8); /* Subindex15 - Out8 */
ALIGN8(SI16) /* Subindex16 */
BOOLEAN(Out9); /* Subindex17 - Out9 */
ALIGN7(SI18) /* Subindex18 */
BOOLEAN(Out10); /* Subindex19 - Out10 */
ALIGN6(SI20) /* Subindex20 */
BOOLEAN(Out11); /* Subindex21 - Out11 */
ALIGN5(SI22) /* Subindex22 */
BOOLEAN(Out12); /* Subindex23 - Out12 */
ALIGN4(SI24) /* Subindex24 */
BOOLEAN(Out13); /* Subindex25 - Out13 */
ALIGN3(SI26) /* Subindex26 */
BOOLEAN(Out14); /* Subindex27 - Out14 */
ALIGN2(SI28) /* Subindex28 */
BOOLEAN(Out15); /* Subindex29 - Out15 */
ALIGN1(SI30) /* Subindex30 */
BOOLEAN(Out16); /* Subindex31 - Out16 */
/* Subindex 032 has no bitlength therefore no variable is created */
} OBJ_STRUCT_PACKED_END
TOBJ7100;


with all entries rw, even the padding ones.

The 8bit output object is


typedef struct OBJ_STRUCT_PACKED_START {
UINT16 u16SubIndex0;
BOOLEAN(Out1); /* Subindex1 - Out1 */
ALIGN15(SI2) /* Subindex2 */
BOOLEAN(Out2); /* Subindex3 - Out2 */
ALIGN14(SI4) /* Subindex4 */
BOOLEAN(Out3); /* Subindex5 - Out3 */
ALIGN13(SI6) /* Subindex6 */
BOOLEAN(Out4); /* Subindex7 - Out4 */
ALIGN12(SI8) /* Subindex8 */
BOOLEAN(Out5); /* Subindex9 - Out5 */
ALIGN11(SI10) /* Subindex10 */
BOOLEAN(Out6); /* Subindex11 - Out6 */
ALIGN10(SI12) /* Subindex12 */
BOOLEAN(Out7); /* Subindex13 - Out7 */
ALIGN9(SI14) /* Subindex14 */
BOOLEAN(Out8); /* Subindex15 - Out8 */
ALIGN8(SI16) /* Subindex16 */
} OBJ_STRUCT_PACKED_END
TOBJ7300;


But writing the objects in this way doesn't fix the problem, because when i flash the code in the xmc4800, the board just stop working, the master doesn't recognize the ethercat slave. Did I add to mush pad entries?

Thank you for any reply
0 Likes
User15738
Level 1
Level 1
Sorry not comming back to that topic earlier did you make any progress?
0 Likes
User16529
Level 4
Level 4
First solution authored
Unfortunately no
0 Likes
User15738
Level 1
Level 1
This way of adding padding entries is a waste of memory and would also not work, you've just decremetn the padding after each entry:
BOOL (SI1)
15bit padding
BOOL (SI3)
14bit padding
BOOL (SI5)
13bit padding
....

You don't need to add padding entries if the structures does not have any implicit padding (as mentioned before the easiest way to check that is set all entries to 1 and check the memory).

If that is the case change the you could deal with the 8Bit objects, either by adapting the pointer type in in the mapping functions or by adding 1 additional 8bit padding after the last entry.
0 Likes
User16529
Level 4
Level 4
First solution authored
Yes, padding doesn't help. The problem is 100% the pData in void APPL_InputMapping(UINT16* pData), it's shifted. Now i'm having addressing problem even without the 8entries object. I have 16entries objects and one input object with 4 uint16 entries, that are all set to 1.
For this object the input mapping is in this way


*pData = AnalogueInputs0x6000.Ch0;
pData++;
*pData = AnalogueInputs0x6000.Ch1;
pData++;
*pData = AnalogueInputs0x6000.Ch2;
pData++;
*pData = AnalogueInputs0x6000.Ch3;
pData++;


and everything is ok.
But if i use the same mapping method for the 16boolean object the things get wierd, so i maintain the "classical" mapping method


memcpy(pData, &(((UINT16 *)&Input10x6300)[1]), SIZEOF(Input10x6310)-2);
pData++;


But when I write "1" on the first object, i see the value even in the last object and whe i write on the second object i don't see the value i set, and the writing on the third object goes to the second.

I've tried to set pData as an 8bit pointer, but it doesn't change anything
0 Likes
User16529
Level 4
Level 4
First solution authored
Finally i've solved the problem! pData pointer wasn't shifted, i just had to read/write the 8 MSB bits or the 8 LSB bits according to the mapped object
0 Likes