- PHY common 0x1D0 buggy identifier added
- serial IO thread added - H7 CMSIS files updated - Ethernet-related commands added - Memory allocations separated
This commit is contained in:
parent
d85f429be0
commit
46ee3099a5
5
.vscode/settings.json
vendored
5
.vscode/settings.json
vendored
@ -1,6 +1,6 @@
|
||||
{
|
||||
"workbench.colorTheme": "CLion Plus Theme",
|
||||
"cortex-debug.variableUseNaturalFormat": true,
|
||||
"cortex-debug.variableUseNaturalFormat": false,
|
||||
"todohighlight.keywords": [
|
||||
"TODO",
|
||||
"FIXME"
|
||||
@ -10,7 +10,8 @@
|
||||
"--query-driver=${config:STM32VSCodeExtension.cubeCLT.path}/GNU-tools-for-STM32/bin/arm-none-eabi-gcc",
|
||||
"--compile-commands-dir=build/debug",
|
||||
"--function-arg-placeholders=false",
|
||||
"--clang-tidy"
|
||||
"--clang-tidy",
|
||||
"--header-insertion=never"
|
||||
],
|
||||
"editor.wordBasedSuggestions": "off"
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -8,21 +8,20 @@
|
||||
* is using in the C source code, usually in main.c. This file contains:
|
||||
* - Configuration section that allows to select:
|
||||
* - The STM32H7xx device used in the target application
|
||||
* - To use or not the peripheral’s drivers in application code(i.e.
|
||||
* code will be based on direct access to peripheral’s registers
|
||||
* - To use or not the peripheral's drivers in application code(i.e.
|
||||
* code will be based on direct access to peripheral's registers
|
||||
* rather than drivers API), this option is controlled by
|
||||
* "#define USE_HAL_DRIVER"
|
||||
*
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2017 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
* Copyright (c) 2017 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
@ -59,7 +58,7 @@
|
||||
*/
|
||||
|
||||
#if !defined (STM32H743xx) && !defined (STM32H753xx) && !defined (STM32H750xx) && !defined (STM32H742xx) && \
|
||||
!defined (STM32H745xx) && !defined (STM32H755xx) && !defined (STM32H747xx) && !defined (STM32H757xx) && \
|
||||
!defined (STM32H745xx) && !defined (STM32H745xG) && !defined (STM32H755xx) && !defined (STM32H747xx) && !defined (STM32H747xG)&& !defined (STM32H757xx) && \
|
||||
!defined (STM32H7A3xx) && !defined (STM32H7A3xxQ) && !defined (STM32H7B3xx) && !defined (STM32H7B3xxQ) && !defined (STM32H7B0xx) && !defined (STM32H7B0xxQ) && \
|
||||
!defined (STM32H735xx) && !defined (STM32H733xx) && !defined (STM32H730xx) && !defined (STM32H730xxQ) && !defined (STM32H725xx) && !defined (STM32H723xx)
|
||||
/* #define STM32H742xx */ /*!< STM32H742VI, STM32H742ZI, STM32H742AI, STM32H742II, STM32H742BI, STM32H742XI Devices */
|
||||
@ -67,10 +66,13 @@
|
||||
/* #define STM32H753xx */ /*!< STM32H753VI, STM32H753ZI, STM32H753AI, STM32H753II, STM32H753BI, STM32H753XI Devices */
|
||||
/* #define STM32H750xx */ /*!< STM32H750V, STM32H750I, STM32H750X Devices */
|
||||
/* #define STM32H747xx */ /*!< STM32H747ZI, STM32H747AI, STM32H747II, STM32H747BI, STM32H747XI Devices */
|
||||
/* #define STM32H747xG */ /*!< STM32H747AG, STM32H747IG, STM32H747BG, STM32H747XG */
|
||||
/* #define STM32H757xx */ /*!< STM32H757ZI, STM32H757AI, STM32H757II, STM32H757BI, STM32H757XI Devices */
|
||||
/* #define STM32H745xx */ /*!< STM32H745ZI, STM32H745II, STM32H745BI, STM32H745XI Devices */
|
||||
/* #define STM32H745xG */ /*!< STM32H745ZG, STM32H745IG, STM32H745BG, STM32H745XG Devices */
|
||||
/* #define STM32H755xx */ /*!< STM32H755ZI, STM32H755II, STM32H755BI, STM32H755XI Devices */
|
||||
/* #define STM32H7B0xx */ /*!< STM32H7B0ABIxQ, STM32H7B0IBTx, STM32H7B0RBTx, STM32H7B0VBTx, STM32H7B0ZBTx, STM32H7B0IBKxQ */
|
||||
/* #define STM32H7B0xx */ /*!< STM32H7B0IBTx, STM32H7B0RBTx, STM32H7B0VBTx, STM32H7B0ZBTx Devices */
|
||||
/* #define STM32H7B0xxQ */ /*!< STM32H7B0ABIxQ, STM32H7B0IBKxQ Devices */
|
||||
/* #define STM32H7A3xx */ /*!< STM32H7A3IIK6, STM32H7A3IIT6, STM32H7A3NIH6, STM32H7A3RIT6, STM32H7A3VIH6, STM32H7A3VIT6, STM32H7A3ZIT6 */
|
||||
/* #define STM32H7A3xxQ */ /*!< STM32H7A3QIY6Q, STM32H7A3IIK6Q, STM32H7A3IIT6Q, STM32H7A3LIH6Q, STM32H7A3VIH6Q, STM32H7A3VIT6Q, STM32H7A3AII6Q, STM32H7A3ZIT6Q */
|
||||
/* #define STM32H7B3xx */ /*!< STM32H7B3IIK6, STM32H7B3IIT6, STM32H7B3NIH6, STM32H7B3RIT6, STM32H7B3VIH6, STM32H7B3VIT6, STM32H7B3ZIT6 */
|
||||
@ -101,11 +103,11 @@
|
||||
#endif /* USE_HAL_DRIVER */
|
||||
|
||||
/**
|
||||
* @brief CMSIS Device version number V1.10.0
|
||||
* @brief CMSIS Device version number V1.10.6
|
||||
*/
|
||||
#define __STM32H7xx_CMSIS_DEVICE_VERSION_MAIN (0x01) /*!< [31:24] main version */
|
||||
#define __STM32H7xx_CMSIS_DEVICE_VERSION_SUB1 (0x0A) /*!< [23:16] sub1 version */
|
||||
#define __STM32H7xx_CMSIS_DEVICE_VERSION_SUB2 (0x00) /*!< [15:8] sub2 version */
|
||||
#define __STM32H7xx_CMSIS_DEVICE_VERSION_SUB2 (0x06) /*!< [15:8] sub2 version */
|
||||
#define __STM32H7xx_CMSIS_DEVICE_VERSION_RC (0x00) /*!< [7:0] release candidate */
|
||||
#define __STM32H7xx_CMSIS_DEVICE_VERSION ((__STM32H7xx_CMSIS_DEVICE_VERSION_MAIN << 24)\
|
||||
|(__STM32H7xx_CMSIS_DEVICE_VERSION_SUB1 << 16)\
|
||||
@ -130,10 +132,14 @@
|
||||
#include "stm32h742xx.h"
|
||||
#elif defined(STM32H745xx)
|
||||
#include "stm32h745xx.h"
|
||||
#elif defined(STM32H745xG)
|
||||
#include "stm32h745xg.h"
|
||||
#elif defined(STM32H755xx)
|
||||
#include "stm32h755xx.h"
|
||||
#elif defined(STM32H747xx)
|
||||
#include "stm32h747xx.h"
|
||||
#elif defined(STM32H747xG)
|
||||
#include "stm32h747xg.h"
|
||||
#elif defined(STM32H757xx)
|
||||
#include "stm32h757xx.h"
|
||||
#elif defined(STM32H7B0xx)
|
||||
@ -214,6 +220,60 @@ typedef enum
|
||||
|
||||
#define POSITION_VAL(VAL) (__CLZ(__RBIT(VAL)))
|
||||
|
||||
/* Use of CMSIS compiler intrinsics for register exclusive access */
|
||||
/* Atomic 32-bit register access macro to set one or several bits */
|
||||
#define ATOMIC_SET_BIT(REG, BIT) \
|
||||
do { \
|
||||
uint32_t val; \
|
||||
do { \
|
||||
val = __LDREXW((__IO uint32_t *)&(REG)) | (BIT); \
|
||||
} while ((__STREXW(val,(__IO uint32_t *)&(REG))) != 0U); \
|
||||
} while(0)
|
||||
|
||||
/* Atomic 32-bit register access macro to clear one or several bits */
|
||||
#define ATOMIC_CLEAR_BIT(REG, BIT) \
|
||||
do { \
|
||||
uint32_t val; \
|
||||
do { \
|
||||
val = __LDREXW((__IO uint32_t *)&(REG)) & ~(BIT); \
|
||||
} while ((__STREXW(val,(__IO uint32_t *)&(REG))) != 0U); \
|
||||
} while(0)
|
||||
|
||||
/* Atomic 32-bit register access macro to clear and set one or several bits */
|
||||
#define ATOMIC_MODIFY_REG(REG, CLEARMSK, SETMASK) \
|
||||
do { \
|
||||
uint32_t val; \
|
||||
do { \
|
||||
val = (__LDREXW((__IO uint32_t *)&(REG)) & ~(CLEARMSK)) | (SETMASK); \
|
||||
} while ((__STREXW(val,(__IO uint32_t *)&(REG))) != 0U); \
|
||||
} while(0)
|
||||
|
||||
/* Atomic 16-bit register access macro to set one or several bits */
|
||||
#define ATOMIC_SETH_BIT(REG, BIT) \
|
||||
do { \
|
||||
uint16_t val; \
|
||||
do { \
|
||||
val = __LDREXH((__IO uint16_t *)&(REG)) | (BIT); \
|
||||
} while ((__STREXH(val,(__IO uint16_t *)&(REG))) != 0U); \
|
||||
} while(0)
|
||||
|
||||
/* Atomic 16-bit register access macro to clear one or several bits */
|
||||
#define ATOMIC_CLEARH_BIT(REG, BIT) \
|
||||
do { \
|
||||
uint16_t val; \
|
||||
do { \
|
||||
val = __LDREXH((__IO uint16_t *)&(REG)) & ~(BIT); \
|
||||
} while ((__STREXH(val,(__IO uint16_t *)&(REG))) != 0U); \
|
||||
} while(0)
|
||||
|
||||
/* Atomic 16-bit register access macro to clear and set one or several bits */
|
||||
#define ATOMIC_MODIFYH_REG(REG, CLEARMSK, SETMASK) \
|
||||
do { \
|
||||
uint16_t val; \
|
||||
do { \
|
||||
val = (__LDREXH((__IO uint16_t *)&(REG)) & ~(CLEARMSK)) | (SETMASK); \
|
||||
} while ((__STREXH(val,(__IO uint16_t *)&(REG))) != 0U); \
|
||||
} while(0)
|
||||
|
||||
/**
|
||||
* @}
|
||||
@ -240,4 +300,3 @@ typedef enum
|
||||
|
||||
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
||||
@ -6,13 +6,12 @@
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2017 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
* Copyright (c) 2017 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
@ -85,6 +84,7 @@ extern const uint8_t D1CorePrescTable[16] ; /*!< D1CorePrescTable prescalers ta
|
||||
|
||||
extern void SystemInit(void);
|
||||
extern void SystemCoreClockUpdate(void);
|
||||
extern void ExitRun0Mode(void);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
@ -102,4 +102,3 @@ extern void SystemCoreClockUpdate(void);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
#include <stdint.h>
|
||||
#include <stm32h7xx_hal.h>
|
||||
|
||||
#include "cmsis_os2.h"
|
||||
#include "lwip/arch.h"
|
||||
#include "lwip/err.h"
|
||||
#include "lwip/etharp.h"
|
||||
@ -51,78 +52,52 @@ struct {
|
||||
// ---------- Global objects -----------
|
||||
// -------------------------------------
|
||||
|
||||
static EXTI_HandleTypeDef hEXTI0;
|
||||
|
||||
static void process_phy_event();
|
||||
|
||||
static struct netif *if0;
|
||||
|
||||
static LinkState linkState = {false, 0, false};
|
||||
static LinkState linkState = {false, false, 0, false};
|
||||
|
||||
static void ethdrv_init_misc_pins() {
|
||||
__HAL_RCC_GPIOB_CLK_ENABLE();
|
||||
|
||||
// initialize PB0 as input
|
||||
GPIO_InitTypeDef gpioInit;
|
||||
gpioInit.Speed = GPIO_SPEED_FREQ_MEDIUM;
|
||||
gpioInit.Mode = GPIO_MODE_IT_FALLING;
|
||||
gpioInit.Pull = GPIO_PULLUP;
|
||||
gpioInit.Pin = GPIO_PIN_0;
|
||||
HAL_GPIO_Init(GPIOB, &gpioInit);
|
||||
|
||||
// setup EXTI0 multiplexer
|
||||
EXTI_ConfigTypeDef extiConf;
|
||||
extiConf.Line = EXTI_LINE_0;
|
||||
extiConf.GPIOSel = EXTI_GPIOB;
|
||||
extiConf.Trigger = EXTI_TRIGGER_FALLING;
|
||||
extiConf.Mode = EXTI_MODE_INTERRUPT;
|
||||
HAL_EXTI_SetConfigLine(&hEXTI0, &extiConf);
|
||||
|
||||
// enable interrupt source
|
||||
HAL_NVIC_SetPriority(EXTI0_IRQn, 12, 0); // some medium-low priority
|
||||
HAL_NVIC_EnableIRQ(EXTI0_IRQn);
|
||||
}
|
||||
static osThreadId_t th;
|
||||
|
||||
static void fetch_link_properties() {
|
||||
const PHY_LinkStatus *status = phy_get_link_status();
|
||||
|
||||
// set link up/down state
|
||||
linkState.up = status->up;
|
||||
if ((linkState.up != status->up) || (!linkState.init)) {
|
||||
linkState.up = status->up;
|
||||
|
||||
if (linkState.up) {
|
||||
bool fe = status->speed == PHY_LS_100Mbps;
|
||||
bool duplex = status->type == PHY_LT_FULL_DUPLEX;
|
||||
ETHHW_SetLinkProperties(ETH, fe, duplex);
|
||||
if (linkState.up) {
|
||||
bool fe = status->speed == PHY_LS_100Mbps;
|
||||
bool duplex = status->type == PHY_LT_FULL_DUPLEX;
|
||||
ETHHW_SetLinkProperties(ETH, fe, duplex);
|
||||
|
||||
// convert "Fast Ethernet" to numerical speed value
|
||||
linkState.speed = (status->speed == PHY_LS_100Mbps) ? 100 : 10;
|
||||
// convert "Fast Ethernet" to numerical speed value
|
||||
linkState.speed = (status->speed == PHY_LS_100Mbps) ? 100 : 10;
|
||||
|
||||
// save duplex field
|
||||
linkState.duplex = duplex;
|
||||
// save duplex field
|
||||
linkState.duplex = duplex;
|
||||
}
|
||||
|
||||
// invoke link change notification callback
|
||||
if (linkState.up) {
|
||||
// MSG("UP!\n");
|
||||
netif_set_link_up(if0);
|
||||
} else {
|
||||
netif_set_link_down(if0);
|
||||
// MSG("DOWN!\n");
|
||||
}
|
||||
}
|
||||
|
||||
// invoke link change notification callback
|
||||
if (linkState.up) {
|
||||
MSG("UP!\n");
|
||||
netif_set_link_up(if0);
|
||||
} else {
|
||||
netif_set_link_down(if0);
|
||||
MSG("DOWN!\n");
|
||||
}
|
||||
linkState.init = true;
|
||||
}
|
||||
|
||||
static void process_phy_event() {
|
||||
PHY_Event evt = phy_get_event(); // get event
|
||||
if (evt != PHYEVENT_NO_EVENT) {
|
||||
// if link is up, then set link properties accordingly
|
||||
static void phy_thread(void *arg) {
|
||||
while (true) {
|
||||
fetch_link_properties();
|
||||
osDelay(500);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void EXTI0_IRQHandler() {
|
||||
HAL_EXTI_ClearPending(&hEXTI0, EXTI_TRIGGER_FALLING); // clear interrupt
|
||||
process_phy_event();
|
||||
}
|
||||
// ------------------------------
|
||||
|
||||
/* Define those to better describe your network interface. */
|
||||
@ -140,9 +115,6 @@ static void ethernetif_input(struct netif *netif);
|
||||
* for this ethernetif
|
||||
*/
|
||||
static void low_level_init(struct netif *netif) {
|
||||
// ------- PHY IRQ initialization ----------
|
||||
ethdrv_init_misc_pins();
|
||||
|
||||
// ------- Ethernet MAC initialization -----
|
||||
|
||||
ETHHW_InitOpts opts = {
|
||||
@ -162,7 +134,13 @@ static void low_level_init(struct netif *netif) {
|
||||
ETHHW_Start(ETH);
|
||||
|
||||
// -------- Process PHY events occured during the initialization phase
|
||||
process_phy_event();
|
||||
|
||||
// start PHY event processing thread
|
||||
osThreadAttr_t attr;
|
||||
memset(&attr, 0, sizeof(attr));
|
||||
attr.stack_size = 2048;
|
||||
attr.name = "phy";
|
||||
th = osThreadNew(phy_thread, NULL, &attr);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
@ -405,9 +383,15 @@ err_t ethernetif_init(struct netif *netif) {
|
||||
/* start up the interface */
|
||||
netif_set_up(netif);
|
||||
|
||||
/* refresh and fetch PHY and link status */
|
||||
/* refresh and fetch PHY and link status */
|
||||
phy_refresh_link_status();
|
||||
fetch_link_properties();
|
||||
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
// -----
|
||||
|
||||
void ETH_IRQHandler() {
|
||||
ETHHW_ISR(ETH);
|
||||
}
|
||||
@ -5,6 +5,7 @@
|
||||
#include <stdbool.h>
|
||||
|
||||
typedef struct {
|
||||
bool init;
|
||||
bool up;
|
||||
uint16_t speed;
|
||||
bool duplex;
|
||||
|
||||
@ -22,7 +22,6 @@ static void ETHHW_InitClocks() {
|
||||
__HAL_RCC_GPIOA_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOB_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOC_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOG_CLK_ENABLE();
|
||||
|
||||
/* Ethernet pins configuration
|
||||
* ************************************************/
|
||||
@ -33,9 +32,9 @@ static void ETHHW_InitClocks() {
|
||||
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_RXER ---------------------> PB10)
|
||||
RMII_MII_TX_EN --------------------> PB11
|
||||
RMII_MII_TXD0 ---------------------> PB12
|
||||
RMII_MII_TXD1 ---------------------> PB13
|
||||
*/
|
||||
|
||||
@ -55,9 +54,9 @@ static void ETHHW_InitClocks() {
|
||||
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;
|
||||
HAL_GPIO_Init(GPIOG, &GPIO_InitStructure);
|
||||
/* Configure PB10, PB11, PB12 and PB13 */
|
||||
GPIO_InitStructure.Pin = GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13;
|
||||
HAL_GPIO_Init(GPIOB, &GPIO_InitStructure);
|
||||
|
||||
/* Enable the Ethernet global Interrupt */
|
||||
HAL_NVIC_SetPriority(ETH_IRQn, 0x7, 0);
|
||||
@ -335,7 +334,7 @@ static void ETHHW_PrintRingBufStatus(ETH_TypeDef *eth,
|
||||
|
||||
// process incoming packet
|
||||
void ETHHW_ProcessRx(ETH_TypeDef *eth) {
|
||||
// ETHHW_PrintRingBufStatus(eth, ETHHW_RINGBUF_RX);
|
||||
//ETHHW_PrintRingBufStatus(eth, ETHHW_RINGBUF_RX);
|
||||
|
||||
ETHHW_DescFull *ring = (ETHHW_DescFull *)eth->DMACRDLAR;
|
||||
uint16_t ringLen = eth->DMACRDRLR + 1;
|
||||
@ -517,7 +516,7 @@ void ETHHW_Transmit(ETH_TypeDef *eth, const uint8_t *buf, uint16_t len, uint8_t
|
||||
bd->desc.DES2 = opts | (len & 0x3FFF); // {IOC|TTSE} and buffer length truncated to 14-bits
|
||||
bd->desc.DES3 = ETH_DMATXNDESCRF_OWN | ETH_DMATXNDESCRF_FD | ETH_DMATXNDESCRF_LD | ETH_DMATXNDESCRF_CIC_IPHDR_PAYLOAD_INSERT_PHDR_CALC; // pass desciptor to the DMA, set First Desc. and Last Desc. flags
|
||||
|
||||
// ETHHW_PrintRingBufStatus(eth, ETHHW_RINGBUF_TX);
|
||||
//ETHHW_PrintRingBufStatus(eth, ETHHW_RINGBUF_TX);
|
||||
|
||||
state->nextTxDescIdx = (state->nextTxDescIdx + 1) % (eth->DMACTDRLR + 1); // advance index to next descriptor
|
||||
|
||||
|
||||
@ -20,11 +20,13 @@ static struct {
|
||||
} phyId = {0};
|
||||
static const char *phyName = NULL; // printable PHY name
|
||||
|
||||
typedef void (*phyIntSetupFn)(); // typedef for PHY interrupt setup function
|
||||
typedef int (*phyIntHandlerFn)(); // typedef for PHY interrupt handling
|
||||
typedef void (*phyIntSetupFn)(); // typedef for PHY interrupt setup function
|
||||
typedef int (*phyIntHandlerFn)(); // typedef for PHY interrupt handling
|
||||
typedef void (*phyFetchLinkStatus)(PHY_LinkStatus *ls); // typedef for link status fetching
|
||||
|
||||
static phyIntSetupFn phyIntSetupCb = NULL; // PHY interrupt setup callback
|
||||
static phyIntHandlerFn phyIntHandlerCb = NULL; // PHY interrupt handler callback
|
||||
static phyIntSetupFn phyIntSetupCb = NULL; // PHY interrupt setup callback
|
||||
static phyIntHandlerFn phyIntHandlerCb = NULL; // PHY interrupt handler callback
|
||||
static phyFetchLinkStatus phyFetchLinkStatusCb = NULL; // fetch link status callback
|
||||
static uint32_t macModeInit = MODEINIT_FULL_DUPLEX | MODEINIT_SPEED_100MBPS; // default mode: 100Mbps FD
|
||||
|
||||
// -------------------------
|
||||
@ -76,27 +78,29 @@ static int phy_sweep_addresses(uint32_t addr0) {
|
||||
static void phy_setup_int_DP83848() {
|
||||
// clear possible interrupts
|
||||
uint32_t regVal;
|
||||
ETHHW_ReadPHYRegister(phyEth, phyAddr, EPHY_DP83848_MISR, ®Val);
|
||||
READ(EPHY_DP83848_MISR, regVal);
|
||||
|
||||
// enable relevant interrupt sources
|
||||
regVal = EPHY_DP83848_MISR_LINK_INT_EN | EPHY_DP83848_MISR_ANC_INT_EN;
|
||||
ETHHW_WritePHYRegister(phyEth, phyAddr, EPHY_DP83848_MISR, regVal);
|
||||
WRITE(EPHY_DP83848_MISR, regVal);
|
||||
|
||||
// global enable interrupts
|
||||
regVal = EPHY_DP83848_MICR_INT_OE | EPHY_DP83848_MICR_INTEN;
|
||||
ETHHW_WritePHYRegister(phyEth, phyAddr, EPHY_DP83848_MICR, regVal);
|
||||
READ(EPHY_DP83848_MICR, regVal);
|
||||
}
|
||||
|
||||
static void phy_fetch_link_status_DP83848(PHY_LinkStatus *ls) {
|
||||
// read and clear interrupt status
|
||||
uint32_t regVal;
|
||||
ETHHW_ReadPHYRegister(phyEth, phyAddr, EPHY_DP83848_PHYSTS, ®Val);
|
||||
READ(EPHY_DP83848_PHYSTS, regVal);
|
||||
|
||||
// set link status flags
|
||||
ls->speed =
|
||||
(regVal & EPHY_DP83848_SPEED_STATUS) ? PHY_LS_10Mbps : PHY_LS_100Mbps;
|
||||
ls->type = (regVal & EPHY_DP83848_DUPLEX_STATUS) ? PHY_LT_FULL_DUPLEX
|
||||
: PHY_LT_HALF_DUPLEX;
|
||||
// fetch link status flags
|
||||
ls->speed = (regVal & EPHY_DP83848_SPEED_STATUS) ? PHY_LS_10Mbps : PHY_LS_100Mbps;
|
||||
ls->type = (regVal & EPHY_DP83848_DUPLEX_STATUS) ? PHY_LT_FULL_DUPLEX : PHY_LT_HALF_DUPLEX;
|
||||
|
||||
// fetch link state
|
||||
READ(EPHY_BSR, regVal);
|
||||
ls->up = (regVal & EPHY_BSR_LINK_STATUS);
|
||||
}
|
||||
|
||||
static int phy_int_handler_DP83848() {
|
||||
@ -124,21 +128,22 @@ static void phy_setup_int_LAN8720A() {
|
||||
ETHHW_WritePHYRegister(phyEth, phyAddr, EPHY_BCR, regVal); */
|
||||
|
||||
// enable relevant interrupt sources
|
||||
uint32_t regVal =
|
||||
EPHY_LAN8720A_IMR_ANC_INT_EN | EPHY_LAN8720A_IMR_ENERGYON_INT_EN;
|
||||
ETHHW_WritePHYRegister(phyEth, phyAddr, EPHY_LAN8720A_IMR, regVal);
|
||||
uint32_t regVal = EPHY_LAN8720A_IMR_ANC_INT_EN | EPHY_LAN8720A_IMR_ENERGYON_INT_EN;
|
||||
WRITE(EPHY_LAN8720A_IMR, regVal);
|
||||
}
|
||||
|
||||
static void phy_fetch_link_status_LAN8720A(PHY_LinkStatus *ls) {
|
||||
// read register containing link state
|
||||
uint32_t regVal;
|
||||
ETHHW_ReadPHYRegister(phyEth, phyAddr, EPHY_LAN8720A_SCSR, ®Val);
|
||||
READ(EPHY_LAN8720A_SCSR, regVal);
|
||||
|
||||
// set link status flags
|
||||
ls->speed =
|
||||
(regVal & EPHY_LAN8720A_SCSR_100MBPS) ? PHY_LS_100Mbps : PHY_LS_10Mbps;
|
||||
ls->type = (regVal & EPHY_LAN8720A_SCSR_FULL_DUPLEX) ? PHY_LT_FULL_DUPLEX
|
||||
: PHY_LT_HALF_DUPLEX;
|
||||
// fetch link status flags
|
||||
ls->speed = (regVal & EPHY_LAN8720A_SCSR_100MBPS) ? PHY_LS_100Mbps : PHY_LS_10Mbps;
|
||||
ls->type = (regVal & EPHY_LAN8720A_SCSR_FULL_DUPLEX) ? PHY_LT_FULL_DUPLEX : PHY_LT_HALF_DUPLEX;
|
||||
|
||||
// fetch link state
|
||||
READ(EPHY_BSR, regVal);
|
||||
ls->up = (regVal & EPHY_BSR_LINK_STATUS);
|
||||
}
|
||||
|
||||
static int phy_int_handler_LAN8720A() {
|
||||
@ -191,10 +196,12 @@ static void phy_fetch_link_status_RTL8201F(PHY_LinkStatus *ls) {
|
||||
READ(EPHY_BCR, regVal);
|
||||
|
||||
// set link status flags
|
||||
ls->speed =
|
||||
(regVal & EPHY_BCR_SPEED_SELECTION) ? PHY_LS_100Mbps : PHY_LS_10Mbps;
|
||||
ls->type =
|
||||
(regVal & EPHY_BCR_DUPLEX_MODE) ? PHY_LT_FULL_DUPLEX : PHY_LT_HALF_DUPLEX;
|
||||
ls->speed = (regVal & EPHY_BCR_SPEED_SELECTION) ? PHY_LS_100Mbps : PHY_LS_10Mbps;
|
||||
ls->type = (regVal & EPHY_BCR_DUPLEX_MODE) ? PHY_LT_FULL_DUPLEX : PHY_LT_HALF_DUPLEX;
|
||||
|
||||
// fetch link state
|
||||
READ(EPHY_BSR, regVal);
|
||||
ls->up = (regVal & EPHY_BSR_LINK_STATUS);
|
||||
|
||||
return;
|
||||
}
|
||||
@ -230,13 +237,13 @@ static void phy_setup_int_DP83TC813() {
|
||||
|
||||
// enable link status interrupt
|
||||
regVal = EPHY_DP83TC813_MISR1_LINK_INT_EN;
|
||||
ETHHW_WritePHYRegister(phyEth, phyAddr, EPHY_DP83TC813_MISR1, regVal);
|
||||
WRITE(EPHY_DP83TC813_MISR1, regVal);
|
||||
|
||||
// turn on master mode
|
||||
WRITE(EPHY_DP83TC813_REGCR, 0x01);
|
||||
WRITE(EPHY_DP83TC813_ADDAR, EPHY_DP83TC813_MMD1_PMA_CTRL_2);
|
||||
WRITE(EPHY_DP83TC813_REGCR, 0x4001);
|
||||
WRITE(EPHY_DP83TC813_ADDAR, EPHY_DP83TC813_MMD1_PMA_CTRL_2_MS_CFG);
|
||||
// WRITE(EPHY_DP83TC813_REGCR, 0x01);
|
||||
// WRITE(EPHY_DP83TC813_ADDAR, EPHY_DP83TC813_MMD1_PMA_CTRL_2);
|
||||
// WRITE(EPHY_DP83TC813_REGCR, 0x4001);
|
||||
// WRITE(EPHY_DP83TC813_ADDAR, EPHY_DP83TC813_MMD1_PMA_CTRL_2_MS_CFG);
|
||||
|
||||
return;
|
||||
}
|
||||
@ -244,15 +251,18 @@ static void phy_setup_int_DP83TC813() {
|
||||
static void phy_fetch_link_status_DP83TC813(PHY_LinkStatus *ls) {
|
||||
// read and clear interrupt status
|
||||
uint32_t regVal;
|
||||
ETHHW_ReadPHYRegister(phyEth, phyAddr, EPHY_DP83TC813_MISR1, ®Val);
|
||||
READ(EPHY_DP83TC813_MISR1, regVal);
|
||||
|
||||
// read basic control register
|
||||
ETHHW_ReadPHYRegister(phyEth, phyAddr, EPHY_BCR, ®Val);
|
||||
READ(EPHY_BCR, regVal);
|
||||
|
||||
// set link status flags
|
||||
ls->speed = PHY_LS_100Mbps; // this PHY is only capable of 100Mbps
|
||||
ls->type =
|
||||
(regVal & EPHY_BCR_DUPLEX_MODE) ? PHY_LT_FULL_DUPLEX : PHY_LT_HALF_DUPLEX;
|
||||
ls->type = (regVal & EPHY_BCR_DUPLEX_MODE) ? PHY_LT_FULL_DUPLEX : PHY_LT_HALF_DUPLEX;
|
||||
|
||||
// fetch link state
|
||||
READ(EPHY_BSR, regVal);
|
||||
ls->up = (regVal & EPHY_BSR_LINK_STATUS);
|
||||
|
||||
return;
|
||||
}
|
||||
@ -286,6 +296,7 @@ static void phy_setup_int_LAN8670() {
|
||||
|
||||
static void phy_fetch_link_status_LAN8670(PHY_LinkStatus *ls) {
|
||||
// link is always 10Mbps HALF duplex
|
||||
ls->up = true;
|
||||
ls->speed = PHY_LS_10Mbps;
|
||||
ls->type = PHY_LT_HALF_DUPLEX;
|
||||
return;
|
||||
@ -303,17 +314,13 @@ static void phy_setup_int_DP83TD510E() {
|
||||
WRITE(EPHY_DP83TD510E_REGCR, 0x1F);
|
||||
WRITE(EPHY_DP83TD510E_ADDAR, EPHY_DP83TD510E_LEDS_CFG2);
|
||||
WRITE(EPHY_DP83TD510E_REGCR, 0x4001);
|
||||
WRITE(EPHY_DP83TD510E_ADDAR, EPHY_DP83TD510E_LEDS_CFG2_LED_1_POLARITY |
|
||||
EPHY_DP83TD510E_LEDS_CFG2_LED_0_POLARITY);
|
||||
WRITE(EPHY_DP83TD510E_ADDAR, EPHY_DP83TD510E_LEDS_CFG2_LED_1_POLARITY | EPHY_DP83TD510E_LEDS_CFG2_LED_0_POLARITY);
|
||||
|
||||
// enable Link Change Interrupt
|
||||
WRITE(EPHY_DP83TD510E_INTERRUPT_REG_1,
|
||||
EPHY_DP83TD510E_INTERRUPT_REG_1_LINK_INT_EN);
|
||||
WRITE(EPHY_DP83TD510E_INTERRUPT_REG_1, EPHY_DP83TD510E_INTERRUPT_REG_1_LINK_INT_EN);
|
||||
|
||||
// select INT functionality on PWDN pin and globally enable interrupts
|
||||
READ_MODIFY_WRITE(EPHY_DP83TD510E_GEN_CFG,
|
||||
EPHY_DP83TD510E_GEN_CFG_INT_EN |
|
||||
EPHY_DP83TD510E_GEN_CFG_INT_OE);
|
||||
READ_MODIFY_WRITE(EPHY_DP83TD510E_GEN_CFG, EPHY_DP83TD510E_GEN_CFG_INT_EN | EPHY_DP83TD510E_GEN_CFG_INT_OE);
|
||||
}
|
||||
|
||||
static void phy_fetch_link_status_DP83TD510E(PHY_LinkStatus *ls) {
|
||||
@ -324,6 +331,11 @@ static void phy_fetch_link_status_DP83TD510E(PHY_LinkStatus *ls) {
|
||||
// link is always 10Mbps HALF duplex
|
||||
ls->speed = PHY_LS_10Mbps;
|
||||
ls->type = (regVal & EPHY_BCR_DUPLEX_MODE) ? PHY_LT_FULL_DUPLEX : PHY_LT_HALF_DUPLEX;
|
||||
|
||||
// fetch link state
|
||||
READ(EPHY_BSR, regVal);
|
||||
ls->up = (regVal & EPHY_BSR_LINK_STATUS);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -351,10 +363,6 @@ static int phy_int_handler_DP83TD510E() {
|
||||
return PHYEVENT_NO_EVENT;
|
||||
}
|
||||
|
||||
|
||||
#define phy_setup_int_LAN8742A phy_setup_int_LAN8720A
|
||||
#define phy_int_handler_LAN8742A phy_int_handler_LAN8720A
|
||||
|
||||
// --------------------------
|
||||
|
||||
static bool phy_populate_handlers() {
|
||||
@ -365,16 +373,19 @@ static bool phy_populate_handlers() {
|
||||
switch (phyId.model) {
|
||||
case EPHY_MODEL_DP83848:
|
||||
phyName = "Texas Instruments DP83848";
|
||||
phyFetchLinkStatusCb = phy_fetch_link_status_DP83848;
|
||||
phyIntSetupCb = phy_setup_int_DP83848;
|
||||
phyIntHandlerCb = phy_int_handler_DP83848;
|
||||
break;
|
||||
case EPHY_MODEL_DP83TC813:
|
||||
phyName = "Texas Instruments DP83TC813";
|
||||
phyFetchLinkStatusCb = phy_fetch_link_status_DP83TC813;
|
||||
phyIntSetupCb = phy_setup_int_DP83TC813;
|
||||
phyIntHandlerCb = phy_int_handler_DP83TC813;
|
||||
break;
|
||||
case EPHY_MODEL_DP83TD510E:
|
||||
phyName = "Texas Instruments DP83TD510E";
|
||||
phyFetchLinkStatusCb = phy_fetch_link_status_DP83TD510E;
|
||||
phyIntSetupCb = phy_setup_int_DP83TD510E;
|
||||
phyIntHandlerCb = phy_int_handler_DP83TD510E;
|
||||
macModeInit = MODEINIT_HALF_DUPLEX | MODEINIT_SPEED_10MBPS;
|
||||
@ -384,19 +395,18 @@ static bool phy_populate_handlers() {
|
||||
break;
|
||||
|
||||
case EPHY_OUI_SMSC: // SMSC PHYs
|
||||
case 0x1D0: // FIXME: it's a bug with the H735 Discovery board
|
||||
switch (phyId.model) {
|
||||
case EPHY_MODEL_LAN8720A:
|
||||
phyName = "SMSC LAN8720A";
|
||||
case EPHY_MODEL_LAN8742A:
|
||||
phyName = (phyId.model == EPHY_MODEL_LAN8720A) ? "SMSC LAN8720A" : "SMSC LAN8742A";
|
||||
phyFetchLinkStatusCb = phy_fetch_link_status_LAN8720A;
|
||||
phyIntSetupCb = phy_setup_int_LAN8720A;
|
||||
phyIntHandlerCb = phy_int_handler_LAN8720A;
|
||||
break;
|
||||
case EPHY_MODEL_LAN8742A:
|
||||
phyName = "SMSC LAN8742A";
|
||||
phyIntSetupCb = phy_setup_int_LAN8742A;
|
||||
phyIntHandlerCb = phy_int_handler_LAN8742A;
|
||||
break;
|
||||
case EPHY_MODEL_LAN8670:
|
||||
phyName = "Microchip LAN8670";
|
||||
phyFetchLinkStatusCb = phy_fetch_link_status_LAN8670;
|
||||
phyIntSetupCb = phy_setup_int_LAN8670;
|
||||
phyIntHandlerCb = phy_int_handler_LAN8670;
|
||||
macModeInit = MODEINIT_HALF_DUPLEX | MODEINIT_SPEED_10MBPS;
|
||||
@ -409,6 +419,7 @@ static bool phy_populate_handlers() {
|
||||
switch (phyId.model) {
|
||||
case EPHY_MODEL_RTL8201F:
|
||||
phyName = "Realtek RTL8201F";
|
||||
phyFetchLinkStatusCb = phy_fetch_link_status_RTL8201F;
|
||||
phyIntSetupCb = phy_setup_int_RTL8201F;
|
||||
phyIntHandlerCb = phy_int_handler_RTL8201F;
|
||||
break;
|
||||
@ -427,6 +438,15 @@ static bool phy_populate_handlers() {
|
||||
|
||||
// ----------------
|
||||
|
||||
static void phy_soft_reset() {
|
||||
WRITE(EPHY_BCR, EPHY_BCR_RESET);
|
||||
uint32_t r;
|
||||
do {
|
||||
osDelay(5);
|
||||
READ(EPHY_BCR, r);
|
||||
} while (r & EPHY_BCR_RESET);
|
||||
}
|
||||
|
||||
uint32_t ETHHW_setupPHY(ETH_TypeDef *eth) {
|
||||
phyEth = eth; // store pointer to ETH hardware
|
||||
|
||||
@ -436,6 +456,9 @@ uint32_t ETHHW_setupPHY(ETH_TypeDef *eth) {
|
||||
return MODEINIT_FULL_DUPLEX | MODEINIT_SPEED_100MBPS;
|
||||
}
|
||||
|
||||
// issue a software reset
|
||||
phy_soft_reset();
|
||||
|
||||
// read the PHYID registers
|
||||
uint32_t id1 = 0x00, id2 = 0x00;
|
||||
READ(EPHY_ID1, id1);
|
||||
@ -484,12 +507,14 @@ void phy_print_full_name() {
|
||||
|
||||
int phy_get_link_state() {
|
||||
uint32_t regVal;
|
||||
ETHHW_ReadPHYRegister(phyEth, phyAddr, EPHY_BSR, ®Val);
|
||||
return (regVal & EPHY_BSR_AUTONEGOTIATION_COMPLETE) &&
|
||||
(regVal & EPHY_BSR_LINK_STATUS);
|
||||
READ(EPHY_BSR, regVal);
|
||||
return (regVal & EPHY_BSR_AUTONEGOTIATION_COMPLETE) && (regVal & EPHY_BSR_LINK_STATUS);
|
||||
}
|
||||
|
||||
const PHY_LinkStatus *phy_get_link_status() { return &linkStatus; }
|
||||
const PHY_LinkStatus *phy_get_link_status() {
|
||||
phyFetchLinkStatusCb(&linkStatus);
|
||||
return &linkStatus;
|
||||
}
|
||||
|
||||
void phy_refresh_link_status() {
|
||||
if (phyIntHandlerCb != NULL) {
|
||||
|
||||
@ -30,12 +30,6 @@ typedef struct {
|
||||
|
||||
// --------------
|
||||
|
||||
#ifdef BOARD_MAIN_F407
|
||||
#define PHY_RESET_PIN GPIO_PIN_2 // PB2
|
||||
#else
|
||||
#define PHY_RESET_PIN GPIO_PIN_1 // PB1
|
||||
#endif
|
||||
|
||||
#define EPHY_MDIO_MAX_ADDR (31)
|
||||
#define EPHY_MDIO_BAD_ADDR (EPHY_MDIO_MAX_ADDR + 1)
|
||||
|
||||
@ -168,7 +162,7 @@ typedef struct {
|
||||
#define EPHY_DP83TC813_MMD1_PMA_CTRL_2 (0x0834)
|
||||
#define EPHY_DP83TC813_MMD1_PMA_CTRL_2_MS_CFG EPHY_BIT(14)
|
||||
|
||||
// CRS_DV to RX_DV feature is not documented, these two lines come from a FAQ answer found on the TI's website
|
||||
// CRS_DV to RX_DV feature is not documented, these two lines came from an FAQ answer found on the TI's website
|
||||
// https://e2e.ti.com/support/interface-group/interface/f/interface-forum/1113891/faq-dp83tc812r-q1-how-can-i-connect-phys-back-to-back-over-rmii
|
||||
#define EPHY_DP83TC813_REG_0X0551 (0x0551)
|
||||
#define EPHY_DP83TC813_REG_0X0551_RX_DV EPHY_BIT(4)
|
||||
@ -245,4 +239,9 @@ bool phy_read_reg(uint32_t addr, uint32_t * dst);
|
||||
*/
|
||||
bool phy_write_reg(uint32_t addr, uint32_t data);
|
||||
|
||||
/**
|
||||
* HW reset PHY.
|
||||
*/
|
||||
void phy_hw_reset();
|
||||
|
||||
#endif /* PHY_DRV_PHY_COMMON */
|
||||
|
||||
@ -107,7 +107,7 @@
|
||||
* (when HSE is used as system clock source, directly or through the PLL).
|
||||
*/
|
||||
#if !defined (HSE_VALUE)
|
||||
#define HSE_VALUE (16000000UL) /*!< Value of the External oscillator in Hz */
|
||||
#define HSE_VALUE (25000000UL) /*!< Value of the External oscillator in Hz */
|
||||
#endif /* HSE_VALUE */
|
||||
|
||||
#if !defined (HSE_STARTUP_TIMEOUT)
|
||||
@ -217,7 +217,7 @@
|
||||
#define USE_HAL_SPI_REGISTER_CALLBACKS 0U /* SPI register callback disabled */
|
||||
#define USE_HAL_SWPMI_REGISTER_CALLBACKS 0U /* SWPMI register callback disabled */
|
||||
#define USE_HAL_TIM_REGISTER_CALLBACKS 0U /* TIM register callback disabled */
|
||||
#define USE_HAL_UART_REGISTER_CALLBACKS 0U /* UART register callback disabled */
|
||||
#define USE_HAL_UART_REGISTER_CALLBACKS 1U /* UART register callback disabled */
|
||||
#define USE_HAL_USART_REGISTER_CALLBACKS 0U /* USART register callback disabled */
|
||||
#define USE_HAL_WWDG_REGISTER_CALLBACKS 0U /* WWDG register callback disabled */
|
||||
|
||||
|
||||
@ -47,7 +47,7 @@
|
||||
#define configUSE_PREEMPTION 1
|
||||
#define configUSE_IDLE_HOOK 1
|
||||
#define configUSE_TICK_HOOK 1
|
||||
#define configCPU_CLOCK_HZ ( 400000000 )
|
||||
#define configCPU_CLOCK_HZ ( 550000000 )
|
||||
#define configTICK_RATE_HZ ( ( TickType_t ) 1000 )
|
||||
#define configMAX_PRIORITIES ( 56 )
|
||||
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 130 )
|
||||
|
||||
@ -444,7 +444,7 @@ void task_cli(void *pParam) {
|
||||
}
|
||||
}
|
||||
|
||||
void usb_acm_read_callback(const uint8_t *data, uint32_t size) {
|
||||
void serial_io_rx_callback(const uint8_t *data, uint32_t size) {
|
||||
if (sInitialized) { // push only, if the CLI had been initialized before
|
||||
bfifo_push(&sInputFifo, data, size);
|
||||
}
|
||||
|
||||
51
Src/cmds.c
51
Src/cmds.c
@ -8,8 +8,13 @@
|
||||
#include "FreeRTOS.h"
|
||||
#include "cmsis_os2.h"
|
||||
|
||||
#include "lwip/ip_addr.h"
|
||||
#include "lwip/netif.h"
|
||||
#include "portable.h"
|
||||
#include "standard_output/standard_output.h"
|
||||
#include "standard_output/standard_output.h"
|
||||
|
||||
#include <stm32h7xx.h>
|
||||
|
||||
|
||||
CMD_FUNCTION(os_info) {
|
||||
osVersion_t kVersion;
|
||||
@ -31,15 +36,55 @@ CMD_FUNCTION(phy_info) {
|
||||
}
|
||||
|
||||
CMD_FUNCTION(print_ip) {
|
||||
MSGraw("IP: " ANSI_COLOR_BYELLOW);
|
||||
//PRINT_IPv4(E.ethIntf->ip);
|
||||
MSG("IP: " ANSI_COLOR_BYELLOW "%s" ANSI_COLOR_RESET "\n", ipaddr_ntoa(&(netif_default->ip_addr)));
|
||||
MSG("Gateway: %s\n", ipaddr_ntoa(&(netif_default->gw)));
|
||||
MSG("Netmask: %s\n", ipaddr_ntoa(&(netif_default->netmask)));
|
||||
MSGraw(ANSI_COLOR_RESET "\r\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define HWA_SEMI ANSI_COLOR_RESET ":" ANSI_COLOR_BYELLOW
|
||||
|
||||
CMD_FUNCTION(print_hwa) {
|
||||
MSGraw("Hardware address:\r\n" ANSI_COLOR_BYELLOW);
|
||||
uint8_t * hwa = netif_default->hwaddr;
|
||||
MSG("%02X" HWA_SEMI "%02X" HWA_SEMI "%02X" HWA_SEMI "%02X" HWA_SEMI "%02X" HWA_SEMI "%02X", hwa[0], hwa[1], hwa[2], hwa[3], hwa[4], hwa[5]);
|
||||
MSGraw(ANSI_COLOR_RESET "\r\n\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
CMD_FUNCTION(read_all_phy_regs) {
|
||||
phy_read_all_regs();
|
||||
return 0;
|
||||
}
|
||||
|
||||
CMD_FUNCTION(read_phy_reg) {
|
||||
const char *strAddr = ppArgs[0];
|
||||
uint32_t addr = strtol(strAddr, NULL, 0);
|
||||
uint32_t value;
|
||||
phy_read_reg(addr, &value);
|
||||
MSG("%04X: %04X\n", addr, value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
CMD_FUNCTION(write_phy_reg) {
|
||||
const char *strAddr = ppArgs[0];
|
||||
const char *strData = ppArgs[1];
|
||||
uint32_t addr = strtol(strAddr, NULL, 0);
|
||||
uint32_t data = strtol(strData, NULL, 0);
|
||||
phy_write_reg(addr, data);
|
||||
MSG("%04X: %04X\n", addr, data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void cmd_init() {
|
||||
cli_register_command("osinfo \t\t\tPrint OS-related information", 1, 0, os_info);
|
||||
cli_register_command("phyinfo \t\t\tPrint Ethernet PHY information", 1, 0, phy_info);
|
||||
|
||||
cli_register_command("ip \t\t\tPrint IP-address", 1, 0, print_ip);
|
||||
cli_register_command("hwa \t\t\tPrint hardware address", 1, 0, print_hwa);
|
||||
|
||||
cli_register_command("phy readall \t\t\tRead all PHY registers", 2, 0, read_all_phy_regs);
|
||||
cli_register_command("phy read <address>\t\t\tRead a single PHY register", 2, 1, read_phy_reg);
|
||||
cli_register_command("phy write <address> <data>\t\t\tWrite a single PHY register", 2, 2, write_phy_reg);
|
||||
}
|
||||
@ -53,6 +53,8 @@
|
||||
a lot of data that needs to be copied, this should be set high. */
|
||||
#define MEM_SIZE (12*1024) // (10*1024)
|
||||
|
||||
#define LWIP_DECLARE_MEMORY_POSTFIX __attribute__((section(".lwIPHeapSection")))
|
||||
|
||||
/* MEMP_NUM_PBUF: the number of memp struct pbufs. If the application
|
||||
sends a lot of data out of ROM (or other static memory), this
|
||||
should be set high. */
|
||||
|
||||
16
Src/main.c
16
Src/main.c
@ -12,6 +12,7 @@
|
||||
#include "cmds.h"
|
||||
#include "ethernet/ethernet_lwip.h"
|
||||
|
||||
#include "standard_output/serial_io.h"
|
||||
#include "standard_output/standard_output.h"
|
||||
|
||||
#include <cmsis_os2.h>
|
||||
@ -40,8 +41,8 @@ void init_pll() {
|
||||
osc.PLL.PLLM = 2; // 25MHz -> 12.5MHz
|
||||
osc.PLL.PLLN = 44; // 12.5MHz -> 550MHz
|
||||
osc.PLL.PLLP = 1; // 550MHz -> 550MHz
|
||||
osc.PLL.PLLQ = 11; // 550MHz -> 50MHz
|
||||
osc.PLL.PLLR = 11; // 550MHz -> 50MHz
|
||||
osc.PLL.PLLQ = 5; // 550MHz -> 110MHz
|
||||
osc.PLL.PLLR = 5; // 550MHz -> 110MHz
|
||||
osc.PLL.PLLFRACN = 0; // no fractional tuning
|
||||
|
||||
HAL_RCC_OscConfig(&osc);
|
||||
@ -106,10 +107,6 @@ static void init_led() {
|
||||
}
|
||||
|
||||
void task_startup(void *arg) {
|
||||
#ifdef DEBUG
|
||||
osDelay(1000);
|
||||
#endif
|
||||
|
||||
// initialize on-board LED(s)
|
||||
init_led();
|
||||
|
||||
@ -119,6 +116,10 @@ void task_startup(void *arg) {
|
||||
// print greetings
|
||||
print_welcome_message();
|
||||
|
||||
// #ifdef DEBUG
|
||||
// osDelay(2000);
|
||||
// #endif
|
||||
|
||||
// initialize Ethernet
|
||||
init_ethernet();
|
||||
|
||||
@ -156,6 +157,9 @@ int main(void) {
|
||||
// make random a bit more undeterministic
|
||||
init_randomizer();
|
||||
|
||||
// initialize standard output
|
||||
serial_io_init();
|
||||
|
||||
// -------------
|
||||
|
||||
// initialize the FreeRTOS kernel
|
||||
|
||||
@ -1,6 +1,10 @@
|
||||
target_sources(
|
||||
${CMAKE_PROJECT_NAME}
|
||||
PUBLIC
|
||||
|
||||
serial_io.c
|
||||
serial_io.h
|
||||
|
||||
standard_output.c
|
||||
standard_output.h
|
||||
term_colors.h
|
||||
|
||||
145
Src/standard_output/serial_io.c
Normal file
145
Src/standard_output/serial_io.c
Normal file
@ -0,0 +1,145 @@
|
||||
#include "serial_io.h"
|
||||
#include "blocking_io/blocking_fifo.h"
|
||||
#include "cmsis_os2.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stm32h7xx_hal.h>
|
||||
#include <string.h>
|
||||
|
||||
static void serial_io_tx_cplt(UART_HandleTypeDef *huart);
|
||||
static void serial_io_rx_cplt(UART_HandleTypeDef *huart);
|
||||
static void serial_io_thread(void * arg);
|
||||
|
||||
#define SERIAL_IO_FIFO_LEN (2048)
|
||||
|
||||
static UART_HandleTypeDef uart;
|
||||
static DMA_HandleTypeDef dma;
|
||||
static osEventFlagsId_t flags;
|
||||
static osThreadId_t th;
|
||||
static BFifo fifo;
|
||||
static uint8_t buf[SERIAL_IO_FIFO_LEN];
|
||||
static char c;
|
||||
|
||||
#define SERIAL_IO_TX_CPLT_FLAG (0x01)
|
||||
|
||||
void serial_io_init() {
|
||||
// initialize FIFO
|
||||
bfifo_create(&fifo, buf, SERIAL_IO_FIFO_LEN);
|
||||
|
||||
// initialize flags and thread
|
||||
flags = osEventFlagsNew(NULL);
|
||||
|
||||
osThreadAttr_t attr;
|
||||
memset(&attr, 0, sizeof(osThreadAttr_t));
|
||||
attr.name = "serialio";
|
||||
attr.stack_size = 2048;
|
||||
th = osThreadNew(serial_io_thread, NULL, &attr);
|
||||
|
||||
// Enable peripheral clocks
|
||||
__HAL_RCC_GPIOD_CLK_ENABLE();
|
||||
__HAL_RCC_USART3_CLK_ENABLE();
|
||||
__HAL_RCC_DMA1_CLK_ENABLE();
|
||||
|
||||
// Initialize pins as USART3 Tx and Rx
|
||||
GPIO_InitTypeDef gpio;
|
||||
|
||||
// TX
|
||||
gpio.Pin = GPIO_PIN_8;
|
||||
gpio.Mode = GPIO_MODE_AF_PP;
|
||||
gpio.Alternate = GPIO_AF7_USART3;
|
||||
gpio.Speed = GPIO_SPEED_HIGH;
|
||||
gpio.Pull = GPIO_NOPULL;
|
||||
HAL_GPIO_Init(GPIOD, &gpio);
|
||||
|
||||
// RX
|
||||
gpio.Pin = GPIO_PIN_9;
|
||||
gpio.Mode = GPIO_MODE_AF_OD;
|
||||
HAL_GPIO_Init(GPIOD, &gpio);
|
||||
|
||||
// Initialize USART3
|
||||
uart.Instance = USART3;
|
||||
uart.Init.BaudRate = 115200;
|
||||
uart.Init.Mode = UART_MODE_TX_RX;
|
||||
uart.Init.Parity = UART_PARITY_NONE;
|
||||
uart.Init.WordLength = UART_WORDLENGTH_8B;
|
||||
uart.Init.StopBits = UART_STOPBITS_1;
|
||||
uart.Init.HwFlowCtl = UART_HWCONTROL_NONE;
|
||||
uart.Init.OverSampling = UART_OVERSAMPLING_16;
|
||||
uart.Init.ClockPrescaler = UART_PRESCALER_DIV16;
|
||||
// huart.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
|
||||
HAL_UART_Init(&uart);
|
||||
|
||||
HAL_UART_RegisterCallback(&uart, HAL_UART_TX_COMPLETE_CB_ID, serial_io_tx_cplt);
|
||||
HAL_UART_RegisterCallback(&uart, HAL_UART_RX_COMPLETE_CB_ID, serial_io_rx_cplt);
|
||||
|
||||
HAL_UART_Receive_IT(&uart, (uint8_t *)&c, 1);
|
||||
|
||||
HAL_NVIC_SetPriority(USART3_IRQn, 12, 0);
|
||||
HAL_NVIC_EnableIRQ(USART3_IRQn);
|
||||
|
||||
// configure DMA
|
||||
dma.Instance = DMA1_Stream0;
|
||||
dma.Init.Request = DMA_REQUEST_USART3_TX;
|
||||
dma.Init.Direction = DMA_MEMORY_TO_PERIPH;
|
||||
dma.Init.PeriphInc = DMA_PINC_DISABLE;
|
||||
dma.Init.MemInc = DMA_MINC_ENABLE;
|
||||
dma.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
|
||||
dma.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
|
||||
dma.Init.Mode = DMA_NORMAL;
|
||||
dma.Init.Priority = DMA_PRIORITY_VERY_HIGH;
|
||||
dma.Init.FIFOMode = DMA_FIFO_THRESHOLD_FULL;
|
||||
dma.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
|
||||
dma.Init.MemBurst = DMA_MBURST_SINGLE;
|
||||
dma.Init.PeriphBurst = DMA_PBURST_SINGLE;
|
||||
|
||||
HAL_DMA_Init(&dma);
|
||||
|
||||
__HAL_LINKDMA(&uart, hdmatx, dma);
|
||||
|
||||
HAL_NVIC_SetPriority(DMA1_Stream0_IRQn, 12, 0);
|
||||
HAL_NVIC_EnableIRQ(DMA1_Stream0_IRQn);
|
||||
}
|
||||
|
||||
void DMA1_Stream0_IRQHandler() {
|
||||
HAL_DMA_IRQHandler(&dma);
|
||||
}
|
||||
|
||||
void USART3_IRQHandler() {
|
||||
HAL_UART_IRQHandler(&uart);
|
||||
}
|
||||
|
||||
void serial_io_write(const char *str, uint32_t len) {
|
||||
bfifo_push(&fifo, (const uint8_t *)str, len);
|
||||
}
|
||||
|
||||
// ----------
|
||||
|
||||
#define SERIAL_IO_LINEBUF_LEN (256)
|
||||
static uint8_t lineBuf[SERIAL_IO_LINEBUF_LEN];
|
||||
|
||||
static void serial_io_thread(void * arg) {
|
||||
while (true) {
|
||||
bfifo_wait_avail(&fifo);
|
||||
uint32_t size = bfifo_read(&fifo, lineBuf, SERIAL_IO_LINEBUF_LEN);
|
||||
bfifo_pop(&fifo, size, 0);
|
||||
HAL_UART_Transmit_DMA(&uart, lineBuf, size);
|
||||
osEventFlagsWait(flags, SERIAL_IO_TX_CPLT_FLAG, 0, osWaitForever);
|
||||
}
|
||||
}
|
||||
|
||||
// ----------
|
||||
|
||||
static void serial_io_tx_cplt(UART_HandleTypeDef *huart) {
|
||||
osEventFlagsSet(flags, SERIAL_IO_TX_CPLT_FLAG);
|
||||
}
|
||||
|
||||
__weak void serial_io_rx_callback(const uint8_t *data, uint32_t size) {
|
||||
(void)data;
|
||||
(void)size;
|
||||
}
|
||||
|
||||
static void serial_io_rx_cplt(UART_HandleTypeDef *huart) {
|
||||
char k = c;
|
||||
HAL_UART_Receive_IT(&uart, (uint8_t *)&c, 1);
|
||||
serial_io_rx_callback((const uint8_t *)&k, 1);
|
||||
}
|
||||
9
Src/standard_output/serial_io.h
Normal file
9
Src/standard_output/serial_io.h
Normal file
@ -0,0 +1,9 @@
|
||||
#ifndef STANDARD_OUTPUT_SERIAL_OUTPUT
|
||||
#define STANDARD_OUTPUT_SERIAL_OUTPUT
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
void serial_io_init();
|
||||
void serial_io_write(const char * str, uint32_t len);
|
||||
|
||||
#endif /* STANDARD_OUTPUT_SERIAL_OUTPUT */
|
||||
@ -1,4 +1,6 @@
|
||||
#include "standard_output.h"
|
||||
#include "cmsis_os2.h"
|
||||
#include "standard_output/serial_io.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
@ -35,15 +37,15 @@ void MSG(const char *format, ...) {
|
||||
va_end(vaArgP);
|
||||
lineLen = insert_carriage_return(lineBuf, STDIO_OUTPUT_LINEBUF_LEN); // insert carriage returns
|
||||
if (lineLen > 0) {
|
||||
// usb_acm_write((const uint8_t *)lineBuf, lineLen); // send line to the CDC
|
||||
serial_io_write(lineBuf, lineLen); // send line to the CDC
|
||||
last_char = lineBuf[lineLen - 1];
|
||||
}
|
||||
}
|
||||
|
||||
void MSGchar(int c) {
|
||||
// usb_acm_write((const uint8_t *)&c, 1);
|
||||
serial_io_write((const char *)&c, 1);
|
||||
}
|
||||
|
||||
void MSGraw(const char *str) {
|
||||
// usb_acm_write(str, strlen(str));
|
||||
serial_io_write(str, strlen(str));
|
||||
}
|
||||
|
||||
@ -38,7 +38,7 @@ ENTRY(Reset_Handler)
|
||||
_estack = ORIGIN(RAM_D1) + LENGTH(RAM_D1); /* end of RAM */
|
||||
/* Generate a link error if heap and stack don't fit into RAM */
|
||||
_Min_Heap_Size = 0x200; /* required amount of heap */
|
||||
_Min_Stack_Size = 0x400; /* required amount of stack */
|
||||
_Min_Stack_Size = 0x800; /* required amount of stack */
|
||||
|
||||
/* Specify the memory areas */
|
||||
MEMORY
|
||||
@ -166,6 +166,23 @@ SECTIONS
|
||||
. = ALIGN(8);
|
||||
} >RAM_D1
|
||||
|
||||
.EthDrv_sec (NOLOAD) :
|
||||
{
|
||||
*(.ETHStateAndDecripSection)
|
||||
*(.ETHBufferSection)
|
||||
} >RAM_D1
|
||||
|
||||
/* FreeRTOS heap region */
|
||||
.FreeRTOS_sec (NOLOAD) :
|
||||
{
|
||||
*(.FreeRTOSHeapSection)
|
||||
} >ITCMRAM
|
||||
|
||||
.lwIP_sec (NOLOAD) :
|
||||
{
|
||||
*(.lwIPHeapSection)
|
||||
} > DTCMRAM
|
||||
|
||||
/* Remove information from the standard libraries */
|
||||
/DISCARD/ :
|
||||
{
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user