Beispiel #1
0
static void loras_timer_poll_timeout(LORA* lora)
{
    int last_error;
#if (LORA_DEBUG)
    uint32_t duration_ms;
    ++lora->polls_cnt;
#endif

    if (lora->status != LORA_STATUS_TRANSFER_IN_PROGRESS)
    {
        loras_fatal(lora);
#if (LORA_DEBUG)
        printf("[loras] [fatal error] unexpected status %d => server closed\n", lora->status);
#endif
        return;
    }

    (lora->tx ? loras_hw_tx_async_wait : loras_hw_rx_async_wait)(lora);

    last_error = get_last_error();

#if (LORA_DEBUG)
    //check for internal unexpected errors (ex. ERROR_INVALID_STATE -- chip is in invalid state)
    if (!(last_error >= ERROR_OK || last_error == ERROR_TIMEOUT))
    {
        loras_fatal(lora);
        printf("[loras] [fatal error] unexpected error %d => server closed\n", last_error);
        return;
    }
#endif

    switch (lora->status)
    {
    case LORA_STATUS_TRANSFER_IN_PROGRESS:
        timer_start_ms(lora->timer_poll_timeout, LORA_POLL_TIMEOUT_MS);
        //note: do not check if last_error == ERROR_OK (should be)
        ipc_post_inline(lora->process, HAL_CMD(HAL_LORA, LORA_TRANSFER_IN_PROGRESS), 0, 0, last_error);
        break;
    case LORA_STATUS_TRANSFER_COMPLETED:
        timer_stop(lora->timer_txrx_timeout, 0, HAL_LORA);
#if (LORA_DEBUG)
        duration_ms = loras_get_uptime_ms() - lora->transfer_in_progress_ms;
        printf("[loras] [info] poll completed duration_ms:%u polls_cnt:%u\n", duration_ms, lora->polls_cnt);
#endif
        ipc_post_inline(lora->process, HAL_CMD(HAL_LORA, LORA_TRANSFER_COMPLETED), 0, 0, last_error);
        break;
    default:
        error(ERROR_NOT_SUPPORTED);
        break;
    }
}
Beispiel #2
0
static inline void lpc_usb_suspend(CORE* core)
{
    IPC ipc;
    ipc.process = core->usb.device;
    ipc.cmd = HAL_CMD(HAL_USB, USB_SUSPEND);
    ipc.param1 = USB_HANDLE_DEVICE;
    ipc_ipost(&ipc);
}
Beispiel #3
0
static inline void lpc_usb_wakeup(CORE* core)
{
    IPC ipc;
    ipc.process = core->usb.device;
    ipc.cmd = HAL_CMD(HAL_USB, USB_WAKEUP);
    ipc.param1 = USB_HANDLE_DEVICE;
    ipc_ipost(&ipc);
}
Beispiel #4
0
static inline void usb_suspend(EXO* exo)
{
    IPC ipc;
    OTG_FS_GENERAL->INTMSK &= ~OTG_FS_GENERAL_INTMSK_USBSUSPM;
    ipc.process = exo->usb.device;
    ipc.param1 = USB_HANDLE_DEVICE;
    ipc.cmd = HAL_CMD(HAL_USB, USB_SUSPEND);
    ipc_ipost(&ipc);
}
Beispiel #5
0
static inline void usb_wakeup(EXO* exo)
{
    IPC ipc;
    OTG_FS_GENERAL->INTMSK |= OTG_FS_GENERAL_INTMSK_USBSUSPM;
    ipc.process = exo->usb.device;
    ipc.param1 = USB_HANDLE_DEVICE;
    ipc.cmd = HAL_CMD(HAL_USB, USB_WAKEUP);
    ipc_ipost(&ipc);
}
Beispiel #6
0
void lpc_sdmmc_on_isr(int vector, void* param)
{
    CORE* core = (CORE*)param;
    if (LPC_SDMMC->IDSTS & SDMMC_IDSTS_NIS_Msk)
    {
        switch (core->sdmmc.state)
        {
        case SDMMC_STATE_READ:
        case SDMMC_STATE_WRITE:
            if (core->sdmmc.state == SDMMC_STATE_READ)
                core->sdmmc.io->data_size = core->sdmmc.total;
            iio_complete(core->sdmmc.process, HAL_IO_CMD(HAL_SDMMC, core->sdmmc.state == SDMMC_STATE_READ ? IPC_READ : IPC_WRITE), core->sdmmc.user, core->sdmmc.io);
            core->sdmmc.io = NULL;
            core->sdmmc.process = INVALID_HANDLE;
            core->sdmmc.state = SDMMC_STATE_IDLE;
            break;
        case SDMMC_STATE_VERIFY:
        case SDMMC_STATE_WRITE_VERIFY:
            //write is taking some also as hash, so it's better to switch to userspace for completion
            ipc_ipost_inline(process_iget_current(), HAL_CMD(HAL_SDMMC, LPC_SDMMC_VERIFY), 0, 0, 0);
            break;
        default:
            break;
        }
        LPC_SDMMC->IDSTS = SDMMC_IDSTS_RI_Msk | SDMMC_IDSTS_TI_Msk | SDMMC_IDSTS_NIS_Msk;
    }
    if (LPC_SDMMC->IDSTS & SDMMC_IDSTS_AIS_Msk)
    {

        if (LPC_SDMMC->IDSTS & SDMMC_IDSTS_FBE_Msk)
        {
            lpc_sdmmc_error(core, ERROR_HARDWARE);
            LPC_SDMMC->IDSTS = SDMMC_IDSTS_FBE_Msk;
        }
        if (LPC_SDMMC->IDSTS & SDMMC_IDSTS_CES_Msk)
        {
            if (LPC_SDMMC->RINTSTS & SDMMC_RINTSTS_DRTO_BDS_Msk)
            {
                lpc_sdmmc_error(core, ERROR_TIMEOUT);
                LPC_SDMMC->RINTSTS = SDMMC_RINTSTS_DRTO_BDS_Msk;
            }
            if (LPC_SDMMC->RINTSTS & SDMMC_RINTSTS_DCRC_Msk)
            {
                lpc_sdmmc_error(core, ERROR_CRC);
                LPC_SDMMC->RINTSTS = SDMMC_RINTSTS_DCRC_Msk;
            }
            if (LPC_SDMMC->RINTSTS & (SDMMC_RINTSTS_SBE_Msk | SDMMC_RINTSTS_EBE_Msk))
            {
                lpc_sdmmc_error(core, ERROR_HARDWARE);
                LPC_SDMMC->RINTSTS = SDMMC_RINTSTS_SBE_Msk | SDMMC_RINTSTS_EBE_Msk;
            }
            LPC_SDMMC->IDSTS = SDMMC_IDSTS_CES_Msk;
        }
        LPC_SDMMC->IDSTS = SDMMC_IDSTS_AIS_Msk;
    }
}
Beispiel #7
0
static inline void lpc_usb_setup(CORE* core)
{
    IPC ipc;
    ipc.process = core->usb.device;
    ipc.cmd = HAL_CMD(HAL_USB, USB_SETUP);
    ipc.param1 = 0;
    ipc.param2 = *((uint32_t*)(USB_SETUP_BUF_BASE));
    ipc.param3 = *((uint32_t*)(USB_SETUP_BUF_BASE + 4));
    ipc_ipost(&ipc);
}
Beispiel #8
0
void ksystime_soft_timer_timeout(void* param)
{
    SOFT_TIMER* timer = (SOFT_TIMER*)param;
    IPC ipc;
    ipc.process = timer->owner;
    ipc.cmd = HAL_CMD(timer->hal, IPC_TIMEOUT);
    ipc.param1 = timer->param;
    ipc.param2 = (unsigned int)timer;
    kipc_post(KERNEL_HANDLE, &ipc);
}
Beispiel #9
0
static inline void usb_enumdne(EXO* exo)
{
    OTG_FS_GENERAL->INTMSK |= OTG_FS_GENERAL_INTMSK_USBSUSPM;

    IPC ipc;
    ipc.process = exo->usb.device;
    ipc.param1 = USB_HANDLE_DEVICE;
    ipc.param2 = stm32_otg_get_speed(exo);
    ipc.cmd = HAL_CMD(HAL_USB, USB_RESET);
    ipc_ipost(&ipc);
}
Beispiel #10
0
static inline int hidd_kbd_set_report(USBD* usbd, HIDD_KBD* hidd, IO* io, unsigned int length)
{
    uint8_t* report = io_data(io);
#if (USBD_HID_DEBUG_REQUESTS)
    printf("HIDD KBD: set LEDs %#X\n", report[0]);
#endif
    if (hidd->kbd.leds != report[0])
        usbd_post_user(usbd, hidd->iface, 0, HAL_CMD(HAL_USBD_IFACE, USB_HID_KBD_LEDS_STATE_CHANGED), report[0], 0);
    hidd->kbd.leds = report[0];
    return 0;
}
Beispiel #11
0
static inline void lpc_usb_reset(CORE* core)
{
    //enable device
    LPC_USB->DEVCMDSTAT |= USB_DEVCMDSTAT_DEV_EN;
    IPC ipc;
    ipc.process = core->usb.device;
    ipc.cmd = HAL_CMD(HAL_USB, USB_RESET);
    ipc.param1 = USB_HANDLE_DEVICE;
    ipc.param2 = lpc_usb_get_speed(core);
    ipc_ipost(&ipc);

}
Beispiel #12
0
static void lpc_eth_conn_check(EXO* exo)
{
    ETH_CONN_TYPE new_conn;
    new_conn = eth_phy_get_conn_status(exo->eth.phy_addr);
    if (new_conn != exo->eth.conn)
    {
        exo->eth.conn = new_conn;
        exo->eth.connected = ((exo->eth.conn != ETH_NO_LINK) && (exo->eth.conn != ETH_REMOTE_FAULT));
        kexo_post(exo->eth.tcpip, HAL_CMD(HAL_ETH, ETH_NOTIFY_LINK_CHANGED), exo->eth.phy_addr, exo->eth.conn, 0);
        if (exo->eth.connected)
        {
            //set speed and duplex
            switch (exo->eth.conn)
            {
            case ETH_10_HALF:
                LPC_ETHERNET->MAC_CONFIG &= ~(ETHERNET_MAC_CONFIG_DM_Msk | ETHERNET_MAC_CONFIG_FES_Msk);
                break;
            case ETH_10_FULL:
                LPC_ETHERNET->MAC_CONFIG &= ~ETHERNET_MAC_CONFIG_FES_Msk;
                LPC_ETHERNET->MAC_CONFIG |= ETHERNET_MAC_CONFIG_DM_Msk;
                break;
            case ETH_100_HALF:
                LPC_ETHERNET->MAC_CONFIG &= ~ETHERNET_MAC_CONFIG_DM_Msk;
                LPC_ETHERNET->MAC_CONFIG |= ETHERNET_MAC_CONFIG_FES_Msk;
                break;
            case ETH_100_FULL:
                LPC_ETHERNET->MAC_CONFIG |= ETHERNET_MAC_CONFIG_DM_Msk | ETHERNET_MAC_CONFIG_FES_Msk;
                break;
            default:
                break;
            }
            //Looks like some timeout is required after connection mode is changed to setup state machin
            //in other case there is chance it will hang
#ifdef EXODRIVERS
            exodriver_delay_us(1 * 1000);
#else
            sleep_ms(1);
#endif //EXODRIVERS
            //enable RX/TX, PAD/CRC strip
            LPC_ETHERNET->MAC_CONFIG |= ETHERNET_MAC_CONFIG_RE_Msk | ETHERNET_MAC_CONFIG_TE_Msk | ETHERNET_MAC_CONFIG_ACS_Msk;
            LPC_ETHERNET->DMA_OP_MODE |= ETHERNET_DMA_OP_MODE_SR_Msk | ETHERNET_DMA_OP_MODE_ST_Msk;
        }
        else
        {
            lpc_eth_flush(exo);
            LPC_ETHERNET->DMA_OP_MODE &= ~(ETHERNET_DMA_OP_MODE_SR_Msk | ETHERNET_DMA_OP_MODE_ST_Msk);
            LPC_ETHERNET->MAC_CONFIG &= ~(ETHERNET_MAC_CONFIG_RE_Msk | ETHERNET_MAC_CONFIG_TE_Msk | ETHERNET_MAC_CONFIG_ACS_Msk);
        }
    }
    ksystime_soft_timer_start_ms(exo->eth.timer, 1000);
}
Beispiel #13
0
static void udps_flush(TCPIPS* tcpips, HANDLE handle)
{
    IO* io;
    UDP_HANDLE* uh;
    int err;
    uh = so_get(&tcpips->udps.handles, handle);
    if (uh == NULL)
        return;
    err = ERROR_IO_CANCELLED;
#if (ICMP)
    if (uh->err != ERROR_OK)
        err = uh->err;
#endif //ICMP
    while ((io = udps_peek_head(tcpips, uh)) != NULL)
        io_complete_ex(uh->process, HAL_CMD(HAL_UDP, IPC_READ), handle, io, err);
}
Beispiel #14
0
//------------------------------------------------------------------------
static inline void stm32_otg_on_isr_rx(EXO* exo)
{
    IPC ipc;
    unsigned int sta = OTG_FS_GENERAL->RXSTSP;
    unsigned int pktsts = sta & OTG_FS_GENERAL_RXSTSR_PKTSTS;
    int bcnt = (sta & OTG_FS_GENERAL_RXSTSR_BCNT) >> OTG_FS_GENERAL_RXSTSR_BCNT_POS;
    unsigned int ep_num = (sta & OTG_FS_GENERAL_RXSTSR_EPNUM) >> OTG_FS_GENERAL_RXSTSR_EPNUM_POS;
    EP* ep = exo->usb.out[ep_num];
    if (pktsts == OTG_FS_GENERAL_RXSTSR_PKTSTS_SETUP_RX)
    {
//ignore all data on setup packet
        exo->usb.setup_lo = ((uint32_t*)(OTG_FS_FIFO_BASE + ep_num * 0x1000))[0];
        exo->usb.setup_hi = ((uint32_t*)(OTG_FS_FIFO_BASE + ep_num * 0x1000))[1];
    }
    else  if ((pktsts == OTG_FS_GENERAL_RXSTSR_PKTSTS_SETUP_DONE))
    {
        ipc.process = exo->usb.device;
        ipc.cmd = HAL_CMD(HAL_USB, USB_SETUP);
        ipc.param1 = USB_HANDLE(USB_0, 0);
        ipc.param2 = exo->usb.setup_lo;
        ipc.param3 = exo->usb.setup_hi;
        ipc_ipost(&ipc);
    }
    else  if ((pktsts == OTG_FS_GENERAL_RXSTSR_PKTSTS_OUT_RX) && bcnt)
    {
        memcpy4(io_data(ep->io) + ep->io->data_size, (void*)(OTG_FS_FIFO_BASE + ep_num * 0x1000), bcnt);
        ep->io->data_size += bcnt;

        if (ep->io->data_size >= ep->size || bcnt < ep->mps )
        {
          iio_complete(exo->usb.device, HAL_IO_CMD(HAL_USB, IPC_READ), ep_num, ep->io);
            ep->io_active = false;
            ep->io = NULL;
        }
        else
            stm32_otg_rx_prepare(exo, ep_num);
    }
    OTG_FS_GENERAL->INTMSK |= OTG_FS_GENERAL_INTMSK_RXFLVLM;
}
Beispiel #15
0
static void loras_timer_txrx_timeout(LORA* lora)
{
    if (lora->status != LORA_STATUS_TRANSFER_IN_PROGRESS)
    {
        loras_fatal(lora);
#if (LORA_DEBUG)
        printf("[loras] [fatal error] unexpected status %d => server closed\n", lora->status);
#endif
        return;
    }
#if (LORA_DEBUG)
    printf("[loras] [info] timer_txrx_timeout expired -> transfer completed\n");
#endif
    timer_stop(lora->timer_poll_timeout, 0, HAL_LORA);
    if (lora->tx || !LORA_CONTINUOUS_RECEPTION_ON)
        loras_hw_sleep(lora);
#if (LORA_DO_ERROR_COUNTING)
    lora->tx ? ++lora->stats_tx.timeout_num : ++lora->stats_rx.timeout_num;
#endif
    lora->status = LORA_STATUS_TRANSFER_COMPLETED;
    ipc_post_inline(lora->process, HAL_CMD(HAL_LORA, LORA_TRANSFER_COMPLETED), 0, 0, ERROR_TIMEOUT);
}
Beispiel #16
0
void gpio_disable_pin(unsigned int pin)
{
    ipc_post_exo(HAL_CMD(HAL_GPIO, IPC_GPIO_DISABLE_PIN), pin, 0, 0);
}
Beispiel #17
0
static inline void hidd_kbd_write_complete(USBD* usbd, HIDD_KBD* hidd)
{
    usbd_post_user(usbd, hidd->iface, 0, HAL_CMD(HAL_USBD_IFACE, hidd->state), 0, 0);
    hidd->state = USB_HID_KBD_IDLE;
}
Beispiel #18
0
void power_set_mode(POWER_MODE mode)
{
    ipc_post_exo(HAL_CMD(HAL_POWER, POWER_SET_MODE), mode, 0, 0);
}
Beispiel #19
0
static void icmps_echo_complete(TCPIPS* tcpips, int err)
{
    ipc_post_inline(tcpips->icmps.process, HAL_CMD(HAL_ICMP, ICMP_PING), tcpips->icmps.echo_ip.u32.ip, err == ERROR_OK ? 0 : INVALID_HANDLE, err);
    tcpips->icmps.process = INVALID_HANDLE;
}
Beispiel #20
0
void gpio_reset_pin(unsigned int pin)
{
    ipc_post_exo(HAL_CMD(HAL_GPIO, IPC_GPIO_RESET_PIN), pin, 0, 0);
}
Beispiel #21
0
void gpio_enable_pin(unsigned int pin, GPIO_MODE mode)
{
    ipc_post_exo(HAL_CMD(HAL_GPIO, IPC_GPIO_ENABLE_PIN), pin, mode, 0);
}
Beispiel #22
0
void gpio_set_data_in(unsigned int port, unsigned int mask)
{
    ipc_post_exo(HAL_CMD(HAL_GPIO, IPC_GPIO_SET_DATA_IN), port, mask, 0);
}
Beispiel #23
0
void gpio_reset_mask(unsigned int port, unsigned int mask)
{
    ipc_post_exo(HAL_CMD(HAL_GPIO, IPC_GPIO_RESET_MASK), port, mask, 0);
}
Beispiel #24
0
void lpc_usb_on_isr(int vector, void* param)
{
    int i;
    CORE* core = (SHARED_USB_DRV*)param;
    uint32_t sta = LPC_USB->INTSTAT;
    EP* ep;

#if (USB_DEBUG_ERRORS)
    IPC ipc;
    switch (LPC_USB->INFO & USB_INFO_ERR_CODE_MASK)
    {
    case USB_INFO_ERR_CODE_NO_ERROR:
    case USB_INFO_ERR_CODE_IONAK:
        //no error
        break;
    default:
        ipc.process = process_iget_current();
        ipc.cmd = HAL_CMD(HAL_USB, LPC_USB_ERROR);
        ipc.param1 = USB_HANDLE_DEVICE;
        ipc.param2 = (LPC_USB->INFO & USB_INFO_ERR_CODE_MASK) >> USB_INFO_ERR_CODE_POS;
        ipc_ipost(&ipc);
        LPC_USB->INFO &= ~USB_INFO_ERR_CODE_MASK;
    }
#endif

    if (sta & USB_INTSTAT_DEV_INT)
    {
        sta = LPC_USB->DEVCMDSTAT;
        //Don't care on connection change, just clear pending bit
        if (sta & USB_DEVCMDSTAT_DCON_C)
            LPC_USB->DEVCMDSTAT |= USB_DEVCMDSTAT_DCON_C;
        if (sta & USB_DEVCMDSTAT_DSUS_C)
        {
            if (sta & USB_DEVCMDSTAT_DSUS)
                lpc_usb_suspend(core);
            else
                lpc_usb_wakeup(core);
            LPC_USB->DEVCMDSTAT |= USB_DEVCMDSTAT_DSUS_C;
        }
        if (sta & USB_DEVCMDSTAT_DRES_C)
        {
            lpc_usb_reset(core);
            LPC_USB->DEVCMDSTAT |= USB_DEVCMDSTAT_DRES_C;
        }
        LPC_USB->INTSTAT = USB_INTSTAT_DEV_INT;
        return;
    }
    if ((sta & USB_INTSTAT_EP0OUT) && (LPC_USB->DEVCMDSTAT & USB_DEVCMDSTAT_SETUP))
    {
        lpc_usb_setup(core);
        LPC_USB->DEVCMDSTAT |= USB_DEVCMDSTAT_SETUP;
        LPC_USB->INTSTAT = USB_INTSTAT_EP0OUT;
        return;
    }

    for (i = 0; i < USB_EP_COUNT_MAX; ++i)
    {
        if (sta & USB_EP_INT_BIT(i))
        {
            ep = core->usb.out[i];
            if (ep && ep->io_active)
                lpc_usb_out(core, i);
            LPC_USB->INTSTAT = USB_EP_INT_BIT(i);
        }
        if (sta & USB_EP_INT_BIT(USB_EP_IN | i))
        {
            ep = core->usb.in[i];
            if (ep && ep->io_active)
                lpc_usb_in(core, i | USB_EP_IN);
            LPC_USB->INTSTAT = USB_EP_INT_BIT(USB_EP_IN | i);
        }
    }
}
Beispiel #25
0
static inline void lpc_sdmmc_io(CORE* core, HANDLE process, HANDLE user, IO* io, unsigned int size, bool read)
{
    SHA1_CTX sha1;
    unsigned int count;
    STORAGE_STACK* stack = io_stack(io);
    io_pop(io, sizeof(STORAGE_STACK));
    if (!core->sdmmc.active)
    {
        error(ERROR_NOT_CONFIGURED);
        return;
    }
    if (core->sdmmc.state != SDMMC_STATE_IDLE)
    {
        error(ERROR_IN_PROGRESS);
        return;
    }
    if ((user != core->sdmmc.user) || (size == 0))
    {
        error(ERROR_INVALID_PARAMS);
        return;
    }
    //erase
    if (!read && ((stack->flags & STORAGE_MASK_MODE) == 0))
    {
        sdmmcs_erase(&core->sdmmc.sdmmcs, stack->sector, size);
        return;
    }
    if (size % core->sdmmc.sdmmcs.sector_size)
    {
        error(ERROR_INVALID_PARAMS);
        return;
    }
    count = size / core->sdmmc.sdmmcs.sector_size;
    core->sdmmc.total = size;
    if (core->sdmmc.total > LPC_SDMMC_TOTAL_SIZE)
    {
        error(ERROR_INVALID_PARAMS);
        return;
    }
    if ((core->sdmmc.activity != INVALID_HANDLE) && !(stack->flags & STORAGE_FLAG_IGNORE_ACTIVITY_ON_REQUEST))
    {
        ipc_post_inline(core->sdmmc.activity, HAL_CMD(HAL_SDMMC, STORAGE_NOTIFY_ACTIVITY), core->sdmmc.user, read ? 0 : STORAGE_FLAG_WRITE, 0);
        core->sdmmc.activity = INVALID_HANDLE;
    }
    core->sdmmc.io = io;
    core->sdmmc.process = process;

    lpc_sdmmc_prepare_descriptors(core);

    if (read)
    {
        io->data_size = 0;
        core->sdmmc.state = SDMMC_STATE_READ;
        if (sdmmcs_read(&core->sdmmc.sdmmcs, stack->sector, count))
            error(ERROR_SYNC);
    }
    else
    {
        switch (stack->flags & STORAGE_MASK_MODE)
        {
        case STORAGE_FLAG_WRITE:
            core->sdmmc.state = SDMMC_STATE_WRITE;
            if (sdmmcs_write(&core->sdmmc.sdmmcs, stack->sector, count))
                error(ERROR_SYNC);
            break;
        default:
            //verify/verify write
            sha1_init(&sha1);
            sha1_update(&sha1, io_data(io), core->sdmmc.total);
            sha1_final(&sha1, core->sdmmc.hash);
            core->sdmmc.sector = stack->sector;
            switch (stack->flags & STORAGE_MASK_MODE)
            {
            case STORAGE_FLAG_VERIFY:
                core->sdmmc.state = SDMMC_STATE_VERIFY;
                if (sdmmcs_read(&core->sdmmc.sdmmcs, stack->sector, count))
                    error(ERROR_SYNC);
                break;
            case (STORAGE_FLAG_VERIFY | STORAGE_FLAG_WRITE):
                core->sdmmc.state = SDMMC_STATE_WRITE_VERIFY;
                if (sdmmcs_write(&core->sdmmc.sdmmcs, stack->sector, count))
                    error(ERROR_SYNC);
                break;
            default:
                error(ERROR_NOT_SUPPORTED);
                return;
            }
        }
    }
}