📄 intr.c
字号:
/* * $QNXLicenseC: * Copyright 2007, QNX Software Systems. * * Licensed under the Apache License, Version 2.0 (the "License"). You * may not reproduce, modify or distribute this software except in * compliance with the License. You may obtain a copy of the License * at: http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTIES OF ANY KIND, either express or implied. * * This file may contain contributions from others, either as * contributors under the License or as licensors under other terms. * Please review this entire file for other proprietary rights or license * notices, as well as the QNX Development Suite License Guide at * http://licensing.qnx.com/license-guide/ for other information. * $ */#include "mxcspi.h"/* * We use the same buffer for transmit and receive * For exchange, that's exactly what we wanted * For Read, it doesn't matter what we write to SPI, so we are OK. * For transmit, the receive data is put at the buffer we just transmitted, we are still OK. */static const struct sigevent *spi_intr(void *area, int id){ mx21_cspi_t *dev = area; uintptr_t base = dev->vbase; uint32_t data; do { data = in32(base + MX21_CSPI_RXDATA); if (dev->rlen <= dev->xlen) { switch (dev->dlen) { case 1: dev->pbuf[dev->rlen++] = data; /* * More to transmit? */ if (dev->tlen < dev->xlen) out32(base + MX21_CSPI_TXDATA, dev->pbuf[dev->tlen++]); break; case 2: *(uint16_t *)(&dev->pbuf[dev->rlen]) = data; dev->rlen += 2; /* * More to transmit? */ if (dev->tlen < dev->xlen) { out32(base + MX21_CSPI_TXDATA, *(uint16_t *)(&dev->pbuf[dev->tlen])); dev->tlen += 2; } break; case 3: case 4: *(uint32_t *)(&dev->pbuf[dev->rlen]) = data; dev->rlen += 4; /* * More to transmit? */ if (dev->tlen < dev->xlen) { out32(base + MX21_CSPI_TXDATA, *(uint32_t *)(&dev->pbuf[dev->tlen])); dev->tlen += 4; } break; } } if (dev->rlen == dev->xlen) { out32(base + MX21_CSPI_INTREG, 0); /* Disable interrupt */ return (&dev->spievent); } } while (in32(base + MX21_CSPI_INTREG) & (1 << 4)); if ((dev->tlen - dev->rlen) < 4) out32(base + MX21_CSPI_INTREG, 1 << 12); /* Enable RxFIFO data ready interrupt */ return 0;}int mx21_attach_intr(mx21_cspi_t *mx21){ if ((mx21->chid = ChannelCreate(_NTO_CHF_DISCONNECT | _NTO_CHF_UNBLOCK)) == -1) return -1; if ((mx21->coid = ConnectAttach(0, 0, mx21->chid, _NTO_SIDE_CHANNEL, 0)) == -1) goto fail0; mx21->spievent.sigev_notify = SIGEV_PULSE; mx21->spievent.sigev_coid = mx21->coid; mx21->spievent.sigev_code = MX21_CSPI_EVENT; mx21->spievent.sigev_priority = MX21_CSPI_PRIORITY; /* * Attach SPI interrupt */ mx21->iid = InterruptAttach(mx21->irq, spi_intr, mx21, 0, _NTO_INTR_FLAGS_TRK_MSK); if (mx21->iid != -1) return 0; ConnectDetach(mx21->coid);fail0: ChannelDestroy(mx21->chid); return -1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -