LinkedIn YouTube Facebook
Szukaj

Wstecz
IoT

Komunikacja sieciowa z wykorzystaniem mikrokontrolerów Freescale Kinetis

Przykładowy kod źródłowy implementujący wszystkie wymienione wyżej punkty przedstawiono w listingu:

/* Buffer Descriptor Format */
#ifdef ENHANCED_BD
typedef struct
{
uint16_t status; /* control and status */
uint16_t length; /* transfer length */
uint8_t *data; /* buffer address */
uint32_t ebd_status;
uint16_t length_proto_type;
uint16_t payload_checksum;
uint32_t bdu;
uint32_t timestamp;
uint32_t reserverd_word1;
uint32_t reserverd_word2;
} NBUF;
#else
typedef struct
{
uint16_t status; /* control and status */
uint16_t length; /* transfer length */
uint8_t *data; /* buffer address */
} NBUF;
#endif /* ENHANCED_BD */
static void enet_init()
{
int usData;
const unsigned portCHAR ucMACAddress[6] =
{
configMAC_ADDR0,
configMAC_ADDR1,configMAC_ADDR2,configMAC_ADDR3,configMAC_ADDR4,configMAC_ADDR5
};
/* Enable the ENET clock. */
SIM_SCGC2 |= SIM_SCGC2_ENET_MASK;
/*FSL: allow concurrent access to MPU controller. Example: ENET uDMA to SRAM, otherwise
bus error*/
MPU_CESR = 0;
prvInitialiseENETBuffers();
/* Set the Reset bit and clear the Enable bit */
ENET_ECR = ENET_ECR_RESET_MASK;
/* Wait at least 8 clock cycles */
for( usData = 0; usData < 10; usData++ )
{
asm( "NOP" );
}
/*FSL: start MII interface*/
mii_init(0, periph_clk_khz/1000/*MHz*/);
//enet_interrupt_routine
set_irq_priority (76, 6);
enable_irq(76);//ENET xmit interrupt
//enet_interrupt_routine
set_irq_priority (77, 6);
enable_irq(77);//ENET rx interrupt
//enet_interrupt_routine
set_irq_priority (78, 6);
enable_irq(78);//ENET error and misc interrupts
/*
* Make sure the external interface signals are enabled
*/
PORTB_PCR0 = PORT_PCR_MUX(4);//GPIO;//RMII0_MDIO/MII0_MDIO
PORTB_PCR1 = PORT_PCR_MUX(4);//GPIO;//RMII0_MDC/MII0_MDC
#if configUSE_MII_MODE
PORTA_PCR14 = PORT_PCR_MUX(4);//RMII0_CRS_DV/MII0_RXDV
PORTA_PCR5 = PORT_PCR_MUX(4);//RMII0_RXER/MII0_RXER
PORTA_PCR12 = PORT_PCR_MUX(4);//RMII0_RXD1/MII0_RXD1
PORTA_PCR13 = PORT_PCR_MUX(4);//RMII0_RXD0/MII0_RXD0
PORTA_PCR15 = PORT_PCR_MUX(4);//RMII0_TXEN/MII0_TXEN
PORTA_PCR16 = PORT_PCR_MUX(4);//RMII0_TXD0/MII0_TXD0
PORTA_PCR17 = PORT_PCR_MUX(4);//RMII0_TXD1/MII0_TXD1
PORTA_PCR11 = PORT_PCR_MUX(4);//MII0_RXCLK
PORTA_PCR25 = PORT_PCR_MUX(4);//MII0_TXCLK
PORTA_PCR9 = PORT_PCR_MUX(4);//MII0_RXD3
PORTA_PCR10 = PORT_PCR_MUX(4);//MII0_RXD2
PORTA_PCR28 = PORT_PCR_MUX(4);//MII0_TXER
PORTA_PCR24 = PORT_PCR_MUX(4);//MII0_TXD2
PORTA_PCR26 = PORT_PCR_MUX(4);//MII0_TXD3
PORTA_PCR27 = PORT_PCR_MUX(4);//MII0_CRS
PORTA_PCR29 = PORT_PCR_MUX(4);//MII0_COL
#else
PORTA_PCR14 = PORT_PCR_MUX(4);//RMII0_CRS_DV/MII0_RXDV
PORTA_PCR5 = PORT_PCR_MUX(4);//RMII0_RXER/MII0_RXER
PORTA_PCR12 = PORT_PCR_MUX(4);//RMII0_RXD1/MII0_RXD1
PORTA_PCR13 = PORT_PCR_MUX(4);//RMII0_RXD0/MII0_RXD0
PORTA_PCR15 = PORT_PCR_MUX(4);//RMII0_TXEN/MII0_TXEN
PORTA_PCR16 = PORT_PCR_MUX(4);//RMII0_TXD0/MII0_TXD0
PORTA_PCR17 = PORT_PCR_MUX(4);//RMII0_TXD1/MII0_TXD1
#endif
/* Can we talk to the PHY? */
do
{
RTOS_DELAY( netifLINK_DELAY );
usData = 0xffff;
mii_read( 0, configPHY_ADDRESS, PHY_PHYIDR1, &usData );
} while( usData == 0xffff );
/* Start auto negotiate. */
mii_write( 0, configPHY_ADDRESS, PHY_BMCR, ( PHY_BMCR_AN_RESTART | PHY_BMCR_AN_ENABLE ) );
/* Wait for auto negotiate to complete. */
do
{
RTOS_DELAY( netifLINK_DELAY );
mii_read( 0, configPHY_ADDRESS, PHY_BMSR, &usData );
} while( !( usData & PHY_BMSR_AN_COMPLETE ) );
/* When we get here we have a link - find out what has been negotiated. */
usData = 0;
mii_read( 0, configPHY_ADDRESS, PHY_STATUS, &usData );
/* Clear the Individual and Group Address Hash registers */
ENET_IALR = 0;
ENET_IAUR = 0;
ENET_GALR = 0;
ENET_GAUR = 0;
/* Set the Physical Address for the selected ENET */
enet_set_address( 0, ucMACAddress );
#if configUSE_MII_MODE
/* Various mode/status setup. */
ENET_RCR = ENET_RCR_MAX_FL(configENET_RX_BUFFER_SIZE) | ENET_RCR_MII_MODE_MASK |
ENET_RCR_CRCFWD_MASK;
#else
ENET_RCR = ENET_RCR_MAX_FL(configENET_RX_BUFFER_SIZE) | ENET_RCR_MII_MODE_MASK |
ENET_RCR_CRCFWD_MASK | ENET_RCR_RMII_MODE_MASK;
#endif
/*FSL: clear rx/tx control registers*/
ENET_TCR = 0;
/* Setup half or full duplex. */
if( usData & PHY_DUPLEX_STATUS )
{
/*Full duplex*/
ENET_RCR &= (unsigned portLONG)~ENET_RCR_DRT_MASK;
ENET_TCR |= ENET_TCR_FDEN_MASK;
}
else
{
/*half duplex*/
ENET_RCR |= ENET_RCR_DRT_MASK;
ENET_TCR &= (unsigned portLONG)~ENET_TCR_FDEN_MASK;
}
/* Setup speed */
if( usData & PHY_SPEED_STATUS )
{
/*10Mbps*/
ENET_RCR |= ENET_RCR_RMII_10T_MASK;
}
#if( configUSE_PROMISCUOUS_MODE == 1 )
{
ENET_RCR |= ENET_RCR_PROM_MASK;
}
#endif
#ifdef ENHANCED_BD
ENET_ECR = ENET_ECR_EN1588_MASK;
#else
ENET_ECR = 0;
#endif
/* Set Rx Buffer Size */
ENET_MRBR = (unsigned portSHORT) configENET_RX_BUFFER_SIZE;
/* Point to the start of the circular Rx buffer descriptor queue */
ENET_RDSR = ( unsigned portLONG ) &( xENETRxDescriptors[ 0 ] );
/* Point to the start of the circular Tx buffer descriptor queue */
ENET_TDSR = ( unsigned portLONG ) xENETTxDescriptors;
/* Clear all ENET interrupt events */
ENET_EIR = ( unsigned portLONG ) -1;
/* Enable interrupts */
ENET_EIMR = ENET_EIR_TXF_MASK | ENET_EIMR_RXF_MASK | ENET_EIMR_RXB_MASK |
ENET_EIMR_UN_MASK | ENET_EIMR_RL_MASK | ENET_EIMR_LC_MASK | ENET_EIMR_BABT_MASK |
ENET_EIMR_BABR_MASK | ENET_EIMR_EBERR_MASK;
/* Create the task that handles the MAC ENET RX */
/* RTOS + TCP/IP stack dependent */
/* Enable the MAC itself. */
ENET_ECR |= ENET_ECR_ETHEREN_MASK;
/* Indicate that there have been empty receive buffers produced */
ENET_RDAR = ENET_RDAR_RDAR_MASK;
}
static void prvInitialiseENETBuffers( void )
{
unsigned portBASE_TYPE ux;
unsigned char *pcBufPointer;
pcBufPointer = &( xENETTxDescriptors_unaligned[ 0 ] );
while( ( ( unsigned long ) pcBufPointer & 0x0fUL ) != 0 )
{
pcBufPointer++;
}
xENETTxDescriptors = ( NBUF * ) pcBufPointer;
pcBufPointer = &( xENETRxDescriptors_unaligned[ 0 ] );
while( ( ( unsigned long ) pcBufPointer & 0x0fUL ) != 0 )
{
pcBufPointer++;
}
xENETRxDescriptors = ( NBUF * ) pcBufPointer;
/* Setup the buffers and descriptors. */
pcBufPointer = &( ucENETTxBuffers[ 0 ] );
while( ( ( unsigned long ) pcBufPointer & 0x0fUL ) != 0 )
{
pcBufPointer++;
}
for( ux = 0; ux < configNUM_ENET_TX_BUFFERS; ux++ )
{
xENETTxDescriptors[ ux ].status = TX_BD_TC;
#ifdef NBUF_LITTLE_ENDIAN
xENETTxDescriptors[ ux ].data = (uint8_t *)__REV((uint32_t)pcBufPointer);
#else
xENETTxDescriptors[ ux ].data = pcBufPointer;
#endif
pcBufPointer += configENET_TX_BUFFER_SIZE;
xENETTxDescriptors[ ux ].length = 0;
#ifdef ENHANCED_BD
xENETTxDescriptors[ ux ].ebd_status = TX_BD_IINS | TX_BD_PINS;
#endif
}
pcBufPointer = &( ucENETRxBuffers[ 0 ] );
while( ( ( unsigned long ) pcBufPointer & 0x0fUL ) != 0 )
{
pcBufPointer++;
}
for( ux = 0; ux < configNUM_ENET_RX_BUFFERS; ux++ )
{
xENETRxDescriptors[ ux ].status = RX_BD_E;
xENETRxDescriptors[ ux ].length = 0;
#ifdef NBUF_LITTLE_ENDIAN
xENETRxDescriptors[ ux ].data = (uint8_t *)__REV((uint32_t)pcBufPointer);
#else
xENETRxDescriptors[ ux ].data = pcBufPointer;
#endif
pcBufPointer += configENET_RX_BUFFER_SIZE;
#ifdef ENHANCED_BD
xENETRxDescriptors[ ux ].bdu = 0x00000000;
xENETRxDescriptors[ ux ].ebd_status = RX_BD_INT;
#endif
}
/* Set the wrap bit in the last descriptors to form a ring. */
xENETTxDescriptors[ configNUM_ENET_TX_BUFFERS - 1 ].status |= TX_BD_W;
xENETRxDescriptors[ configNUM_ENET_RX_BUFFERS - 1 ].status |= RX_BD_W;
uxNextRxBuffer = 0;
uxNextTxBuffer = 0;
}