Teensy 3.6 lan8720a ethernet

Status
Not open for further replies.

alex-arc

Active member
i am working on getting to know the new lan8720a ethernet module and have been digging through Poul's example https://github.com/PaulStoffregen/k66_ethernet

on page 1458 in the data sheet is a list of the different flags
https://cdn.sparkfun.com/datasheets/Dev/Arduino/Boards/K66P144M180SF5RMV2.pdf

trying to make a nice struct for it i ended up with this:

Code:
typedef struct {
	uint16_t length;
  union {
    uint16_t all;
    struct {
      uint16_t TR   : 1;  //frame must be discarded. Set if the receive frame is truncated (frame length >TRUNC_FL).
      uint16_t OV   : 1;  //This field is valid only if the L field is set. A receive FIFO overrun occurred
      uint16_t CR   : 1;  //This field is valid only if the L field is set. Receive CRC or frame error.
      uint16_t Reserved0 : 1;  //Reserved
      uint16_t NO   : 1;  //This field is valid only if the L field is set. Receive non-octet aligned frame
      uint16_t LG   : 1;  //This field is valid only if the L field is set. A frame length greater than RCR[MAX_FL] was recognized.
      uint16_t MC   : 1;  //Set if is multicast and not BC.
      uint16_t BC   : 1;  //Set if is broadcast (FFFF_FFFF_FFFF).
      uint16_t M    : 1;  //This field is valid only if the L and PROM bits are set. 0 The frame was received because of an address recognition hit. 1 The frame was received because of promiscuous mode.
      uint16_t Reserved1 : 2;  //Reserved
      uint16_t L    : 1;  //last frame
      uint16_t RO2  : 1;
      uint16_t W    : 1;  //Warp
      uint16_t RO1  : 1;  //Receive software ownership. This field is reserved for use by software. This read/write field is not modified by hardware, nor does its value affect hardware.
      uint16_t E    : 1;  //0 data in buffer. 1 buffer empty.
    };
  }flags;
	void *buffer;
  union {
    uint32_t all;
    struct {
      uint8_t Reserved0  : 7;
      uint8_t INT   : 1;
      uint8_t UC    : 1;        //unicast frame
      uint8_t CE    : 1;        //Collision error The frame is invalid. Only valid if the L field is set.
      uint8_t PE    : 1;        //PHY error The frame is invalid. Only valid if the L field is set.
      uint8_t Reserved1  : 4;
      uint8_t ME    : 1;        //Erroe in memory or receive FIFO overflow. Only valid if the L field is set.
      uint8_t FRAG  : 1;        //This is a IPv4 fragment frame. Only valid if the L field is set.
      uint8_t IPV6  : 1;        //IPV6 tag. Only valid if the L field is set.
      uint8_t VLAN  : 1;        //VLAN tag. Only valid if the L field is set.
      uint8_t Reserved2  : 1;
      uint8_t PCR  : 1;         //Protocol checksum error. Only valid if the L field is set.
      uint8_t ICE  : 1;         //IP header checksum error. Only valid if the L field is set.
      uint8_t Reserved3  : 2;
      uint8_t Reserved4  : 5;
      uint8_t VPCP : 3;         //VLAN priority code 0-7
    };
  }moreflags;
	uint16_t checksum;
	uint8_t header;
  uint8_t protocolType :7;
	uint32_t dmadone;
	uint32_t timestamp;
	uint32_t unused1;
	uint32_t unused2;
} enetbufferdesc_t;

on github https://github.com/alex-Arc/k66_ethernet

my question is, will the bit fields make this very slow and if so, how to do it differently and still keep the clarity of the 1 bit flags?

:D Alex
 
Well, that depends on your idea of "clarity". ;)
when testing all the flags, instead of figuring out masks i found it easier to declare every bit.
now when trying to implement the flags i proper code that generates annoyingly long if statements and i am now using masks.


bjdump -d to look at the generated assembly code.

this was interesting. this code:
Code:
typedef struct {
  uint8_t t1;
}test_t;

test_t testVar;

void setup() {
  // put your setup code here, to run once:
  testVar.t1 = 0xAA; // seting 10101010
}

void loop() {
  // put your main code here, to run repeatedly:

}

generates assembly:
Code:
00000000 <setup>:
   0:	2201      	movs	r2, #1
   2:	4b01      	ldr	r3, [pc, #4]	; (8 <setup+0x8>)
   4:	701a      	strb	r2, [r3, #0]
   6:	4770      	bx	lr
   8:	00000000 	.word	0x00000000

Disassembly of section .text.loop:

00000000 <loop>:
   0:	4770      	bx	lr
   2:	bf00      	nop

and this code:
Code:
typedef struct {
  uint8_t t1 :1;
  uint8_t t2 :1;
  uint8_t t3 :1;
  uint8_t t4 :1;
  uint8_t t5 :1;
  uint8_t t6 :1;
  uint8_t t7 :1;
  uint8_t t8 :1;
}test_t;

test_t testVar;

void setup() {
  // put your setup code here, to run once:
  testVar.t1 = 1; // seting 10101010
  testVar.t2 = 0;
  testVar.t3 = 1;
  testVar.t4 = 0;
  testVar.t5 = 1;
  testVar.t6 = 0;
  testVar.t7 = 1;
  testVar.t8 = 0;
}

void loop() {
  // put your main code here, to run repeatedly:

}

generats this:
Code:
00000000 <setup>:
   0:	4b04      	ldr	r3, [pc, #16]	; (14 <setup+0x14>)
   2:	781a      	ldrb	r2, [r3, #0]
   4:	f002 0280 	and.w	r2, r2, #128	; 0x80
   8:	f042 0255 	orr.w	r2, r2, #85	; 0x55
   c:	f36f 12c7 	bfc	r2, #7, #1
  10:	701a      	strb	r2, [r3, #0]
  12:	4770      	bx	lr
  14:	00000000 	.word	0x00000000

Disassembly of section .text.loop:

00000000 <loop>:
   0:	4770      	bx	lr
   2:	bf00      	nop

so
5 lines :)
vs
8 lines :(
 
Last edited:
Just a quick question: will PJRC make this board commercially available soon?
Thank you!
 
Status
Not open for further replies.
Back
Top