/* region (origin, length) */
ROM (0x08000000, 256K)
RAM (0x20000000, 40K)
region(SRAM_CCM, 0x10000000, 8K)
/* section (region[, lma_region]) */
text (ROM)
rodata (ROM)
data (RAM, ROM)
bss (RAM)
const struct uart_ops stm32_uart_ops = { .uart_getc = stm32_uart_getc, .uart_putc = stm32_uart_putc, .uart_hasrx = stm32_uart_hasrx, .uart_setup = stm32_uart_setup, }; static struct uart stm32_diag = { .uart_ops = &stm32_uart_ops, .irq_num = USARTx_IRQn, .base_addr = (unsigned long) USARTx, };
uart_setup()
function is not much more complicated, it sets the port parameters. static int stm32_uart_setup(struct uart *dev, const struct uart_params *params) { UART_HandleTypeDef UartHandle; memset(&UartHandle, 0, sizeof(UartHandle)); UartHandle.Instance = (void*) dev->base_addr; UartHandle.Init.BaudRate = params->baud_rate; UartHandle.Init.WordLength = UART_WORDLENGTH_8B; UartHandle.Init.StopBits = UART_STOPBITS_1; UartHandle.Init.Parity = UART_PARITY_NONE; UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE; UartHandle.Init.Mode = UART_MODE_TX_RX; if (HAL_UART_Init(&UartHandle) != HAL_OK) { return -1; } if (dev->params.irq) { /* Enable the UART Data Register not empty Interrupt */ __HAL_UART_ENABLE_IT(&UartHandle, UART_IT_RXNE); } return 0; } static int stm32_uart_putc(struct uart *dev, int ch) { USART_TypeDef *uart = (void *) dev->base_addr; while ((STM32_USART_FLAGS(uart) & USART_FLAG_TXE) == 0); STM32_USART_TXDATA(uart) = (uint8_t) ch; return 0; } static int stm32_uart_hasrx(struct uart *dev) { USART_TypeDef *uart = (void *) dev->base_addr; return STM32_USART_FLAGS(uart) & USART_FLAG_RXNE; } static int stm32_uart_getc(struct uart *dev) { USART_TypeDef *uart = (void *) dev->base_addr; return (uint8_t)(STM32_USART_RXDATA(uart) & 0xFF); }
HAL_UART_MspInit()
for one or another family of controllers. This function is declared as weak in the cube itself and is redefined for a specific example. It is called from HAL_UART_Init()
and, in fact, sets up the I / O pins as needed. void HAL_UART_MspInit(UART_HandleTypeDef *huart) { GPIO_InitTypeDef GPIO_InitStruct; void *uart_base = huart->Instance; /*##-1- Enable peripherals and GPIO Clocks #################################*/ /* Enable GPIO TX/RX clock */ USART_TX_GPIO_CLK_ENABLE(uart_base); USART_RX_GPIO_CLK_ENABLE(uart_base); /* Enable USART2 clock */ USART_CLK_ENABLE(uart_base); /*##-2- Configure peripheral GPIO ##########################################*/ /* UART TX GPIO pin configuration */ GPIO_InitStruct.Pin = USART_TX_PIN(uart_base); GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; GPIO_InitStruct.Alternate = USART_TX_AF(uart_base); HAL_GPIO_Init(USART_TX_GPIO_PORT(uart_base), &GPIO_InitStruct); /* UART RX GPIO pin configuration */ GPIO_InitStruct.Pin = USART_RX_PIN(uart_base); GPIO_InitStruct.Alternate = USART_RX_AF(uart_base); HAL_GPIO_Init(USART_RX_GPIO_PORT(uart_base), &GPIO_InitStruct); }
#define MODOPS_USARTX OPTION_GET(NUMBER, usartx) #if MODOPS_USARTX == 6 #define USARTx USART6 #define USARTx_CLK_ENABLE() __HAL_RCC_USART6_CLK_ENABLE() #define USARTx_RX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOC_CLK_ENABLE() #define USARTx_TX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOC_CLK_ENABLE() #define USARTx_FORCE_RESET() __HAL_RCC_USART6_FORCE_RESET() #define USARTx_RELEASE_RESET() __HAL_RCC_USART6_RELEASE_RESET() /* Definition for USARTx Pins */ #define USARTx_TX_PIN GPIO_PIN_6 #define USARTx_TX_GPIO_PORT GPIOC #define USARTx_TX_AF GPIO_AF8_USART6 #define USARTx_RX_PIN GPIO_PIN_7 #define USARTx_RX_GPIO_PORT GPIOC #define USARTx_RX_AF GPIO_AF8_USART6 /* Definition for USARTx's NVIC */ #define USARTx_IRQn USART6_IRQn + 16 #define USARTx_IRQHandler USART6_IRQHandler #elif MODOPS_USARTX == 2 #define USARTx USART2 #define USARTx_CLK_ENABLE() __HAL_RCC_USART2_CLK_ENABLE() #define USARTx_RX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE() #define USARTx_TX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE() #define USARTx_FORCE_RESET() __HAL_RCC_USART2_FORCE_RESET() #define USARTx_RELEASE_RESET() __HAL_RCC_USART2_RELEASE_RESET() /* Definition for USARTx Pins */ #define USARTx_TX_PIN GPIO_PIN_2 #define USARTx_TX_GPIO_PORT GPIOA #define USARTx_TX_AF GPIO_AF7_USART2 #define USARTx_RX_PIN GPIO_PIN_3 #define USARTx_RX_GPIO_PORT GPIOA #define USARTx_RX_AF GPIO_AF7_USART2 /* Definition for USARTx's NVIC */ #define USARTx_IRQn USART2_IRQn + 16 #define USARTx_IRQHandler USART2_IRQHandler #else #error Unsupported USARTx #endif #define STM32_USART_FLAGS(uart) uart->SR #define STM32_USART_RXDATA(uart) uart->DR #define STM32_USART_TXDATA(uart) uart->DR
#define MODOPS_USARTX OPTION_GET(NUMBER, usartx) #if MODOPS_USARTX == 6 #define USARTx USART6 #define USARTx_CLK_ENABLE() __HAL_RCC_USART6_CLK_ENABLE(); #define USARTx_RX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOC_CLK_ENABLE() #define USARTx_TX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOC_CLK_ENABLE() #define USARTx_FORCE_RESET() __HAL_RCC_USART6_FORCE_RESET() #define USARTx_RELEASE_RESET() __HAL_RCC_USART6_RELEASE_RESET() /* Definition for USARTx Pins */ #define USARTx_TX_PIN GPIO_PIN_6 #define USARTx_TX_GPIO_PORT GPIOC #define USARTx_TX_AF GPIO_AF8_USART6 #define USARTx_RX_PIN GPIO_PIN_7 #define USARTx_RX_GPIO_PORT GPIOC #define USARTx_RX_AF GPIO_AF8_USART6 /* Definition for USARTx's NVIC */ #define USARTx_IRQn USART6_IRQn + 16 #define USARTx_IRQHandler USART6_IRQHandler #elif MODOPS_USARTX == 2 #define USARTx USART2 #define USARTx_CLK_ENABLE() __HAL_RCC_USART2_CLK_ENABLE(); #define USARTx_RX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE() #define USARTx_TX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE() #define USARTx_FORCE_RESET() __HAL_RCC_USART2_FORCE_RESET() #define USARTx_RELEASE_RESET() __HAL_RCC_USART2_RELEASE_RESET() /* Definition for USARTx Pins */ #define USARTx_TX_PIN GPIO_PIN_2 #define USARTx_TX_GPIO_PORT GPIOA #define USARTx_TX_AF GPIO_AF7_USART2 #define USARTx_RX_PIN GPIO_PIN_3 #define USARTx_RX_GPIO_PORT GPIOA #define USARTx_RX_AF GPIO_AF7_USART2 /* Definition for USARTx's NVIC */ #define USARTx_IRQn USART2_IRQn + 16 #define USARTx_IRQHandler USART2_IRQHandler #elif MODOPS_USARTX == 1 #define USARTx USART1 #define USARTx_CLK_ENABLE() __HAL_RCC_USART1_CLK_ENABLE(); #define USARTx_RX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE() #define USARTx_TX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE() #define USARTx_FORCE_RESET() __HAL_RCC_USART1_FORCE_RESET() #define USARTx_RELEASE_RESET() __HAL_RCC_USART1_RELEASE_RESET() /* Definition for USARTx Pins */ #define USARTx_TX_PIN GPIO_PIN_9 #define USARTx_TX_GPIO_PORT GPIOA #define USARTx_TX_AF GPIO_AF7_USART1 #define USARTx_RX_PIN GPIO_PIN_7 #define USARTx_RX_GPIO_PORT GPIOB #define USARTx_RX_AF GPIO_AF7_USART1 /* Definition for USARTx's NVIC */ #define USARTx_IRQn USART1_IRQn + 16 #define USARTx_IRQHandler USART1_IRQHandler #else #error Unsupported USARTx #endif #define STM32_USART_FLAGS(uart) uart->ISR #define STM32_USART_RXDATA(uart) uart->RDR #define STM32_USART_TXDATA(uart) uart->TDR
#define MODOPS_USARTX OPTION_GET(NUMBER, usartx) #if MODOPS_USARTX == 1 #define USARTx USART1 #define USARTx_CLK_ENABLE() __USART1_CLK_ENABLE(); #define USARTx_RX_GPIO_CLK_ENABLE() __GPIOC_CLK_ENABLE() #define USARTx_TX_GPIO_CLK_ENABLE() __GPIOC_CLK_ENABLE() #define USARTx_FORCE_RESET() __USART1_FORCE_RESET() #define USARTx_RELEASE_RESET() __USART1_RELEASE_RESET() /* Definition for USARTx Pins */ #define USARTx_TX_PIN GPIO_PIN_4 #define USARTx_TX_GPIO_PORT GPIOC #define USARTx_TX_AF GPIO_AF7_USART1 #define USARTx_RX_PIN GPIO_PIN_5 #define USARTx_RX_GPIO_PORT GPIOC #define USARTx_RX_AF GPIO_AF7_USART1 /* Definition for USARTx's NVIC */ /* In Embox we assume that the lower external irq number is 0, * but in the cortexm3 it is -15 */ #define USARTx_IRQn USART1_IRQn + 16 #define USARTx_IRQHandler USART1_IRQHandler #elif MODOPS_USARTX == 2 #define USARTx USART2 #define USARTx_CLK_ENABLE() __USART2_CLK_ENABLE(); #define USARTx_RX_GPIO_CLK_ENABLE() __GPIOA_CLK_ENABLE() #define USARTx_TX_GPIO_CLK_ENABLE() __GPIOA_CLK_ENABLE() #define USARTx_FORCE_RESET() __USART2_FORCE_RESET() #define USARTx_RELEASE_RESET() __USART2_RELEASE_RESET() /* Definition for USARTx Pins */ #define USARTx_TX_PIN GPIO_PIN_2 #define USARTx_TX_GPIO_PORT GPIOA #define USARTx_TX_AF GPIO_AF7_USART2 #define USARTx_RX_PIN GPIO_PIN_3 #define USARTx_RX_GPIO_PORT GPIOA #define USARTx_RX_AF GPIO_AF7_USART2 /* Definition for USARTx's NVIC */ /* In Embox we assume that the lower external irq number is 0, * but in the cortexm3 it is -15 */ #define USARTx_IRQn USART2_IRQn + 16 #define USARTx_IRQHandler USART2_IRQHandler #elif MODOPS_USARTX == 3 #define USARTx USART3 #define USARTx_CLK_ENABLE() __USART3_CLK_ENABLE(); #define USARTx_RX_GPIO_CLK_ENABLE() __GPIOB_CLK_ENABLE() #define USARTx_TX_GPIO_CLK_ENABLE() __GPIOB_CLK_ENABLE() #define USARTx_FORCE_RESET() __USART3_FORCE_RESET() #define USARTx_RELEASE_RESET() __USART3_RELEASE_RESET() /* Definition for USARTx Pins */ #define USARTx_TX_PIN GPIO_PIN_10 #define USARTx_TX_GPIO_PORT GPIOB #define USARTx_TX_AF GPIO_AF7_USART3 #define USARTx_RX_PIN GPIO_PIN_11 #define USARTx_RX_GPIO_PORT GPIOB #define USARTx_RX_AF GPIO_AF7_USART3 /* Definition for USARTx's NVIC */ /* In Embox we assume that the lower external irq number is 0, * but in the cortexm3 it is -15 */ #define USARTx_IRQn USART3_IRQn + 16 #define USARTx_IRQHandler USART3_IRQHandler #endif #define STM32_USART_FLAGS(uart) uart->ISR #define STM32_USART_RXDATA(uart) uart->RDR #define STM32_USART_TXDATA(uart) uart->TDR
@Runlevel(1) include embox.driver.serial.stm_ttyS1(baud_rate=57600, usartx=2)
@Runlevel(1) include embox.driver.serial.stm_ttyS0(baud_rate=115200, usartx=6)
uint32_t HAL_GetTick(void)
function in order for the STM32FCube to work correctly, well, and I still had to poke it in the initialization.SystemInit()
and HAL_Init()
from stm32cube and configure clocks for a specific platform. static void SystemClock_Config(void) { RCC_ClkInitTypeDef RCC_ClkInitStruct; RCC_OscInitTypeDef RCC_OscInitStruct; /* Enable Power Control clock */ __HAL_RCC_PWR_CLK_ENABLE(); /* The voltage scaling allows optimizing the power consumption when the device is clocked below the maximum system frequency, to update the voltage scaling value regarding system frequency refer to product datasheet. */ __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); /* Enable HSE Oscillator and activate PLL with HSE as source */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLM = 8; RCC_OscInitStruct.PLL.PLLN = 336; RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; RCC_OscInitStruct.PLL.PLLQ = 7; HAL_RCC_OscConfig(&RCC_OscInitStruct); /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers */ RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5); /* STM32F405x/407x/415x/417x Revision Z devices: prefetch is supported */ if (HAL_GetREVID() == 0x1001) { /* Enable the Flash prefetch */ __HAL_FLASH_PREFETCH_BUFFER_ENABLE(); } }
static void SystemClock_Config(void) { RCC_ClkInitTypeDef RCC_ClkInitStruct; RCC_OscInitTypeDef RCC_OscInitStruct; /* Enable HSE Oscillator and activate PLL with HSE as source */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.HSIState = RCC_HSI_OFF; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLM = 25; RCC_OscInitStruct.PLL.PLLN = 432; RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; RCC_OscInitStruct.PLL.PLLQ = 9; if(HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { printf(">>> SystemClock_Config failed\n"); } /* activate the OverDrive to reach the 216 Mhz Frequency */ if(HAL_PWREx_EnableOverDrive() != HAL_OK) { printf(">>> SystemClock_Config failed\n"); } /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers */ RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; if(HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_7) != HAL_OK) { printf(">>> SystemClock_Config failed\n"); } }
static void SystemClock_Config(void) { RCC_ClkInitTypeDef RCC_ClkInitStruct; RCC_OscInitTypeDef RCC_OscInitStruct; /* Enable HSE Oscillator and activate PLL with HSE as source */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9; if (HAL_RCC_OscConfig(&RCC_OscInitStruct)!= HAL_OK) { // Error_Handler(); } /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers */ RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2)!= HAL_OK) { // Error_Handler(); } }
void HAL_ETH_MspInit(ETH_HandleTypeDef *heth) { /*(##) Enable the Ethernet interface clock using (+++) __HAL_RCC_ETHMAC_CLK_ENABLE(); (+++) __HAL_RCC_ETHMACTX_CLK_ENABLE(); (+++) __HAL_RCC_ETHMACRX_CLK_ENABLE(); (##) Initialize the related GPIO clocks (##) Configure Ethernet pin-out (##) Configure Ethernet NVIC interrupt (IT mode) */ GPIO_InitTypeDef GPIO_InitStructure; /* Enable ETHERNET clock __HAL_RCC_ETHMAC_CLK_ENABLE(); __HAL_RCC_ETHMACTX_CLK_ENABLE(); __HAL_RCC_ETHMACRX_CLK_ENABLE(); */ __HAL_RCC_ETH_CLK_ENABLE(); /* Enable GPIOs clocks */ __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); __HAL_RCC_GPIOC_CLK_ENABLE(); __HAL_RCC_GPIOE_CLK_ENABLE(); /* Ethernet pins configuration ************************************************/ /* ETH_MDIO --------------> PA2 ETH_MDC ---------------> PC1 ETH_RMII_REF_CLK-------> PA1 ETH_RMII_CRS_DV -------> PA7 ETH_MII_RX_ER -------> PB10 ETH_RMII_RXD0 -------> PC4 ETH_RMII_RXD1 -------> PC5 ETH_RMII_TX_EN -------> PB11 ETH_RMII_TXD0 -------> PB12 ETH_RMII_TXD1 -------> PB13 ETH_RST_PIN -------> PE2 */ /* Configure PA1,PA2 and PA7 */ GPIO_InitStructure.Pin = GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_7; GPIO_InitStructure.Speed = GPIO_SPEED_HIGH; GPIO_InitStructure.Mode = GPIO_MODE_AF_PP; GPIO_InitStructure.Pull = GPIO_NOPULL; GPIO_InitStructure.Alternate = GPIO_AF11_ETH; HAL_GPIO_Init(GPIOA, &GPIO_InitStructure); /* Configure PB10,PB11,PB12 and PB13 */ GPIO_InitStructure.Pin = GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13; /* GPIO_InitStructure.Alternate = GPIO_AF11_ETH; */ HAL_GPIO_Init(GPIOB, &GPIO_InitStructure); /* Configure PC1, PC4 and PC5 */ GPIO_InitStructure.Pin = GPIO_PIN_1 | GPIO_PIN_4 | GPIO_PIN_5; /* GPIO_InitStructure.Alternate = GPIO_AF11_ETH; */ HAL_GPIO_Init(GPIOC, &GPIO_InitStructure); if (heth->Init.MediaInterface == ETH_MEDIA_INTERFACE_MII) { /* Output HSE clock (25MHz) on MCO pin (PA8) to clock the PHY */ HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_HSE, RCC_MCODIV_1); } /* Configure the PHY RST pin */ GPIO_InitStructure.Pin = GPIO_PIN_2; GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStructure.Pull = GPIO_PULLUP; GPIO_InitStructure.Speed = GPIO_SPEED_FAST; HAL_GPIO_Init(GPIOE, &GPIO_InitStructure); HAL_GPIO_WritePin(GPIOE, GPIO_PIN_2, GPIO_PIN_RESET); HAL_Delay(1); HAL_GPIO_WritePin(GPIOE, GPIO_PIN_2, GPIO_PIN_SET); HAL_Delay(1); }
void HAL_ETH_MspInit(ETH_HandleTypeDef *heth) { GPIO_InitTypeDef GPIO_InitStructure; /* Enable GPIOs clocks */ __HAL_RCC_GPIOA_CLK_ENABLE() ; __HAL_RCC_GPIOC_CLK_ENABLE() ; __HAL_RCC_GPIOG_CLK_ENABLE(); /* Ethernet pins configuration *****************************************/ /* RMII_REF_CLK ----------------------> PA1 RMII_MDIO -------------------------> PA2 RMII_MDC --------------------------> PC1 RMII_MII_CRS_DV -------------------> PA7 RMII_MII_RXD0 ---------------------> PC4 RMII_MII_RXD1 ---------------------> PC5 RMII_MII_RXER ---------------------> PG2 RMII_MII_TX_EN --------------------> PG11 RMII_MII_TXD0 ---------------------> PG13 RMII_MII_TXD1 ---------------------> PG14 */ /* Configure PA1, PA2 and PA7 */ GPIO_InitStructure.Speed = GPIO_SPEED_HIGH; GPIO_InitStructure.Mode = GPIO_MODE_AF_PP; GPIO_InitStructure.Pull = GPIO_NOPULL; GPIO_InitStructure.Alternate = GPIO_AF11_ETH; GPIO_InitStructure.Pin = GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_7; HAL_GPIO_Init(GPIOA, &GPIO_InitStructure); /* Configure PC1, PC4 and PC5 */ GPIO_InitStructure.Pin = GPIO_PIN_1 | GPIO_PIN_4 | GPIO_PIN_5; HAL_GPIO_Init(GPIOC, &GPIO_InitStructure); /* Configure PG2, PG11, PG13 and PG14 */ GPIO_InitStructure.Pin = GPIO_PIN_2 | GPIO_PIN_11 | GPIO_PIN_13 | GPIO_PIN_14; HAL_GPIO_Init(GPIOG, &GPIO_InitStructure); /* Enable the Ethernet global Interrupt */ HAL_NVIC_SetPriority(ETH_IRQn, 0x7, 0); HAL_NVIC_EnableIRQ(ETH_IRQn); /* Enable ETHERNET clock */ __HAL_RCC_ETH_CLK_ENABLE(); }
static const struct net_driver stm32eth_ops = { .xmit = stm32eth_xmit, .start = stm32eth_open, .set_macaddr = stm32eth_set_mac, };
static int stm32eth_init(void) { int res; struct net_device *nic; nic = (struct net_device *) etherdev_alloc(0); if (nic == NULL) { return -ENOMEM; } nic->drv_ops = &stm32eth_ops; nic->irq = STM32ETH_IRQ; nic->base_addr = ETH_BASE; nic_priv = netdev_priv(nic, struct stm32eth_priv); stm32eth_netdev = nic; res = irq_attach(nic->irq, stm32eth_interrupt, 0, stm32eth_netdev, ""); if (res < 0) { return res; } return inetdev_register_dev(nic); }
static void low_level_init(unsigned char mac[6]) { //uint32_t regvalue; int err; memset(&stm32_eth_handler, 0, sizeof(stm32_eth_handler)); stm32_eth_handler.Instance = (ETH_TypeDef *) ETH_BASE; /* Fill ETH_InitStructure parametrs */ stm32_eth_handler.Init.MACAddr = mac; stm32_eth_handler.Init.AutoNegotiation = ETH_AUTONEGOTIATION_DISABLE; //stm32_eth_handler.Init.AutoNegotiation = ETH_AUTONEGOTIATION_ENABLE; stm32_eth_handler.Init.Speed = ETH_SPEED_100M; stm32_eth_handler.Init.DuplexMode = ETH_MODE_FULLDUPLEX; stm32_eth_handler.Init.MediaInterface = ETH_MEDIA_INTERFACE_RMII; stm32_eth_handler.Init.ChecksumMode = ETH_CHECKSUM_BY_SOFTWARE;//ETH_CHECKSUM_BY_HARDWARE; stm32_eth_handler.Init.PhyAddress = PHY_ADDRESS; stm32_eth_handler.Init.RxMode = ETH_RXINTERRUPT_MODE; if (HAL_OK != (err = HAL_ETH_Init(&stm32_eth_handler))) { log_error("HAL_ETH_Init err %d\n", err); } if (stm32_eth_handler.State == HAL_ETH_STATE_READY) { log_error("STATE_READY sp %d duplex %d\n", stm32_eth_handler.Init.Speed, stm32_eth_handler.Init.DuplexMode); } /*(#)Initialize Ethernet DMA Descriptors in chain mode and point to allocated buffers:*/ HAL_ETH_DMATxDescListInit(&stm32_eth_handler, DMATxDscrTab, &Tx_Buff[0][0], ETH_TXBUFNB); /*for Transmission process*/ if (HAL_OK != (err = HAL_ETH_DMARxDescListInit(&stm32_eth_handler, DMARxDscrTab, &Rx_Buff[0][0], ETH_RXBUFNB))) { /*for Reception process*/ log_error("HAL_ETH_DMARxDescListInit %d\n", err); } /* (#)Enable MAC and DMA transmission and reception: */ HAL_ETH_Start(&stm32_eth_handler); }
static int stm32eth_xmit(struct net_device *dev, struct sk_buff *skb) { __IO ETH_DMADescTypeDef *dma_tx_desc; dma_tx_desc = stm32_eth_handler.TxDesc; memcpy((void *)dma_tx_desc->Buffer1Addr, skb->mac.raw, skb->len); /* Prepare transmit descriptors to give to DMA */ HAL_ETH_TransmitFrame(&stm32_eth_handler, skb->len); skb_free(skb); return 0; }
static irq_return_t stm32eth_interrupt(unsigned int irq_num, void *dev_id) { struct net_device *nic_p = dev_id; struct sk_buff *skb; ETH_HandleTypeDef *heth = &stm32_eth_handler; if (!nic_p) { return IRQ_NONE; } /* Frame received */ if (__HAL_ETH_DMA_GET_FLAG(heth, ETH_DMA_FLAG_R)) { /* Receive complete callback */ while (NULL != (skb = low_level_input())) { skb->dev = nic_p; show_packet(skb->mac.raw, skb->len, "rx"); netif_rx(skb); } /* Clear the Eth DMA Rx IT pending bits */ __HAL_ETH_DMA_CLEAR_IT(heth, ETH_DMA_IT_R); } __HAL_ETH_DMA_CLEAR_IT(heth, ETH_DMA_IT_NIS); return IRQ_HANDLED; }
static struct sk_buff *low_level_input(void) { struct sk_buff *skb; int len; uint8_t *buffer; uint32_t i=0; __IO ETH_DMADescTypeDef *dmarxdesc; skb = NULL; /* get received frame */ if (HAL_ETH_GetReceivedFrame_IT(&stm32_eth_handler) != HAL_OK) return NULL; /* Obtain the size of the packet and put it into the "len" variable. */ len = stm32_eth_handler.RxFrameInfos.length; buffer = (uint8_t *) stm32_eth_handler.RxFrameInfos.buffer; /* We allocate a pbuf chain of pbufs from the Lwip buffer pool */ skb = skb_alloc(len); /* copy received frame to pbuf chain */ if (skb != NULL) { memcpy(skb->mac.raw, buffer, len); } /* Release descriptors to DMA */ dmarxdesc = stm32_eth_handler.RxFrameInfos.FSRxDesc; /* Set Own bit in Rx descriptors: gives the buffers back to DMA */ for (i=0; i< stm32_eth_handler.RxFrameInfos.SegCount; i++) { dmarxdesc->Status |= ETH_DMARXDESC_OWN; dmarxdesc = (ETH_DMADescTypeDef *)(dmarxdesc->Buffer2NextDescAddr); } /* Clear Segment_Count */ stm32_eth_handler.RxFrameInfos.SegCount =0; /* When Rx Buffer unavailable flag is set: clear it and resume reception */ if ((stm32_eth_handler.Instance->DMASR & ETH_DMASR_RBUS) != (uint32_t)RESET) { /* Clear RBUS ETHERNET DMA flag */ stm32_eth_handler.Instance->DMASR = ETH_DMASR_RBUS; /* Resume DMA reception */ stm32_eth_handler.Instance->DMARPDR = 0; } return skb; }
Source: https://habr.com/ru/post/328866/
All Articles