Author Topic: How fast does ST 32F417 enter Standby mode?  (Read 8399 times)

0 Members and 1 Guest are viewing this topic.

Online peter-hTopic starter

  • Super Contributor
  • ***
  • Posts: 5925
  • Country: gb
  • Doing electronics since the 1960s...
Re: How fast does ST 32F417 enter Standby mode?
« Reply #25 on: March 16, 2022, 02:48:10 pm »
Sorry; I don't see the connection between the Standby mode, and the way the PHY registers are interfaced, with the strange readback, writeback, and the 1ms wait in between.

After much digging around I found the code which is used to write a PHY config register directly:

Code: [Select]
/**
  * @brief  Writes to a PHY register.
  * @param  heth pointer to a ETH_HandleTypeDef structure that contains
  *         the configuration information for ETHERNET module 
  * @param  PHYReg PHY register address, is the index of one of the 32 PHY register.
  *          This parameter can be one of the following values:
  *             PHY_BCR: Transceiver Control Register. 
  *             More PHY register could be written depending on the used PHY
  * @param  RegValue the value to write
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_ETH_WritePHYRegister(ETH_HandleTypeDef *heth, uint16_t PHYReg, uint32_t RegValue)
{
  uint32_t tmpreg1 = 0U;
  uint32_t tickstart = 0U;
 
  /* Check parameters */
  assert_param(IS_ETH_PHY_ADDRESS(heth->Init.PhyAddress));
 
  /* Check the ETH peripheral state */
  if(heth->State == HAL_ETH_STATE_BUSY_WR)
  {
    return HAL_BUSY;
  }
  /* Set ETH HAL State to BUSY_WR */
  heth->State = HAL_ETH_STATE_BUSY_WR;
 
  /* Get the ETHERNET MACMIIAR value */
  tmpreg1 = heth->Instance->MACMIIAR;
 // tmpreg1 = 16; // Just to test !!!!!
 
  /* Keep only the CSR Clock Range CR[2:0] bits value */
  tmpreg1 &= ~ETH_MACMIIAR_CR_MASK;
 
  /* Prepare the MII register address value */
  tmpreg1 |=(((uint32_t)heth->Init.PhyAddress<<11U) & ETH_MACMIIAR_PA); /* Set the PHY device address */
  tmpreg1 |=(((uint32_t)PHYReg<<6U) & ETH_MACMIIAR_MR);                 /* Set the PHY register address */
  tmpreg1 |= ETH_MACMIIAR_MW;                                           /* Set the write mode */
  tmpreg1 |= ETH_MACMIIAR_MB;                                           /* Set the MII Busy bit */
 
  /* Give the value to the MII data register */
  heth->Instance->MACMIIDR = (uint16_t)RegValue;
 
  /* Write the result value into the MII Address register */
  heth->Instance->MACMIIAR = tmpreg1;
 
  /* Get tick */
  tickstart = HAL_GetTick();
 
  /* Check for the Busy flag */
  while((tmpreg1 & ETH_MACMIIAR_MB) == ETH_MACMIIAR_MB)
  {
    /* Check for the Timeout */
    if((HAL_GetTick() - tickstart ) > PHY_WRITE_TO)
    {
      heth->State= HAL_ETH_STATE_READY;
 
      /* Process Unlocked */
      __HAL_UNLOCK(heth);
   
      return HAL_TIMEOUT;
    }
   
    tmpreg1 = heth->Instance->MACMIIAR;
  }
 
  /* Set ETH HAL State to READY */
  heth->State = HAL_ETH_STATE_READY;
 
  /* Return function status */
  return HAL_OK;
}

and obviously this can be much simplified for just accessing this LAN8742 reg:

Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 

Offline newbrain

  • Super Contributor
  • ***
  • Posts: 1903
  • Country: se
Re: How fast does ST 32F417 enter Standby mode?
« Reply #26 on: March 16, 2022, 03:04:38 pm »
Quote
I don't see the connection between the Standby mode, and the way the PHY registers are interfaced, with the strange readback, writeback, and the 1ms wait in between.
I have no idea of the connection - but you were specifically commenting about the strange code (write, read, rewrite): that sequence is suggested as a workaround for the silicon bug described in the errata.
Some bits in some register might not "take" a write if it's too close to another write: the register will look (i.e. read) as if it was correctly written, but the HW will merrily go on with its previous state.
MACCR is affected by the bug, MACMIIAR is not AFAICS.

So, 1 ms (minimum HAL_Delay* granularity) is too much, but a form of delay is needed there.

*I see you have ETH_Delay - the current master on GH directly uses HAL_Delay - given you say it's 1 ms I suppose they are the same.
« Last Edit: March 16, 2022, 03:07:04 pm by newbrain »
Nandemo wa shiranai wa yo, shitteru koto dake.
 

Online peter-hTopic starter

  • Super Contributor
  • ***
  • Posts: 5925
  • Country: gb
  • Doing electronics since the 1960s...
Re: How fast does ST 32F417 enter Standby mode?
« Reply #27 on: March 16, 2022, 03:42:13 pm »
There were two issues here.

One is how to enter Standby reliably, without the __WFI being terminated by some pending interrupt. That errata you found (thanks!) seems to confirm what a few people have been saying: one has to clean up all interrupt enables, all pending ints, wait a bit, and then __WFI should work. However, the other ST appnote suggests putting __WFI in a loop, so if it doesn't work 1st time because it just hit a pending int, it should work on a subsequent time. Well, unless in your target you have a pending int situation which lasts for many milliseconds and then you have to deal with that specifically. In my target I have two scenarios where there could be a long int pending state: a FatFS sector read (200-300us), and a FatFS sector write (15ms). The 1st I handle specifically; the 2nd is a waste of time because that write will be trashed anyway... the only way would be to have enough capacitance to last >15ms at full power and check the rail before every sector write, but even then you will still get a trashed file system... just like on a PC.

The other is regarding shutting down the ETH PHY chip (LAN8742). This uses a dedicated 2-wire (but bidirectional) 64 bit USART. It took me a few hours of digging through the ST libs but eventually I found how this works. The 32F4 has two registers, ETH->MACMIIAR and ETH->MACMIIDR. The former contains (among other stuff, like the USART clock speed, in this case ~1.6MHz) the PHY register address (0-31, which in this case is 0 because the shutdown bit is in reg 0). The latter is a 16 bit data reg whose value is pushed to the addressed PHY chip reg. And there was some funny code around this part, but looking elsewhere (HAL_ETH_WritePHYRegister) this weird code is not needed if you go in low enough. You can just poke the value in there (order: data reg 1st, address reg 2nd, and loading the AR presumably kicks off the 64-clock shift) and go away. You can also read the PHY this way, but I don't need to do that. I still think that 1ms wait is some fossil BS. BTW the 64 bits is 64 because of a preamble of 32 ones; that is the "start bit". See "SMI write operation" in the RM.

My greatly cut-down version of HAL_ETH_WritePHYRegister() which just does the shutdown bit is:

Code: [Select]

// Shut down LAN8742 ETH PHY chip
uint32_t tmpreg1 = 0U; // point at phy=0 reg=0
tmpreg1 = ETH->MACMIIAR; // get existing MACMIIAR value
tmpreg1 &= ~ETH_MACMIIAR_CR_MASK; // mask off 3 clock divider bits (they are 100 for 168MHz/102)
tmpreg1 |= 3; // WR=1 BUSY=1 (BUSY=1 prob not needed)
ETH->MACMIIDR = 1 << 11; // data reg = SHUTDOWN bit set
ETH->MACMIIAR = tmpreg1; // write it back

Then you have to wait > 40us (at CK=100 i.e. 168MHz/102) for the stuff to shift out to the PHY, before issuing the CPU Standby.

Now, if one was doing this properly as a "low power mode" and hoping to wake up from this and run again, forget it ;)

What is interesting is that the ST code, while supporting funcs for all sorts of PHY features, does not support the shut down mode at all. The PHY_POWERDOWN reg (see below) is not referenced in the whole ETH lib

Code: [Select]
/* Section 3: Common PHY Registers */

#define PHY_BCR                         ((uint16_t)0x00)    /*!< Transceiver Basic Control Register   */
#define PHY_BSR                         ((uint16_t)0x01)    /*!< Transceiver Basic Status Register    */
 
#define PHY_RESET                       ((uint16_t)0x8000)  /*!< PHY Reset */
#define PHY_LOOPBACK                    ((uint16_t)0x4000)  /*!< Select loop-back mode */
#define PHY_FULLDUPLEX_100M             ((uint16_t)0x2100)  /*!< Set the full-duplex mode at 100 Mb/s */
#define PHY_HALFDUPLEX_100M             ((uint16_t)0x2000)  /*!< Set the half-duplex mode at 100 Mb/s */
#define PHY_FULLDUPLEX_10M              ((uint16_t)0x0100)  /*!< Set the full-duplex mode at 10 Mb/s  */
#define PHY_HALFDUPLEX_10M              ((uint16_t)0x0000)  /*!< Set the half-duplex mode at 10 Mb/s  */
#define PHY_AUTONEGOTIATION             ((uint16_t)0x1000)  /*!< Enable auto-negotiation function     */
#define PHY_RESTART_AUTONEGOTIATION     ((uint16_t)0x0200)  /*!< Restart auto-negotiation function    */
#define PHY_POWERDOWN                   ((uint16_t)0x0800)  /*!< Select the power down mode           */
#define PHY_ISOLATE                     ((uint16_t)0x0400)  /*!< Isolate PHY from MII                 */

#define PHY_AUTONEGO_COMPLETE           ((uint16_t)0x0020)  /*!< Auto-Negotiation process completed   */
#define PHY_LINKED_STATUS               ((uint16_t)0x0004)  /*!< Valid link established               */
#define PHY_JABBER_DETECTION            ((uint16_t)0x0002)  /*!< Jabber condition detected            */

It is totally pointless to have support for the various convoluted 32F4 low power modes (which according to google only 23.4% of coders ever manage to get to work properly) while your ETH is drawing 100mA :)
« Last Edit: March 17, 2022, 11:33:16 am by peter-h »
Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 

Online peter-hTopic starter

  • Super Contributor
  • ***
  • Posts: 5925
  • Country: gb
  • Doing electronics since the 1960s...
Re: How fast does ST 32F417 enter Standby mode?
« Reply #28 on: March 16, 2022, 06:46:49 pm »
Anyway, it works!

Current drops from about 155mA to 67mA.

I now have > 8ms of adequate VCC.

« Last Edit: March 16, 2022, 09:17:36 pm by peter-h »
Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 
The following users thanked this post: thm_w, newbrain, uer166


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf