Пример #1
0
static inline void lpc_sdmmc_verify(CORE* core)
{
    SHA1_CTX sha1;
    uint8_t hash_in[SHA1_BLOCK_SIZE];
    if ((core->sdmmc.state != SDMMC_STATE_VERIFY) && (core->sdmmc.state != SDMMC_STATE_WRITE_VERIFY))
        return;
    sha1_init(&sha1);
    sha1_update(&sha1, io_data(core->sdmmc.io), core->sdmmc.total);
    sha1_final(&sha1, core->sdmmc.state == SDMMC_STATE_VERIFY ? hash_in : core->sdmmc.hash);

    if (core->sdmmc.state == SDMMC_STATE_WRITE_VERIFY)
    {
        core->sdmmc.state = SDMMC_STATE_VERIFY;
        lpc_sdmmc_prepare_descriptors(core);
        if (sdmmcs_read(&core->sdmmc.sdmmcs, core->sdmmc.sector, core->sdmmc.total / core->sdmmc.sdmmcs.sector_size))
            return;
    }
    else
    {
        if (memcmp(core->sdmmc.hash, hash_in, SHA1_BLOCK_SIZE) == 0)
        {
            io_complete(core->sdmmc.process, HAL_IO_CMD(HAL_SDMMC, IPC_WRITE), core->sdmmc.user, core->sdmmc.io);
            core->sdmmc.io = NULL;
            core->sdmmc.process = INVALID_HANDLE;
            core->sdmmc.state = SDMMC_STATE_IDLE;
            return;
        }
    }
    io_complete_ex(core->sdmmc.process, HAL_IO_CMD(HAL_SDMMC, IPC_WRITE), core->sdmmc.user, core->sdmmc.io, get_last_error());
    core->sdmmc.io = NULL;
    core->sdmmc.process = INVALID_HANDLE;
    core->sdmmc.state = SDMMC_STATE_IDLE;
}
Пример #2
0
static void lpc_eth_flush(EXO* exo)
{
    IO* io;

    //flush TxFIFO controller
    LPC_ETHERNET->DMA_OP_MODE |= ETHERNET_DMA_OP_MODE_FTF_Msk;
    while(LPC_ETHERNET->DMA_OP_MODE & ETHERNET_DMA_OP_MODE_FTF_Msk) {}
#if (ETH_DOUBLE_BUFFERING)
    int i;
    for (i = 0; i < 2; ++i)
    {
        exo->eth.rx_des[0].size = ETH_RDES1_RCH;
        exo->eth.rx_des[0].buf2_ndes = &exo->eth.rx_des[1];
        exo->eth.rx_des[1].size = ETH_RDES1_RCH;
        exo->eth.rx_des[1].buf2_ndes = &exo->eth.rx_des[0];

        exo->eth.tx_des[0].ctl = ETH_TDES0_TCH | ETH_TDES0_IC;
        exo->eth.tx_des[0].buf2_ndes = &exo->eth.tx_des[1];
        exo->eth.tx_des[1].ctl = ETH_TDES0_TCH | ETH_TDES0_IC;
        exo->eth.tx_des[1].buf2_ndes = &exo->eth.tx_des[0];

        __disable_irq();
        exo->eth.rx_des[i].ctl = 0;
        io = exo->eth.rx[i];
        exo->eth.rx[i] = NULL;
        __enable_irq();
        if (io != NULL)
            kexo_io_ex(exo->eth.tcpip, HAL_IO_CMD(HAL_ETH, IPC_READ), exo->eth.phy_addr, io, ERROR_IO_CANCELLED);

        __disable_irq();
        exo->eth.tx_des[i].ctl = ETH_TDES0_TCH | ETH_TDES0_IC;;
        io = exo->eth.tx[i];
        exo->eth.tx[i] = NULL;
        __enable_irq();
        if (io != NULL)
            kexo_io_ex(exo->eth.tcpip, HAL_IO_CMD(HAL_ETH, IPC_WRITE), exo->eth.phy_addr, io, ERROR_IO_CANCELLED);
    }
    exo->eth.cur_rx = (LPC_ETHERNET->DMA_CURHOST_REC_BUF == (unsigned int)(&exo->eth.rx_des[0]) ? 0 : 1);
    exo->eth.cur_tx = (LPC_ETHERNET->DMA_CURHOST_TRANS_BUF == (unsigned int)(&exo->eth.tx_des[0]) ? 0 : 1);
#else
    __disable_irq();
    io = exo->eth.rx;
    exo->eth.rx = NULL;
    __enable_irq();
    if (io != NULL)
        kexo_io_ex(exo->eth.tcpip, HAL_IO_CMD(HAL_ETH, IPC_READ), exo->eth.phy_addr, io, ERROR_IO_CANCELLED);

    __disable_irq();
    io = exo->eth.tx;
    exo->eth.tx = NULL;
    __enable_irq();
    if (io != NULL)
        kexo_io_ex(exo->eth.tcpip, HAL_IO_CMD(HAL_ETH, IPC_WRITE), exo->eth.phy_addr, io, ERROR_IO_CANCELLED);
#endif
}
Пример #3
0
static void udps_send_user(TCPIPS* tcpips, IP* src, IO* io, HANDLE handle)
{
    IO* user_io;
    unsigned int offset, size;
    UDP_STACK* udp_stack;
    UDP_HANDLE* uh;
    UDP_HEADER* hdr = io_data(io);

    uh = so_get(&tcpips->udps.handles, handle);
    for (offset = sizeof(UDP_HEADER); uh->head && offset < io->data_size; offset += size)
    {
        user_io = udps_peek_head(tcpips, uh);
        udp_stack = io_push(user_io, sizeof(UDP_STACK));
        udp_stack->remote_addr.u32.ip = src->u32.ip;
        udp_stack->remote_port = be2short(hdr->src_port_be);

        size = io_get_free(user_io);
        if (size > io->data_size - offset)
            size = io->data_size - offset;
        memcpy(io_data(user_io), (uint8_t*)io_data(io) + offset, size);
        user_io->data_size = size;
        io_complete(uh->process, HAL_IO_CMD(HAL_UDP, IPC_READ), handle, user_io);
    }
#if (UDP_DEBUG)
    if (offset < io->data_size)
        printf("UDP: %d byte(s) dropped\n", io->data_size - offset);
#endif //UDP_DEBUG
}
Пример #4
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;
    }
}
Пример #5
0
static void lpc_sdmmc_error(CORE* core, int error)
{
    if (core->sdmmc.state != SDMMC_STATE_IDLE)
    {
        iio_complete_ex(core->sdmmc.process, HAL_IO_CMD(HAL_SDMMC, core->sdmmc.state == SDMMC_STATE_READ ? IPC_READ : IPC_WRITE), 0, core->sdmmc.io, error);
        core->sdmmc.io = NULL;
        core->sdmmc.process = INVALID_HANDLE;
        core->sdmmc.state = SDMMC_STATE_IDLE;
    }
}
Пример #6
0
static inline void lpc_usb_out(CORE* core, int num)
{
    EP* ep = core->usb.out[USB_EP_NUM(num)];
    unsigned int cnt = ep->mps - (((*USB_EP_LISTSTS(num, 0)) & USB_EP_LISTST_NBYTES_MASK) >> USB_EP_LISTST_NBYTES_POS);

    io_data_append(ep->io, ep->fifo, cnt);
    if (ep->io->data_size >= ep->size || cnt < ep->mps)
    {
        ep->io_active = false;
        iio_complete(core->usb.device, HAL_IO_CMD(HAL_USB, IPC_READ), num, ep->io);
        ep->io = NULL;
    }
    else
        lpc_usb_rx_prepare(core, num);
}
Пример #7
0
void usb_on_isr(int vector, void* param)
{
    int i;
    EXO* exo = param;
    unsigned int sta = OTG_FS_GENERAL->INTSTS;

    //first two most often called
    if ((OTG_FS_GENERAL->INTMSK & OTG_FS_GENERAL_INTMSK_RXFLVLM) && (sta & OTG_FS_GENERAL_INTSTS_RXFLVL))
    {
        //mask interrupts, will be umasked by process after FIFO read
        OTG_FS_GENERAL->INTMSK &= ~OTG_FS_GENERAL_INTMSK_RXFLVLM;
        stm32_otg_on_isr_rx(exo);
        return;
    }
    for (i = 0; i < USB_EP_COUNT_MAX; ++i)
        if (exo->usb.in[i] != NULL && exo->usb.in[i]->io_active && (OTG_FS_DEVICE->INEP[i].INT & OTG_FS_DEVICE_ENDPOINT_INT_XFRC))
        {
            OTG_FS_DEVICE->INEP[i].INT = OTG_FS_DEVICE_ENDPOINT_INT_XFRC;
            if (exo->usb.in[i]->size >= exo->usb.in[i]->io->data_size)
            {
                exo->usb.in[i]->io_active = false;
                iio_complete(exo->usb.device, HAL_IO_CMD(HAL_USB, IPC_WRITE), USB_EP_IN | i, exo->usb.in[i]->io);
                exo->usb.in[i]->io = NULL;
            }
            else
                stm32_otg_tx(exo,  USB_EP_IN | i);
            return;
        }
    //rarely called
    if (sta & OTG_FS_GENERAL_INTSTS_ENUMDNE)
    {
        usb_enumdne(exo);
        OTG_FS_GENERAL->INTSTS |= OTG_FS_GENERAL_INTSTS_ENUMDNE;
        return;
    }
    if ((sta & OTG_FS_GENERAL_INTSTS_USBSUSP) && (OTG_FS_GENERAL->INTMSK & OTG_FS_GENERAL_INTMSK_USBSUSPM))
    {
        usb_suspend(exo);
        OTG_FS_GENERAL->INTSTS |= OTG_FS_GENERAL_INTSTS_USBSUSP;
        return;
    }
    if (sta & OTG_FS_GENERAL_INTSTS_WKUPINT)
    {
        usb_wakeup(exo);
        OTG_FS_GENERAL->INTSTS |= OTG_FS_GENERAL_INTSTS_WKUPINT | OTG_FS_GENERAL_INTSTS_USBSUSP;
    }
    OTG_FS_GENERAL->OTGINT  = 0xFFFFFF;// clear other request
}
Пример #8
0
bool stm32_otg_ep_flush(EXO* exo, int num)
{
    EP* ep = ep_data(exo, num);
    if (ep == NULL)
    {
        kerror(ERROR_NOT_CONFIGURED);
        return false;
    }
    if (ep->io != NULL)
    {
        kexo_io_ex(exo->usb.device, HAL_IO_CMD(HAL_USB, (num & USB_EP_IN) ? IPC_WRITE : IPC_READ), num, ep->io, ERROR_IO_CANCELLED);
        ep->io = NULL;
        ep_reg_data(num)->CTL |= OTG_FS_DEVICE_ENDPOINT_CTL_SNAK;
    }
    ep->io_active = false;
    return true;
}
Пример #9
0
bool lpc_usb_ep_flush(CORE* core, int num)
{
    EP* ep = ep_data(core, num);
    if (ep == NULL)
    {
        error(ERROR_NOT_CONFIGURED);
        return false;
    }

    ep->io_active = false;
    lpc_usb_ep_reset(core, num);
    if (ep->io != NULL)
    {
        io_complete_ex(core->usb.device, HAL_IO_CMD(HAL_USB, (num & USB_EP_IN) ? IPC_WRITE : IPC_READ), num, ep->io, ERROR_IO_CANCELLED);
        ep->io = NULL;
    }
    return true;
}
Пример #10
0
static inline void lpc_usb_in(CORE* core, int num)
{
    EP* ep = core->usb.in[USB_EP_NUM(num)];
    //handle STATUS in for set address
    if (core->usb.addr && ep->size == 0)
    {
        LPC_USB->DEVCMDSTAT |= core->usb.addr;
        core->usb.addr = 0;
    }

    if (ep->size >= ep->io->data_size)
    {
        ep->io_active = false;
        iio_complete(core->usb.device, HAL_IO_CMD(HAL_USB, IPC_WRITE), USB_EP_IN | num, ep->io);
        ep->io = NULL;
    }
    else
        lpc_usb_tx(core, num);
}
Пример #11
0
static void lpc_sdmmc_flush(CORE* core)
{
    IO* io;
    HANDLE process;
    SDMMC_STATE state = SDMMC_STATE_IDLE;
    __disable_irq();
    if (core->sdmmc.state != SDMMC_STATE_IDLE)
    {
        process = core->sdmmc.process;
        io = core->sdmmc.io;
        state = core->sdmmc.state;
        core->sdmmc.state = SDMMC_STATE_IDLE;
    }
    __enable_irq();
    if (state != SDMMC_STATE_IDLE)
    {
        sdmmcs_stop(&core->sdmmc.sdmmcs);
        io_complete_ex(process, HAL_IO_CMD(HAL_SDMMC, state == SDMMC_STATE_READ ? IPC_READ : IPC_WRITE), core->sdmmc.user, io, ERROR_IO_CANCELLED);
    }
}
Пример #12
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;
}
Пример #13
0
void lpc_eth_isr(int vector, void* param)
{
#if (ETH_DOUBLE_BUFFERING)
    int i;
#endif //ETH_DOUBLE_BUFFERING
    uint32_t sta;
    EXO* exo = (EXO*)param;
    sta = LPC_ETHERNET->DMA_STAT;
    if (sta & ETHERNET_DMA_STAT_RI_Msk)
    {
#if (ETH_DOUBLE_BUFFERING)
        for (i = 0; i < 2; ++i)
        {
            if ((exo->eth.rx[exo->eth.cur_rx] != NULL) && ((exo->eth.rx_des[exo->eth.cur_rx].ctl & ETH_RDES0_OWN) == 0))
            {
                exo->eth.rx[exo->eth.cur_rx]->data_size = (exo->eth.rx_des[exo->eth.cur_rx].ctl & ETH_RDES0_FL_MASK) >> ETH_RDES0_FL_POS;
                iio_complete(exo->eth.tcpip, HAL_IO_CMD(HAL_ETH, IPC_READ), exo->eth.phy_addr, exo->eth.rx[exo->eth.cur_rx]);
                exo->eth.rx[exo->eth.cur_rx] = NULL;
                exo->eth.cur_rx = (exo->eth.cur_rx + 1) & 1;
            }
            else
                break;
        }
Пример #14
0
static inline void lpc_sdmmc_get_media_descriptor(CORE* core, HANDLE process, HANDLE user, IO* io)
{
    STORAGE_MEDIA_DESCRIPTOR* media;
    if (!core->sdmmc.active)
    {
        error(ERROR_NOT_CONFIGURED);
        return;
    }
    if (user != core->sdmmc.user)
    {
        error(ERROR_INVALID_PARAMS);
        return;
    }
    media = io_data(io);
    media->num_sectors = core->sdmmc.sdmmcs.num_sectors;
    //SDSC/HC
    media->num_sectors_hi = 0;
    media->sector_size = core->sdmmc.sdmmcs.sector_size;
    sprintf(STORAGE_MEDIA_SERIAL(media), "%08X", core->sdmmc.sdmmcs.serial);
    io->data_size = sizeof(STORAGE_MEDIA_DESCRIPTOR) + 8 + 1;
    io_complete(process, HAL_IO_CMD(HAL_SDMMC, STORAGE_GET_MEDIA_DESCRIPTOR), core->sdmmc.user, io);
    error(ERROR_SYNC);
}