1
1
/*
2
- * SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD
2
+ * SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD
3
3
*
4
4
* SPDX-License-Identifier: Apache-2.0
5
5
*/
25
25
#include "esp_rom_gpio.h"
26
26
#include "esp_rom_sys.h"
27
27
#include "esp_cpu.h"
28
+ #include "esp_timer.h"
28
29
29
30
static const char * TAG = "dm9051.mac" ;
30
31
@@ -67,6 +68,8 @@ typedef struct {
67
68
TaskHandle_t rx_task_hdl ;
68
69
uint32_t sw_reset_timeout_ms ;
69
70
int int_gpio_num ;
71
+ esp_timer_handle_t poll_timer ;
72
+ uint32_t poll_period_ms ;
70
73
uint8_t addr [6 ];
71
74
bool packets_remain ;
72
75
bool flow_ctrl_enabled ;
@@ -421,6 +424,12 @@ IRAM_ATTR static void dm9051_isr_handler(void *arg)
421
424
}
422
425
}
423
426
427
+ static void dm9051_poll_timer (void * arg )
428
+ {
429
+ emac_dm9051_t * emac = (emac_dm9051_t * )arg ;
430
+ xTaskNotifyGive (emac -> rx_task_hdl );
431
+ }
432
+
424
433
static esp_err_t emac_dm9051_set_mediator (esp_eth_mac_t * mac , esp_eth_mediator_t * eth )
425
434
{
426
435
esp_err_t ret = ESP_OK ;
@@ -514,12 +523,21 @@ static esp_err_t emac_dm9051_get_addr(esp_eth_mac_t *mac, uint8_t *addr)
514
523
static esp_err_t emac_dm9051_set_link (esp_eth_mac_t * mac , eth_link_t link )
515
524
{
516
525
esp_err_t ret = ESP_OK ;
526
+ emac_dm9051_t * emac = __containerof (mac , emac_dm9051_t , parent );
517
527
switch (link ) {
518
528
case ETH_LINK_UP :
519
529
ESP_GOTO_ON_ERROR (mac -> start (mac ), err , TAG , "dm9051 start failed" );
530
+ if (emac -> poll_timer ) {
531
+ ESP_GOTO_ON_ERROR (esp_timer_start_periodic (emac -> poll_timer , emac -> poll_period_ms * 1000 ),
532
+ err , TAG , "start poll timer failed" );
533
+ }
520
534
break ;
521
535
case ETH_LINK_DOWN :
522
536
ESP_GOTO_ON_ERROR (mac -> stop (mac ), err , TAG , "dm9051 stop failed" );
537
+ if (emac -> poll_timer ) {
538
+ ESP_GOTO_ON_ERROR (esp_timer_stop (emac -> poll_timer ),
539
+ err , TAG , "stop poll timer failed" );
540
+ }
523
541
break ;
524
542
default :
525
543
ESP_GOTO_ON_FALSE (false, ESP_ERR_INVALID_ARG , err , TAG , "unknown link status" );
@@ -777,12 +795,14 @@ static esp_err_t emac_dm9051_init(esp_eth_mac_t *mac)
777
795
esp_err_t ret = ESP_OK ;
778
796
emac_dm9051_t * emac = __containerof (mac , emac_dm9051_t , parent );
779
797
esp_eth_mediator_t * eth = emac -> eth ;
780
- esp_rom_gpio_pad_select_gpio (emac -> int_gpio_num );
781
- gpio_set_direction (emac -> int_gpio_num , GPIO_MODE_INPUT );
782
- gpio_set_pull_mode (emac -> int_gpio_num , GPIO_PULLDOWN_ONLY );
783
- gpio_set_intr_type (emac -> int_gpio_num , GPIO_INTR_POSEDGE );
784
- gpio_intr_enable (emac -> int_gpio_num );
785
- gpio_isr_handler_add (emac -> int_gpio_num , dm9051_isr_handler , emac );
798
+ if (emac -> int_gpio_num >= 0 ) {
799
+ esp_rom_gpio_pad_select_gpio (emac -> int_gpio_num );
800
+ gpio_set_direction (emac -> int_gpio_num , GPIO_MODE_INPUT );
801
+ gpio_set_pull_mode (emac -> int_gpio_num , GPIO_PULLDOWN_ONLY );
802
+ gpio_set_intr_type (emac -> int_gpio_num , GPIO_INTR_POSEDGE );
803
+ gpio_intr_enable (emac -> int_gpio_num );
804
+ gpio_isr_handler_add (emac -> int_gpio_num , dm9051_isr_handler , emac );
805
+ }
786
806
ESP_GOTO_ON_ERROR (eth -> on_state_changed (eth , ETH_STATE_LLINIT , NULL ), err , TAG , "lowlevel init failed" );
787
807
/* reset dm9051 */
788
808
ESP_GOTO_ON_ERROR (dm9051_reset (emac ), err , TAG , "reset dm9051 failed" );
@@ -796,8 +816,10 @@ static esp_err_t emac_dm9051_init(esp_eth_mac_t *mac)
796
816
ESP_GOTO_ON_ERROR (dm9051_get_mac_addr (emac ), err , TAG , "fetch ethernet mac address failed" );
797
817
return ESP_OK ;
798
818
err :
799
- gpio_isr_handler_remove (emac -> int_gpio_num );
800
- gpio_reset_pin (emac -> int_gpio_num );
819
+ if (emac -> int_gpio_num >= 0 ) {
820
+ gpio_isr_handler_remove (emac -> int_gpio_num );
821
+ gpio_reset_pin (emac -> int_gpio_num );
822
+ }
801
823
eth -> on_state_changed (eth , ETH_STATE_DEINIT , NULL );
802
824
return ret ;
803
825
}
@@ -807,8 +829,13 @@ static esp_err_t emac_dm9051_deinit(esp_eth_mac_t *mac)
807
829
emac_dm9051_t * emac = __containerof (mac , emac_dm9051_t , parent );
808
830
esp_eth_mediator_t * eth = emac -> eth ;
809
831
mac -> stop (mac );
810
- gpio_isr_handler_remove (emac -> int_gpio_num );
811
- gpio_reset_pin (emac -> int_gpio_num );
832
+ if (emac -> int_gpio_num >= 0 ) {
833
+ gpio_isr_handler_remove (emac -> int_gpio_num );
834
+ gpio_reset_pin (emac -> int_gpio_num );
835
+ }
836
+ if (emac -> poll_timer && esp_timer_is_active (emac -> poll_timer )) {
837
+ esp_timer_stop (emac -> poll_timer );
838
+ }
812
839
eth -> on_state_changed (eth , ETH_STATE_DEINIT , NULL );
813
840
return ESP_OK ;
814
841
}
@@ -819,9 +846,13 @@ static void emac_dm9051_task(void *arg)
819
846
uint8_t status = 0 ;
820
847
while (1 ) {
821
848
// check if the task receives any notification
822
- if (ulTaskNotifyTake (pdTRUE , pdMS_TO_TICKS (1000 )) == 0 && // if no notification ...
823
- gpio_get_level (emac -> int_gpio_num ) == 0 ) { // ...and no interrupt asserted
824
- continue ; // -> just continue to check again
849
+ if (emac -> int_gpio_num >= 0 ) { // if in interrupt mode
850
+ if (ulTaskNotifyTake (pdTRUE , pdMS_TO_TICKS (1000 )) == 0 && // if no notification ...
851
+ gpio_get_level (emac -> int_gpio_num ) == 0 ) { // ...and no interrupt asserted
852
+ continue ; // -> just continue to check again
853
+ }
854
+ } else {
855
+ ulTaskNotifyTake (pdTRUE , portMAX_DELAY );
825
856
}
826
857
/* clear interrupt status */
827
858
dm9051_register_read (emac , DM9051_ISR , & status );
@@ -867,6 +898,9 @@ static void emac_dm9051_task(void *arg)
867
898
static esp_err_t emac_dm9051_del (esp_eth_mac_t * mac )
868
899
{
869
900
emac_dm9051_t * emac = __containerof (mac , emac_dm9051_t , parent );
901
+ if (emac -> poll_timer ) {
902
+ esp_timer_delete (emac -> poll_timer );
903
+ }
870
904
vTaskDelete (emac -> rx_task_hdl );
871
905
emac -> spi .deinit (emac -> spi .ctx );
872
906
heap_caps_free (emac -> rx_buffer );
@@ -880,13 +914,13 @@ esp_eth_mac_t *esp_eth_mac_new_dm9051(const eth_dm9051_config_t *dm9051_config,
880
914
emac_dm9051_t * emac = NULL ;
881
915
ESP_GOTO_ON_FALSE (dm9051_config , NULL , err , TAG , "can't set dm9051 specific config to null" );
882
916
ESP_GOTO_ON_FALSE (mac_config , NULL , err , TAG , "can't set mac config to null" );
917
+ ESP_GOTO_ON_FALSE ((dm9051_config -> int_gpio_num >= 0 ) != (dm9051_config -> poll_period_ms > 0 ), NULL , err , TAG , "invalid configuration argument combination" );
883
918
emac = calloc (1 , sizeof (emac_dm9051_t ));
884
919
ESP_GOTO_ON_FALSE (emac , NULL , err , TAG , "calloc emac failed" );
885
- /* dm9051 receive is driven by interrupt only for now*/
886
- ESP_GOTO_ON_FALSE (dm9051_config -> int_gpio_num >= 0 , NULL , err , TAG , "error interrupt gpio number" );
887
920
/* bind methods and attributes */
888
921
emac -> sw_reset_timeout_ms = mac_config -> sw_reset_timeout_ms ;
889
922
emac -> int_gpio_num = dm9051_config -> int_gpio_num ;
923
+ emac -> poll_period_ms = dm9051_config -> poll_period_ms ;
890
924
emac -> parent .set_mediator = emac_dm9051_set_mediator ;
891
925
emac -> parent .init = emac_dm9051_init ;
892
926
emac -> parent .deinit = emac_dm9051_deinit ;
@@ -937,10 +971,23 @@ esp_eth_mac_t *esp_eth_mac_new_dm9051(const eth_dm9051_config_t *dm9051_config,
937
971
emac -> rx_buffer = heap_caps_malloc (ETH_MAX_PACKET_SIZE + DM9051_RX_HDR_SIZE , MALLOC_CAP_DMA );
938
972
ESP_GOTO_ON_FALSE (emac -> rx_buffer , NULL , err , TAG , "RX buffer allocation failed" );
939
973
974
+ if (emac -> int_gpio_num < 0 ) {
975
+ const esp_timer_create_args_t poll_timer_args = {
976
+ .callback = dm9051_poll_timer ,
977
+ .name = "emac_spi_poll_timer" ,
978
+ .arg = emac ,
979
+ .skip_unhandled_events = true
980
+ };
981
+ ESP_GOTO_ON_FALSE (esp_timer_create (& poll_timer_args , & emac -> poll_timer ) == ESP_OK , NULL , err , TAG , "create poll timer failed" );
982
+ }
983
+
940
984
return & (emac -> parent );
941
985
942
986
err :
943
987
if (emac ) {
988
+ if (emac -> poll_timer ) {
989
+ esp_timer_delete (emac -> poll_timer );
990
+ }
944
991
if (emac -> rx_task_hdl ) {
945
992
vTaskDelete (emac -> rx_task_hdl );
946
993
}
0 commit comments