scottalford75 / Remora-RT1052-cpp

Remora firmware for RT1052 based CNC controllers. C++ version
10 stars 6 forks source link

Create FreeRTOS Repository #4

Open Geramy opened 9 months ago

Geramy commented 9 months ago

Hey Scott,

If you would like to make a repository specific for RTOS I’ll work on setting up the initial project. I think faster communications like you talked about will take this firmware another step up perhaps past the level of the mesa cards because of availability and cost :) plus more communication time means lower latencies between LinuxCNC and motion card and means faster velocity with less errors and that’s exciting enough, that will make probing even more stable too.

Geramy commented 9 months ago

Fixed uart output also, it was set to 1 and changed the physical ethernet address because in board.h it was wrong.

scottalford75 commented 9 months ago

Great, UART is up. But network throws a assert error from ENET_GETInstance() at fsl_enet.c:187

Geramy commented 9 months ago

Yeah I cant figure out how the hell we get the ENET Base and how we install it into the mdio driver, its missing the resource address for the mdio register in the resource.base? idk ive been spending hours trying to find out how to add a resource to mdio without success, reading the other original code i cant make heads or tails to where the hell we get the mdio register and how we add it to the list of resources. Good examples of initializing ethernet, just use github search "ethernetif0_init", "ethernetif_get_enet_base", "ENET_GetInstance" it never shows how it fills the array of base addresses, we onyl have one for the flexspi flash, maybe that driver will tell us how it adds itself to the resources.

scottalford75 commented 9 months ago

Where about it the ethernet initialisation now? Like in

https://github.com/scottalford75/Remora-RT1052-cpp/blob/main/Remora-RT1052-cpp/source/ethernet.cpp

Geramy commented 9 months ago

I took about up to line 46 and shoved it inside the threadx rt1050 network driver and then adapted the rest, of course it didnt go so well, now that we are seeing. but apparently the rt1050 ethernet driver they built used mdio and dma also

Geramy commented 9 months ago

base address is 0x402d8000 from the original firmware.

scottalford75 commented 9 months ago

Is this header being pulled in? Maybe wrong PHY address?

https://github.com/scottalford75/Remora_rt1052_AzureRTOS_Test/blob/3adf5e1c624791f3fddccc642a41e58e48f9e229/board/RTE_Device.h#L126

scottalford75 commented 9 months ago

Where's the threadx rt1050 network driver hidden? Been digging through the source without success...

Geramy commented 9 months ago

source -> drivers -> nx_driver -> threadx / azure rtos driver component -> phy -> physical driver files

Geramy commented 9 months ago

Is this header being pulled in? Maybe wrong PHY address?

https://github.com/scottalford75/Remora_rt1052_AzureRTOS_Test/blob/3adf5e1c624791f3fddccc642a41e58e48f9e229/board/RTE_Device.h#L126

I'm not using this header file, i removed it just now, i'm going to review a second time the physical driver for the ethernet card and the mdio initialize crap and see if I can fix it after debugging the old remora kernel and saving screenshots of the values in the variables lol.

scottalford75 commented 9 months ago

Looks like the board specific stuff start here

https://github.com/azure-rtos/getting-started/blob/37ff82f757070f3fa5364acb1ac06fcc7a5b9d38/NXP/MIMXRT1050-EVKB/lib/netx_driver/src/nx_driver_imxrt10xx.c#L1485

Geramy commented 9 months ago

Yeah, we initialize the ethernet card itself I believe I have everything setup correctly for that and then we try to get the ENET address I believe to communicate with it or the ENET_Type base address, which should be ENET technically because there is only one ENET interface which is the default interface for the board, but I can't seem to set it right.

Geramy commented 9 months ago

I think I finally got it, I need to return ethernetif_get_enet_base to the base inside the resource inside the handle from file https://github.com/scottalford75/Remora-RT1052-cpp/blob/main/Remora-RT1052-cpp/lwip/port/enet_ethernetif.c#L193 line 193 in order to get the base correct.

Geramy commented 9 months ago

Looks like its not working still, must be missing some sort of initialization, we got the correct base now i believe.

Geramy commented 9 months ago

The problem is inside fsl_phylan8720a.c line 70 inside function "PHY_LAN8720A_Init" function "result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_ID1_REG, &regValue);" which keeps coming back returning failed to read from the mdio port, if i'm understanding this correctly. the value of regValue should be PHY_CONTROL_ID1 which is 7 but its never that which means we arn't reading from the correct pin or timers arnt setup to put the pin data into the memory, or how ever this part works because i'm not too sure.

Geramy commented 9 months ago

Looks like pin_mux.c and .h where wrong.

Geramy commented 9 months ago

Finally found that it looks like i'm missing this bit of code, of course converted to the new system.

static struct ethernetif ethernetif_0;
    AT_NONCACHEABLE_SECTION_ALIGN(static enet_rx_bd_struct_t rxBuffDescrip_0[ENET_RXBD_NUM], FSL_ENET_BUFF_ALIGNMENT);
    AT_NONCACHEABLE_SECTION_ALIGN(static enet_tx_bd_struct_t txBuffDescrip_0[ENET_TXBD_NUM], FSL_ENET_BUFF_ALIGNMENT);
    AT_NONCACHEABLE_SECTION_ALIGN(static rx_buffer_t rxDataBuff_0[ENET_RXBUFF_NUM], FSL_ENET_BUFF_ALIGNMENT);
    AT_NONCACHEABLE_SECTION_ALIGN(static tx_buffer_t txDataBuff_0[ENET_TXBD_NUM], FSL_ENET_BUFF_ALIGNMENT);

    ethernetif_0.RxBuffDescrip = &(rxBuffDescrip_0[0]);
    ethernetif_0.TxBuffDescrip = &(txBuffDescrip_0[0]);
    ethernetif_0.RxDataBuff    = &(rxDataBuff_0[0]);
    ethernetif_0.TxDataBuff    = &(txDataBuff_0[0]);

void ethernetif_enet_init(struct netif *netif,
                          struct ethernetif *ethernetif,
                          const ethernetif_config_t *ethernetifConfig)
{
    enet_config_t config;
    uint32_t sysClock;
    enet_buffer_config_t buffCfg[ENET_RING_NUM];
    phy_speed_t speed;
    phy_duplex_t duplex;
    int i;

    /* prepare the buffer configuration. */
    buffCfg[0].rxBdNumber      = ENET_RXBD_NUM;       /* Receive buffer descriptor number. */
    buffCfg[0].txBdNumber      = ENET_TXBD_NUM;       /* Transmit buffer descriptor number. */
    buffCfg[0].rxBuffSizeAlign = sizeof(rx_buffer_t); /* Aligned receive data buffer size. */
    buffCfg[0].txBuffSizeAlign = sizeof(tx_buffer_t); /* Aligned transmit data buffer size. */
    buffCfg[0].rxBdStartAddrAlign =
        &(ethernetif->RxBuffDescrip[0]); /* Aligned receive buffer descriptor start address. */
    buffCfg[0].txBdStartAddrAlign =
        &(ethernetif->TxBuffDescrip[0]); /* Aligned transmit buffer descriptor start address. */
    buffCfg[0].rxBufferAlign =
        NULL; /* Receive data buffer start address. NULL when buffers are allocated by callback for RX zero-copy. */
    buffCfg[0].txBufferAlign = &(ethernetif->TxDataBuff[0][0]); /* Transmit data buffer start address. */
    buffCfg[0].txFrameInfo = NULL; /* Transmit frame information start address. Set only if using zero-copy transmit. */
    buffCfg[0].rxMaintainEnable = true; /* Receive buffer cache maintain. */
    buffCfg[0].txMaintainEnable = true; /* Transmit buffer cache maintain. */

    sysClock = ethernetifConfig->phyHandle->mdioHandle->resource.csrClock_Hz;

    ENET_GetDefaultConfig(&config);
    config.ringNum     = ENET_RING_NUM;
    config.rxBuffAlloc = ethernetif_rx_alloc;
    config.rxBuffFree  = ethernetif_rx_free;
    config.userData    = netif;
#ifdef LWIP_ENET_FLEXIBLE_CONFIGURATION
    extern void BOARD_ENETFlexibleConfigure(enet_config_t * config);
    BOARD_ENETFlexibleConfigure(&config);
#endif

    ethernetif_phy_init(ethernetif, ethernetifConfig, &speed, &duplex);
    config.miiSpeed  = (enet_mii_speed_t)speed;
    config.miiDuplex = (enet_mii_duplex_t)duplex;

#if USE_RTOS && defined(SDK_OS_FREE_RTOS)
    uint32_t instance;
    static ENET_Type *const enetBases[]  = ENET_BASE_PTRS;
    static const IRQn_Type enetTxIrqId[] = ENET_Transmit_IRQS;
    /*! @brief Pointers to enet receive IRQ number for each instance. */
    static const IRQn_Type enetRxIrqId[] = ENET_Receive_IRQS;
#if defined(ENET_ENHANCEDBUFFERDESCRIPTOR_MODE) && ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
    /*! @brief Pointers to enet timestamp IRQ number for each instance. */
    static const IRQn_Type enetTsIrqId[] = ENET_1588_Timer_IRQS;
#endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */

    /* Create the Event for transmit busy release trigger. */
    ethernetif->enetTransmitAccessEvent = xEventGroupCreate();
    ethernetif->txFlag                  = 0x1;

    config.interrupt |=
        kENET_RxFrameInterrupt | kENET_TxFrameInterrupt | kENET_TxBufferInterrupt | kENET_LateCollisionInterrupt;
    config.callback = ethernet_callback;

    for (instance = 0; instance < ARRAY_SIZE(enetBases); instance++)
    {
        if (enetBases[instance] == ethernetif->base)
        {
#ifdef __CA7_REV
            GIC_SetPriority(enetRxIrqId[instance], ENET_PRIORITY);
            GIC_SetPriority(enetTxIrqId[instance], ENET_PRIORITY);
#if defined(ENET_ENHANCEDBUFFERDESCRIPTOR_MODE) && ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
            GIC_SetPriority(enetTsIrqId[instance], ENET_1588_PRIORITY);
#endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
#else
            NVIC_SetPriority(enetRxIrqId[instance], ENET_PRIORITY);
            NVIC_SetPriority(enetTxIrqId[instance], ENET_PRIORITY);
#if defined(ENET_ENHANCEDBUFFERDESCRIPTOR_MODE) && ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
            NVIC_SetPriority(enetTsIrqId[instance], ENET_1588_PRIORITY);
#endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
#endif /* __CA7_REV */
            break;
        }
    }

    LWIP_ASSERT("Input Ethernet base error!", (instance != ARRAY_SIZE(enetBases)));
#endif /* USE_RTOS */

    for (i = 0; i < ENET_RXBUFF_NUM; i++)
    {
        ethernetif->RxPbufs[i].p.custom_free_function = ethernetif_rx_release;
        ethernetif->RxPbufs[i].buffer                 = &(ethernetif->RxDataBuff[i][0]);
        ethernetif->RxPbufs[i].buffer_used            = false;
        ethernetif->RxPbufs[i].netif                  = netif;
    }

    /* Initialize the ENET module. */
    ENET_Init(ethernetif->base, &ethernetif->handle, &config, &buffCfg[0], netif->hwaddr, sysClock);

    ENET_ActiveRead(ethernetif->base);
}
Geramy commented 9 months ago

Need to finish implementing the enet driver inside the netxduo driver, apparently they dont automatically take care of the initialization.

Geramy commented 9 months ago

PHY_Init is working not sure where Board_InitModule function came from but that was a killer function literally, killed everything. So i'm going to work on setting up the buffers and hopefully this time the board doesnt freeze up and cause me to have to short BOOT_M0 and 3v3 to get it to flash again.

Geramy commented 9 months ago

Maybe you could take a look at how i setup the buffers? Seem to be getting faults in weird places. source -> drivers -> nx_driver -> nx_driver_imxrt10xx.c Line 2044 roughly to the end is where i'm getting weird faults, and other times not.

Geramy commented 9 months ago

I could change it and use a linux compatible linux abstract hardware layer? But do you think it will take too much cpu time away?