реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> Ethernet на STM32F107, Не могу прочитать входящий пакет
war4one
сообщение Dec 22 2011, 05:49
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 260
Регистрация: 16-07-05
Из: г. Уфа
Пользователь №: 6 851



Имеется схема на контроллере STM32F107 и свиче KSZ8995, свич подключен к контроллеру по MII и SPI.

Что работает: могу обмениваться со свичем информацией по SPI и по MDIO. Со свича идут клоки 25 МГЦ по линиям TX_CLK и RX_CLK, идет информация по линиям RXD0..RXD3, идут стробы по RX_DV. Сам свич "свичует", если подключить Ethernet к портам 1 и 2, можно через такое соединение выходить в интернет, например.

Что не работает: хочу микроконтроллером принять пакет от Ethernet на самом нижнем уровне, без всяких TCP/IP, но не могу. Подозреваю, что дело в программе, что-то я настраиваю неправильно (еще и с DMA никогда не работал, а тут без него никак).
Ниже программа, после настроек я в бесконечном цикле проверяю условие (DMARxDscrTab->Status & ETH_DMARxDesc_OWN) == (u32)RESET, но вхожу в это условие только дважды после старта, потом все.

Прикрепленный файл  ______KSZ8995_STM32.pdf ( 47.83 килобайт ) Кол-во скачиваний: 352

CODE
// Процессор STM32F107VCT6
#include "stm32f10x.h"
#include "stm32_eth.h"

#define ETH_RXBUFNB 8
#define ETH_TXBUFNB 2

__IO uint32_t HSEStatus = 0;
unsigned char temp = 0;
unsigned int inttemp = 0;
uint32_t uint32temp = 0;

void SetSysClockTo72(void); // Инициализируем и раздаем клоки
static void SetSysClockTo72(void);
void InitGPIO(void); // Инициализируем GPIO
void InitNVIC(void); // Инициализируем прерывания
void InitTIM(void); // Инициализируем таймеры
void InitSPI3(void);
void SPI3_WriteByte(unsigned char Data);
unsigned char KSZ8995_ReadByte(unsigned char Address);
void KSZ8995_WriteByte(unsigned char Address, unsigned char Data);

main(void)
{
SetSysClockTo72(); // Инициализируем и раздаем клоки
InitGPIO(); // Инициализируем GPIO
InitNVIC(); // Инициализируем прерывания
InitTIM(); // Инициализируем таймеры
GPIO_PinRemapConfig(GPIO_Remap_SPI3, ENABLE); // Делаем ремап для работы с SPI3
InitSPI3();

GPIO_SetBits(GPIOD, GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12 \
| GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15); // Гасим все светодиоды
GPIO_ResetBits(GPIOD, GPIO_Pin_8); // Зажигаем первый светодиод

GPIO_SetBits(GPIOA, GPIO_Pin_12); // MDI-X_DISABLE в 1

GPIO_SetBits(GPIOE, GPIO_Pin_2); // ETH_PWRDN в 1

GPIO_SetBits(GPIOA, GPIO_Pin_4); // SPI CS

GPIO_SetBits(GPIOE, GPIO_Pin_8); // Reset KSZ8995 (via ETH_DROP pin)
Delay(2000000);
GPIO_ResetBits(GPIOE, GPIO_Pin_8);
Delay(2000000);
GPIO_SetBits(GPIOE, GPIO_Pin_8);
Delay(12000000);

GPIO_SetBits(GPIOE, GPIO_Pin_4); // SCONF0
GPIO_ResetBits(GPIOE, GPIO_Pin_3); // SCONF1
GPIO_ResetBits(GPIOA, GPIO_Pin_5); // LED5-1

temp = KSZ8995_ReadByte(0x00);
if (temp == 0x95) // KSZ8995 подключен и исправен
{
temp = KSZ8995_ReadByte(0x01);
KSZ8995_WriteByte(0x01, temp|1);
temp = KSZ8995_ReadByte(0x01);
}

ETH_InitTypeDef ETH_InitStructure;

// Config Ethernet interface as MII, not RMII
GPIO_ETH_MediaInterfaceConfig(GPIO_ETH_MediaInterface_MII);

// Reset ETHERNET on AHB Bus
ETH_DeInit();

// Software reset
ETH_SoftwareReset();

// Wait for software reset
while(ETH_GetSoftwareResetStatus()==SET);

// Ethernet Configuration
// Call ETH_StructInit if you don't like to configure all ETH_InitStructure parameter
ETH_StructInit(&ETH_InitStructure);

// Fill ETH_InitStructure parametrs
// MAC
ETH_InitStructure.ETH_AutoNegotiation = ETH_AutoNegotiation_Enable;//
ETH_InitStructure.ETH_LoopbackMode = ETH_LoopbackMode_Disable;//
ETH_InitStructure.ETH_RetryTransmission = ETH_RetryTransmission_Disable;//
ETH_InitStructure.ETH_AutomaticPadCRCStrip = ETH_AutomaticPadCRCStrip_Disable;//
ETH_InitStructure.ETH_ReceiveAll = ETH_ReceiveAll_Enable;//
ETH_InitStructure.ETH_BroadcastFramesReception = ETH_BroadcastFramesReception_Enable;//
ETH_InitStructure.ETH_PromiscuousMode = ETH_PromiscuousMode_Disable;//
ETH_InitStructure.ETH_MulticastFramesFilter = ETH_MulticastFramesFilter_Perfect;//
ETH_InitStructure.ETH_UnicastFramesFilter = ETH_UnicastFramesFilter_Perfect;//
ETH_InitStructure.ETH_Mode = ETH_Mode_FullDuplex;//
ETH_InitStructure.ETH_Speed = ETH_Speed_100M;//

unsigned int PhyAddr;
for(PhyAddr = 1; 32 >= PhyAddr; PhyAddr++)
{
if((0x0022 == ETH_ReadPHYRegister(PhyAddr,2)) // PHYID_HIGH
&& (0x1450 == (ETH_ReadPHYRegister(PhyAddr,3)))) // PHYID_LOW
break;
}

/* Configure Ethernet */
uint32temp = ETH_Init(&ETH_InitStructure, PhyAddr);

/* Enable the Ethernet Rx Interrupt */
ETH_DMAITConfig(ETH_DMA_IT_NIS | ETH_DMA_IT_R, ENABLE);


ETH_DMADESCTypeDef DMARxDscrTab[ETH_RXBUFNB], DMATxDscrTab[ETH_TXBUFNB];
u8 Rx_Buff[ETH_RXBUFNB][ETH_MAX_PACKET_SIZE], Tx_Buff[ETH_TXBUFNB][ETH_MAX_PACKET_SIZE];

/* Initialize Tx Descriptors list: Chain Mode */
ETH_DMATxDescChainInit(DMATxDscrTab, &Tx_Buff[0][0], ETH_TXBUFNB);
/* Initialize Rx Descriptors list: Chain Mode */
ETH_DMARxDescChainInit(DMARxDscrTab, &Rx_Buff[0][0], ETH_RXBUFNB);

DMATxDscrTab->ControlBufferSize = 100;
DMARxDscrTab->ControlBufferSize = ETH_MAX_PACKET_SIZE | (1<<14);
DMARxDscrTab->Status = ETH_DMARxDesc_OWN;

/* Enable MAC and DMA transmission and reception */
ETH_Start();

while(1)
{
if((DMARxDscrTab->Status & ETH_DMARxDesc_OWN) == (u32)RESET)
{
ETH_DMAReceptionCmd(DISABLE);


temp = Rx_Buff[0][21];

DMARxDscrTab->Status = ETH_DMARxDesc_OWN;
ETH_DMAReceptionCmd(ENABLE);
}

}

}


void InitGPIO(void) // Инициализируем GPIO
{
GPIO_InitTypeDef GPIO_InitStructure;

// Включаем PA5, 12 на выход (LED51, MDI-X_DISABLE)
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_12;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);

// Включаем PA2 as alternate function push-pull
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);

// Включаем PB5, 8, 11, 12, 13 as alternate function push-pull
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_8 | GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOB, &GPIO_InitStructure);

// Включаем PC1, 2 as alternate function push-pull
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOC, &GPIO_InitStructure);

// Включаем PD8, 9, 10, 11, 12, 13, 14, 15 на выход (светодиоды)
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 |
GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOD, &GPIO_InitStructure);

// Включаем PE2, 3, 4, 8 на выход (ETH_PWRDN, SCONF1, SCONF0, ETH_DROP)
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_8;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOE, &GPIO_InitStructure);
}

void InitNVIC(void) // Инициализируем прерывания
{
/* Set the Vector Table base location at 0x08000000 */
NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);

NVIC_InitTypeDef NVIC_InitStructure;

NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; // Enable the TIM2 Interrupt
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}

void InitTIM(void) // Инициализируем таймеры
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;

TIM_TimeBaseStructure.TIM_Period = 36000; // Таймер 0.5 с
TIM_TimeBaseStructure.TIM_Prescaler = 999;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
TIM_ARRPreloadConfig(TIM2, ENABLE);
TIM_Cmd(TIM2, ENABLE);
TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);
}

void InitSPI3(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
SPI_InitTypeDef SPI_InitStructure;

/* Configure SPI3 pins: SCK and MOSI */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_12;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOC, &GPIO_InitStructure);

/* Configure SPI3 pin MISO */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOC, &GPIO_InitStructure);

/* Configure PA4 pin: CS pin */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);

/* SPI3 Config */
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_128;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init(SPI3, &SPI_InitStructure);

/* SPI3 enable */
SPI_Cmd(SPI3, ENABLE);
}

unsigned char KSZ8995_ReadByte(unsigned char Address)
{
unsigned char SPI3_Read_Data = 0;

GPIO_ResetBits(GPIOA, GPIO_Pin_4); // SPI CS

SPI_I2S_SendData(SPI3, 3); // Send command
while(SPI_I2S_GetFlagStatus(SPI3,SPI_I2S_FLAG_RXNE) != SET);
SPI_I2S_ReceiveData(SPI3);

SPI_I2S_SendData(SPI3, Address); // Read address
while(SPI_I2S_GetFlagStatus(SPI3,SPI_I2S_FLAG_RXNE) != SET);
SPI_I2S_ReceiveData(SPI3);

SPI_I2S_SendData(SPI3, 0); // Push foo
while(SPI_I2S_GetFlagStatus(SPI3,SPI_I2S_FLAG_RXNE) != SET);
SPI3_Read_Data = SPI_I2S_ReceiveData(SPI3);

GPIO_SetBits(GPIOA, GPIO_Pin_4); // SPI CS
//Delay(8000);
return SPI3_Read_Data;
}

void KSZ8995_WriteByte(unsigned char Address, unsigned char Data)
{
GPIO_ResetBits(GPIOA, GPIO_Pin_4); // SPI CS

SPI_I2S_SendData(SPI3, 2); // Send command
while(SPI_I2S_GetFlagStatus(SPI3,SPI_I2S_FLAG_RXNE) != SET);
SPI_I2S_ReceiveData(SPI3);

SPI_I2S_SendData(SPI3, Address); // Send address
while(SPI_I2S_GetFlagStatus(SPI3,SPI_I2S_FLAG_RXNE) != SET);
SPI_I2S_ReceiveData(SPI3);

SPI_I2S_SendData(SPI3, Data); // Send data
while(SPI_I2S_GetFlagStatus(SPI3,SPI_I2S_FLAG_RXNE) != SET);
SPI_I2S_ReceiveData(SPI3);

GPIO_SetBits(GPIOA, GPIO_Pin_4); // SPI CS
}

static void SetSysClockTo72(void)
{
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;

/* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/
/* Enable HSE */
RCC->CR |= ((uint32_t)RCC_CR_HSEON);

/* Wait till HSE is ready and if Time out is reached exit */
do
{
HSEStatus = RCC->CR & RCC_CR_HSERDY;
StartUpCounter++;
} while((HSEStatus == 0) && (StartUpCounter != HSEStartUp_TimeOut));

if ((RCC->CR & RCC_CR_HSERDY) != RESET)
{
HSEStatus = (uint32_t)0x01;
}
else
{
HSEStatus = (uint32_t)0x00;
}

if (HSEStatus == (uint32_t)0x01)
{
/* Enable Prefetch Buffer */
FLASH->ACR |= FLASH_ACR_PRFTBE;

/* Flash 2 wait state */
FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);
FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2;


/* HCLK = SYSCLK */
RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;

/* PCLK2 = HCLK */
RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;

/* PCLK1 = HCLK */
RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;

#ifdef STM32F10X_CL
/* Configure PLLs ------------------------------------------------------*/
/* PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz */
/* PREDIV1 configuration: PREDIV1CLK = PLL2 / 5 = 8 MHz */

RCC->CFGR2 &= (uint32_t)~(RCC_CFGR2_PREDIV2 | RCC_CFGR2_PLL2MUL |
RCC_CFGR2_PREDIV1 | RCC_CFGR2_PREDIV1SRC);
RCC->CFGR2 |= (uint32_t)(RCC_CFGR2_PREDIV2_DIV5 | RCC_CFGR2_PLL2MUL8 |
RCC_CFGR2_PREDIV1SRC_PLL2 | RCC_CFGR2_PREDIV1_DIV5);

/* Enable PLL2 */
RCC->CR |= RCC_CR_PLL2ON;
/* Wait till PLL2 is ready */
while((RCC->CR & RCC_CR_PLL2RDY) == 0)
{
}


/* PLL configuration: PLLCLK = PREDIV1 * 9 = 72 MHz */
RCC->CFGR &= (uint32_t)~(RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL);
RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLSRC_PREDIV1 |
RCC_CFGR_PLLMULL9);
#else
/* PLL configuration: PLLCLK = HSE * 9 = 72 MHz */
RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE |
RCC_CFGR_PLLMULL));
RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL9);
#endif /* STM32F10X_CL */

/* Enable PLL */
RCC->CR |= RCC_CR_PLLON;

/* Wait till PLL is ready */
while((RCC->CR & RCC_CR_PLLRDY) == 0)
{
}

/* Select PLL as system clock source */
RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;

/* Wait till PLL is used as system clock source */
while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08)
{
}

// Включаем тактирование GPIOs & AFIO
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC |
RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE| RCC_APB2Periph_AFIO, ENABLE);

// Включаем тактирование таймера 2 и SPI3
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2 | RCC_APB1Periph_SPI3, ENABLE);

// Включаем тактирование Ethernet
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_ETH_MAC | RCC_AHBPeriph_ETH_MAC_Tx | RCC_AHBPeriph_ETH_MAC_Rx, ENABLE);
}
else
{ /* If HSE fails to start-up, the application will have wrong clock
configuration. User can add here some code to deal with this error */

/* Go to infinite loop */
while (1)
{
}
}
}


Сообщение отредактировал IgorKossak - Dec 22 2011, 06:46
Причина редактирования: [codebox]


--------------------
Электронные устройства Open Hardware
Go to the top of the page
 
+Quote Post
braunevgen
сообщение Mar 16 2017, 15:25
Сообщение #2





Группа: Новичок
Сообщений: 2
Регистрация: 9-11-10
Пользователь №: 60 766



как-то удалось решить вопрос? у меня аналогичная проблема, по spi общаюсь, линки между портами 1 и 2 ходят без проблем, могу с процессора выдать сообщение в сеть, но принять ничего не получается.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Mar 16 2017, 20:55
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 3 205
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(braunevgen @ Mar 16 2017, 17:25) *
как-то удалось решить вопрос? у меня аналогичная проблема, по spi общаюсь, линки между портами 1 и 2 ходят без проблем, могу с процессора выдать сообщение в сеть, но принять ничего не получается.

Выключите всю фильтрацию в MAC. Скажите ему "пропускать всё".
Go to the top of the page
 
+Quote Post
braunevgen
сообщение Mar 20 2017, 08:40
Сообщение #4





Группа: Новичок
Сообщений: 2
Регистрация: 9-11-10
Пользователь №: 60 766



У себя фильтрацию выключил. С другим PHY-драйвером (не коммутатор, а просто один порт Ethernet) все работает без проблем, так что подозреваю, что что-то в KSZ8995 неправильно настроил. Заметил интересную особенность, если опрашивать регистры портов, через которые есть обмен (порт 1 и порт 2), посредством SPI, то в статусных регистрах биты Link Good не установлены. Если опросить регистры MIIM, то в них биты Link Status стоят в 1 (Link is up). Вроде бы противоречие получается
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 27th April 2017 - 16:51
Рейтинг@Mail.ru


Страница сгенерированна за 0.01392 секунд с 7
ELECTRONIX ©2004-2016