// write 16 bytes hw fifo, and start interrupt send static void write_hw_fifo(uart_t *p) { if((((p==&uart1)?(((LPC_UART_TypeDef *)(p->uart))->LSR):(p->uart->LSR)) & UART_LSR_THRE) != 0) { // hw fifo empty? uint8_t erro; if(p->tx_len == 1) { p->uart->THR = tx_fifo_out(p, &erro); } else if(p->tx_len != 0) { for (uint32_t i=16; (i!=0) && (p->tx_len > 1); i--) { uint8_t data; data = tx_fifo_out(p, &erro); if(erro == 0) { p->uart->THR = data & UART_THR_MASKBIT; } else break; } } } }
static int wlan_trans_thread(void *data) { int i, vif_id, ret, done, retry, sem_count, send_pkt, index, wake_flag, gpio_status; rxfifo_t *rx_fifo; txfifo_t *tx_fifo; wlan_vif_t *vif; sdio_chn_t *tx_chn; sdio_chn_t *rx_chn; unsigned short status; wlan_thread_t *thread; u32 rx_gpio; thread = &(g_wlan.wlan_trans); sdiodev_readchn_init(8, (void *)wlan_rx_chn_isr, 1); sdiodev_readchn_init(9, (void *)wlan_rx_chn_isr, 1); rx_chn = &(g_wlan.hw.sdio_rx_chn); tx_chn = &(g_wlan.hw.sdio_tx_chn); rx_fifo = &(g_wlan.rxfifo); rx_gpio = g_wlan.hw.rx_gpio; up(&(g_wlan.sync.sem)); printke("%s enter\n", __func__); thread->null_run = 0; thread->max_null_run = 100; thread->idle_sleep = 400; thread->prio = 90; wake_flag = 0; thread_sched_policy(thread); trans_down(); do { thread_sleep_policy(thread); send_pkt = retry = done = 0; sem_count = g_wlan.wlan_trans.sem.count; /* if (0 == wake_flag) { wake_lock(&g_wlan.hw.wlan_lock); wake_flag = 1; } */ RX: gpio_status = gpio_get_value(rx_gpio); if (!gpio_status) { if (true == rx_chn->gpio_high) { rx_chn->gpio_high = false; rx_chn->timeout_flag = false; } goto TX; } else { if (false == rx_chn->gpio_high) { rx_chn->gpio_high = true; } } wlan_wakeup(); ret = set_marlin_wakeup(0, 1); #if 0 if (0 != ret) { printke("rx call set_marlin_wakeup error:%d\n", ret); if (ret != -ETIMEDOUT) msleep(200); goto TX; } #endif if (0 != ret) { if( (ITM_NONE_MODE != g_wlan.netif[0].mode) || (ITM_NONE_MODE != g_wlan.netif[1].mode) ) { if(-2 != ret) { printke("rx call set_marlin_wakeup return:%d:%d\n", ret); msleep(200); goto TX; } } else { printke("rx retry open wlan\n", ret); msleep(200); goto TX; } } ret = sdio_chn_status(rx_chn->bit_map, &status); if (0 != ret) { printke("rx call sdio_chn_status error:%d\n", ret); goto RX_SLEEP; } index = check_valid_chn(1, status, rx_chn); if (index < 0) { RX_SLEEP: if (false == rx_chn->timeout_flag) { rx_chn->timeout_flag = true; rx_chn->timeout = jiffies + msecs_to_jiffies(rx_chn->timeout_time); } else { if (time_after(jiffies, rx_chn->timeout)) { printke ("[SDIO_RX_CHN][TIMEOUT][%lu] jiffies:%lu\n", rx_chn->timeout_time, jiffies); msleep(300); rx_chn->timeout_flag = false; } } goto TX; } if (true == rx_chn->timeout_flag) { rx_chn->timeout_flag = false; } if (14 == index) { mdbg_sdio_read(); goto TX; } if (11 == index) { mdbg_at_cmd_read(); goto TX; } if (15 == index) { mdbg_loopcheck_read(); goto TX; } ret = rx_fifo_in(index, rx_fifo, hw_rx); if (OK != ret) { if (HW_READ_ERROR == ret) msleep(100); retry++; goto TX; } g_wlan.wlan_core.need_rx++; core_up(); TX: for (vif_id = NETIF_0_ID; vif_id < WLAN_MAX_ID; vif_id++) { vif = &(g_wlan.netif[vif_id]); tx_fifo = &(vif->txfifo); ret = tx_fifo_used(tx_fifo); if (0 == ret) continue; wlan_wakeup(); ret = set_marlin_wakeup(0, 1); #if 0 if (0 != ret) { printke("tx call set_marlin_wakeup error:%d\n", ret); if (ret != -ETIMEDOUT) msleep(200); retry++; continue; } #endif if (0 != ret) { if( (ITM_NONE_MODE != g_wlan.netif[0].mode) || (ITM_NONE_MODE != g_wlan.netif[1].mode) ) { // -2: means bt ack high if(-2 != ret){ printke("tx call set_marlin_wakeup return:%d\n", ret); msleep(200); retry++; continue; } }else{ printke("tx retry open wlan\n"); msleep(300); retry++; continue; } } ret = sdio_chn_status(tx_chn->bit_map, &status); if (ret) { printke("tx call sdio_chn_status error:%d\n", ret); goto TX_SLEEP; } index = check_valid_chn(0, status, tx_chn); if (index < 0) { TX_SLEEP: if (false == tx_chn->timeout_flag) { tx_chn->timeout_flag = true; tx_chn->timeout = jiffies + msecs_to_jiffies(tx_chn-> timeout_time); } else { if (time_after (jiffies, tx_chn->timeout)) { printke ("[SDIO_TX_CHN][TIMEOUT][%lu] jiffies:%lu\n", tx_chn->timeout_time, jiffies); msleep(300); tx_chn->timeout_flag = false; } } retry++; continue; } if (true == tx_chn->timeout_flag) { tx_chn->timeout_flag = false; } ret = tx_fifo_out(vif_id, index, tx_fifo, hw_tx, &send_pkt); if (OK != ret) { if (HW_WRITE_ERROR == ret) { msleep(100); retry++; } continue; } done = done + send_pkt; core_try_up(); } if (g_wlan.sync.exit) { /* if(1 == wake_flag) { wake_unlock(&g_wlan.hw.wlan_lock); wake_flag = 0; } */ break; } gpio_status = gpio_get_value(rx_gpio); if (gpio_status) { if (g_wlan.wlan_trans.sem.count - done <= 1) { done = (g_wlan.wlan_trans.sem.count > 0) ? (g_wlan.wlan_trans.sem.count - 1) : (0); } } else { if ((0 == done) && (0 == retry)) done = ((0 == sem_count) ? (1) : (sem_count)); } if (done > 0) thread->null_run = 0; else thread->null_run++; wlan_sleep(); /* if ((done >= g_wlan.wlan_trans.sem.count) && (wake_flag = 1) &&(!gpio_status) ) { wake_unlock(&g_wlan.hw.wlan_lock); wake_flag = 0; } */ for (i = 0; i < done; i++) { trans_down(); } } while (!kthread_should_stop()); sdiodev_readchn_uninit(8); sdiodev_readchn_uninit(9); mdbg_sdio_read(); del_timer_sync(&(g_wlan.hw.wakeup_timer)); printke("%s exit\n", __func__); up(&(g_wlan.sync.sem)); core_up(); return OK; }