diff --git a/components/lua_rtos/drivers/ENC424J600.c b/components/lua_rtos/drivers/ENC424J600.c index 603c551be..94cb6a701 100644 --- a/components/lua_rtos/drivers/ENC424J600.c +++ b/components/lua_rtos/drivers/ENC424J600.c @@ -61,14 +61,14 @@ extern void spi_ethernetif_input(struct netif *neti); -#define ENC424J600_INT_MASK (EIR_LINKIF | EIR_PKTIF | EIR_TXIF | EIR_TXABTIF | EIR_RXABTIF | EIR_PCFULIF) +#define ENC424J600_INT_MASK (EIR_LINKIF | EIR_PKTIF) static volatile int currentBank; static uint16_t nextPacketPointer; static int spi_device; static struct netif *interface; -xQueueHandle ether_q; +static xQueueHandle ether_q = NULL; static uint16_t exec_8_op(uint8_t op); static uint16_t exec_16_op(uint8_t op, uint16_t data); @@ -79,8 +79,6 @@ static uint16_t read_reg(uint16_t address); static void write_phy_reg(uint8_t address, uint16_t Data); static void bfs_reg(uint16_t address, uint16_t bitMask); static void bfc_reg(uint16_t address, uint16_t bitMask); -static void suspend_interrupts(); -static void reenable_interrupts(); static int phy_reset(); static void mac_flush(void); static void write_n(uint8_t op, uint8_t* data, uint16_t len); @@ -172,29 +170,6 @@ static uint16_t read_reg(uint16_t address) { return returnValue; } -#if 0 -static uint16_t read_phy_reg(uint8_t address) { - uint16_t readed; - - // Set the right address and start the register read operation - write_reg(MIREGADR, 0x0100 | address); - write_reg(MICMD, MICMD_MIIRD); - - // Loop to wait until the PHY register has been read through the MII - // This requires 25.6us - while (read_reg(MISTAT) & MISTAT_BUSY) - ; - - // Stop reading - write_reg(MICMD, 0x0000); - - // Obtain results and return - readed = read_reg(MIRD); - - return readed; -} -#endif - static void write_phy_reg(uint8_t address, uint16_t Data) { // Write the register address write_reg(MIREGADR, 0x0100 | address); @@ -223,17 +198,6 @@ static void bfc_reg(uint16_t address, uint16_t bitMask) { exec_16_op(BFC | (address & 0x1F), bitMask); } -static void suspend_interrupts() { - // Disable global interrupts while processing this interrupt - // to avoid loose events - bfc_reg(EIE, EIE_INTIE); -} - -static void reenable_interrupts() { - // Reenable ENC global interrupts - bfs_reg(EIE, EIE_INTIE); -} - static int phy_reset() { uint16_t ret = 0; time_t start, now; @@ -283,63 +247,42 @@ static int phy_reset() { return 0; } +/* + * SPI Ethernet task. Waits the ISR for process an interrupt. + * + */ static void ether_task(void *taskArgs) { - uint16_t flag; + uint8_t dummy; for(;;) { - xQueueReceive(ether_q, &flag, portMAX_DELAY); + // Wait the ISR + xQueueReceive(ether_q, &dummy, portMAX_DELAY); - if (flag & EIR_LINKIF) { - link_status_change(); - bfc_reg(EIR, EIR_LINKIF); - } - - if (flag & EIR_PKTIF) { - spi_ethernetif_input(interface); - bfc_reg(EIR, EIR_PKTIF); - } + // Get cause + unsigned int flag = read_reg(EIR); - if (flag & EIR_TXIF) { - // Packet transmission has completed - bfc_reg(EIR, EIR_TXIF); - } - - if (flag & EIR_TXABTIF) { - // Packet transmission has been aborted due to an error - bfc_reg(EIR, EIR_TXABTIF); - } - - if (flag & EIR_RXABTIF) { - // An RX packet was dropped because there is insufficient space in the - // RX buffer to store the complete packet - bfc_reg(EIR, EIR_RXABTIF); - } - - if (flag & EIR_PCFULIF) { - // PKTCNT field has reached FFh. Software must decrement the packet - // counter to prevent the next RX packet from being dropped - bfc_reg(EIR, EIR_PCFULIF); - } + if (flag) { + if (flag & EIR_LINKIF) { + link_status_change(); + } - gpio_intr_enable(CONFIG_SPI_ETHERNET_INT); + if (flag & EIR_PKTIF) { + spi_ethernetif_input(interface); + } - // Reenable interrupts - reenable_interrupts(); + // Clear all interrupt flags + bfc_reg(EIR, 0xfff); + } } } static void ether_intr(void* arg) { - // Disable interrupt on GPIO - gpio_intr_disable(CONFIG_SPI_ETHERNET_INT); + uint8_t dummy = 0; - // Suspend interrupts - suspend_interrupts(); - - // Get cause of this interrupt - unsigned int flag = read_reg(EIR); - - // Send to ethernet task - xQueueSendFromISR(ether_q, &flag, NULL); + // Inform the ethernet task that there is a new interrupt + // for process. A dummy value is queued, because we don't + // want to pass data. + xQueueSendFromISR(ether_q, &dummy, NULL); } static void mac_flush(void) { @@ -518,7 +461,20 @@ int enc424j600_init(struct netif *netif) { // Enable RX packet reception bfs_reg(ECON1, ECON1_RXEN); - // Configure external interrupt line + // Disable all interrupts + bfc_reg(EIE, 0xfff); + + // Clear all interrupt flags + bfc_reg(EIR, 0xfff); + + // Configure external interrupt line + if (!ether_q) { + ether_q = xQueueCreate(100, sizeof(uint8_t)); + } + + // ISR related task must run on the same core that ISR handler is added + xTaskCreatePinnedToCore(ether_task, "eth", configMINIMAL_STACK_SIZE, NULL, configMAX_PRIORITIES - 6, NULL, xPortGetCoreID()); + if (!status_get(STATUS_ISR_SERVICE_INSTALLED)) { gpio_install_isr_service(0); @@ -530,17 +486,6 @@ int enc424j600_init(struct netif *netif) { gpio_set_intr_type(CONFIG_SPI_ETHERNET_INT, GPIO_INTR_NEGEDGE); gpio_isr_handler_add(CONFIG_SPI_ETHERNET_INT, ether_intr, NULL); - ether_q = xQueueCreate(100, sizeof(unsigned int)); - - // ISR related task must run on the same core that ISR handler is added - xTaskCreatePinnedToCore(ether_task, "eth", CONFIG_LUA_RTOS_LUA_THREAD_STACK_SIZE, NULL, CONFIG_LUA_RTOS_LUA_THREAD_PRIORITY, NULL, xPortGetCoreID()); - - // Disable all interrupts - bfc_reg(EIE, 0xfff); - - // Clear all interrupt flags - bfc_reg(EIR, 0xfff); - // Enable interrupts bfs_reg(EIE, ENC424J600_INT_MASK); @@ -550,28 +495,37 @@ int enc424j600_init(struct netif *netif) { struct pbuf *enc424j600_input(struct netif *netif) { RXSTATUS statusVector; uint16_t newRXTail; - struct pbuf *p, *q; + struct pbuf *p = NULL, *q = NULL; u16_t len = 0; u16_t frame_size = 0; + // Ensure that are pending packets + if (!(read_reg(ESTAT) & 0b11111111)) { + return NULL; + } + // Set the RX Read Pointer to the beginning of the next unprocessed packet write_reg(ERXRDPT, nextPacketPointer); + // Read the adress of next packet read_memory_window(RX_WINDOW, (uint8_t*) & nextPacketPointer, sizeof (nextPacketPointer)); - read_memory_window(RX_WINDOW, (uint8_t*) & statusVector, sizeof (statusVector)); - - len = statusVector.bits.ByteCount - 4; - if (statusVector.bits.Zero || statusVector.bits.ZeroH || - statusVector.bits.CRCError || - statusVector.bits.ByteCount > 1522u || - !statusVector.bits.ReceiveOk) { + // Read the receive status vector + read_memory_window(RX_WINDOW, (uint8_t*) & statusVector, sizeof (statusVector)); + // Check the packet + if ( + statusVector.bits.Zero || statusVector.bits.ZeroH || statusVector.bits.CRCError || + statusVector.bits.ByteCount > 1522u || !statusVector.bits.ReceiveOk + ) { goto exit; } + // Get the packet length + len = statusVector.bits.ByteCount - 4; + // If we don't receive nothing, exit - if (len <= 0) { + if (len == 0) { goto exit; } diff --git a/components/lua_rtos/drivers/ENC424J600.h b/components/lua_rtos/drivers/ENC424J600.h index 29056932b..37338dc54 100644 --- a/components/lua_rtos/drivers/ENC424J600.h +++ b/components/lua_rtos/drivers/ENC424J600.h @@ -68,7 +68,7 @@ // ENC424J600 config #define ENC424J600_RAMSIZE (0x6000) #define ENC424J600_TXSTART (0x0000) -#define ENC424J600_RXSTART (030000) // Should be an even memory address +#define ENC424J600_RXSTART (0x3000) // Should be an even memory address void enc424j600Init(void); uint16_t enc424j600PacketReceive(uint16_t maxlen, uint8_t* packet); diff --git a/components/lua_rtos/drivers/spi.c b/components/lua_rtos/drivers/spi.c index a9e4d67f0..03b8d1efb 100644 --- a/components/lua_rtos/drivers/spi.c +++ b/components/lua_rtos/drivers/spi.c @@ -161,11 +161,11 @@ static void _spi_init() { spi_bus[3].mtx = xSemaphoreCreateRecursiveMutex(); } -static void IRAM_ATTR spi_lock(uint8_t unit) { +static void spi_lock(uint8_t unit) { xSemaphoreTakeRecursive(spi_bus[unit].mtx, portMAX_DELAY); } -static void IRAM_ATTR spi_unlock(uint8_t unit) { +static void spi_unlock(uint8_t unit) { while (xSemaphoreGiveRecursive(spi_bus[unit].mtx) == pdTRUE); } @@ -462,8 +462,6 @@ static void spi_setup_bus(uint8_t unit) { * */ int spi_ll_setup(uint8_t unit, uint8_t master, uint8_t cs, uint8_t mode, uint32_t speed, int *deviceid) { - spi_lock(unit); - // Check if there's some device un bus with the same cs // If there's one, we want to reconfigure device int device = spi_get_device_by_cs(unit, cs); @@ -473,7 +471,6 @@ int spi_ll_setup(uint8_t unit, uint8_t master, uint8_t cs, uint8_t mode, uint32_ device = spi_get_free_device(unit); if (device < 0) { // No more devices - spi_unlock(unit); return -1; } } else { @@ -528,8 +525,6 @@ int spi_ll_setup(uint8_t unit, uint8_t master, uint8_t cs, uint8_t mode, uint32_ spi_bus[unit].setup = 1; spi_bus[unit].device[device].setup = 1; - spi_unlock(unit); - *deviceid = (unit << 8) | device; return 0; @@ -539,16 +534,13 @@ void spi_ll_get_speed(int deviceid, uint32_t *speed) { int unit = (deviceid & 0xff00) >> 8; int device = (deviceid & 0x00ff); - spi_lock(unit); *speed = spi_bus[unit].device[device].speed; - spi_unlock(unit); } void spi_ll_set_speed(int deviceid, uint32_t speed) { int unit = (deviceid & 0xff00) >> 8; int device = (deviceid & 0x00ff); - spi_lock(unit); spi_bus[unit].last_device = -1; spi_bus[unit].device[device].speed = speed; #if !SPI_USE_IDF_DRIVER @@ -569,7 +561,6 @@ void spi_ll_set_speed(int deviceid, uint32_t speed) { assert(ret==ESP_OK); #endif - spi_unlock(unit); } void IRAM_ATTR spi_ll_transfer(int deviceid, uint8_t data, uint8_t *read) { @@ -674,8 +665,6 @@ void IRAM_ATTR spi_ll_select(int deviceid) { int unit = (deviceid & 0xff00) >> 8; int device = (deviceid & 0x00ff); - spi_lock(unit); - if (spi_bus[unit].last_device != deviceid) { #if !SPI_USE_IDF_DRIVER // Complete operations, if pending @@ -744,8 +733,6 @@ void IRAM_ATTR spi_ll_deselect(int deviceid) { // Deselect device gpio_ll_pin_set(spi_bus[unit].device[device].cs); - - spi_unlock(unit); } @@ -798,9 +785,12 @@ driver_error_t *spi_setup(uint8_t unit, uint8_t master, uint8_t cs, uint8_t mode } // Low-level setup + spi_lock(unit); if (spi_ll_setup(unit, master, cs, mode, speed, deviceid) != 0) { + spi_unlock(unit); return driver_operation_error(SPI_DRIVER, SPI_ERR_NO_MORE_DEVICES_ALLOWED, NULL); } + spi_unlock(unit); return NULL; } @@ -822,6 +812,7 @@ driver_error_t *spi_select(int deviceid) { return driver_operation_error(SPI_DRIVER, SPI_ERR_DEVICE_NOT_SETUP, NULL); } + spi_lock(unit); spi_ll_select(deviceid); return NULL; @@ -845,6 +836,7 @@ driver_error_t *spi_deselect(int deviceid) { } spi_ll_deselect(deviceid); + spi_unlock(unit); return NULL; } @@ -866,7 +858,9 @@ driver_error_t *spi_get_speed(int deviceid, uint32_t *speed) { return driver_operation_error(SPI_DRIVER, SPI_ERR_DEVICE_NOT_SETUP, NULL); } + spi_lock(unit); spi_ll_get_speed(deviceid, speed); + spi_unlock(unit); return NULL; } @@ -888,7 +882,9 @@ driver_error_t *spi_set_speed(int deviceid, uint32_t speed) { return driver_operation_error(SPI_DRIVER, SPI_ERR_DEVICE_NOT_SETUP, NULL); } + spi_lock(unit); spi_ll_set_speed(deviceid, speed); + spi_unlock(unit); return NULL; } diff --git a/components/lua_rtos/lwip/netif/spiethernetif.c b/components/lua_rtos/lwip/netif/spiethernetif.c index 9985f6299..fba79a96a 100644 --- a/components/lua_rtos/lwip/netif/spiethernetif.c +++ b/components/lua_rtos/lwip/netif/spiethernetif.c @@ -75,38 +75,38 @@ void spi_ethernetif_input(struct netif *netif) { struct pbuf *p; err_t ok = ERR_OK; +more: /* move received packet into a new pbuf */ p = enc424j600_input(netif); /* no packet could be read, silently ignore this */ if (p == NULL) return; + /* points to packet payload, which starts with an Ethernet header */ ethhdr = p->payload; switch (htons(ethhdr->type)) { - /* IP or ARP packet? */ - case ETHTYPE_IP: - case ETHTYPE_IPV6: - case ETHTYPE_ARP: -#if PPPOE_SUPPORT - /* PPPoE packet? */ - case ETHTYPE_PPPOEDISC: - case ETHTYPE_PPPOE: -#endif /* PPPOE_SUPPORT */ - /* full packet send to tcpip_thread to process */ - ok = netif->input(p, netif); - if (ok != ERR_OK) { - LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n")); + /* IP or ARP packet? */ + case ETHTYPE_IP: + case ETHTYPE_IPV6: + case ETHTYPE_ARP: + /* full packet send to tcpip_thread to process */ + ok = netif->input(p, netif); + if (ok != ERR_OK) { + LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n")); + pbuf_free(p); + p = NULL; + } + break; + + default: pbuf_free(p); p = NULL; - } - break; - - default: - pbuf_free(p); - p = NULL; - break; + break; } + + // More packets? + goto more; } /**