I just re-write spi transfer routine (no DMA mode) with referenced linux code which is as follows:
static int mxs_spi_txrx_pio(struct mxs_spi *ss, int cs,
unsigned char *buf, int len,
int *first, int *last, int write)
{
int count;
if (*first) {
mxs_spi_enable(ss);
*first = 0;
}
__raw_writel(mxs_spi_cs(cs), ss->regs + HW_SSP_CTRL0_SET);
while (len--) {
if (*last && len == 0) {
mxs_spi_disable(ss);
*last = 0;
}
__raw_writel(BM_SSP_CTRL0_XFER_COUNT,
ss->regs + HW_SSP_CTRL0_CLR);
__raw_writel(1, ss->regs + HW_SSP_CTRL0_SET); /* byte-by-byte */
if (write)
__raw_writel(BM_SSP_CTRL0_READ,
ss->regs + HW_SSP_CTRL0_CLR);
else
__raw_writel(BM_SSP_CTRL0_READ,
ss->regs + HW_SSP_CTRL0_SET);
/* Run! */
__raw_writel(BM_SSP_CTRL0_RUN, ss->regs + HW_SSP_CTRL0_SET);
count = 10000;
while (((__raw_readl(ss->regs + HW_SSP_CTRL0) &
BM_SSP_CTRL0_RUN) == 0) && count--)
continue;
if (count <= 0) {
printk(KERN_ERR "%c: timeout on line %s:%d\n",
write ? 'W' : 'C', __func__, __LINE__);
break;
}
if (write)
__raw_writel(*buf, ss->regs + HW_SSP_DATA);
/* Set TRANSFER */
__raw_writel(BM_SSP_CTRL0_DATA_XFER,
ss->regs + HW_SSP_CTRL0_SET);
if (!write) {
count = 10000;
while (count-- &&
(__raw_readl(ss->regs + HW_SSP_STATUS) &
BM_SSP_STATUS_FIFO_EMPTY))
continue;
if (count <= 0) {
printk(KERN_ERR "%c: timeout on line %s:%d\n",
write ? 'W' : 'C', __func__, __LINE__);
break;
}
*buf = (__raw_readl(ss->regs + HW_SSP_DATA) & 0xFF);
}
count = 10000;
while ((__raw_readl(ss->regs + HW_SSP_CTRL0) & BM_SSP_CTRL0_RUN)
&& count--)
continue;
if (count <= 0) {
printk(KERN_ERR "%c: timeout on line %s:%d\n",
write ? 'W' : 'C', __func__, __LINE__);
break;
}
/* advance to the next byte */
buf++;
}
return len < 0 ? 0 : -ETIMEDOUT;
}
The control flow is right, and you can just replace those hardware read/write functions with ones in WinCE6.0. good luck!
BTW, you may need other functions:
static inline void mxs_spi_enable(struct mxs_spi *ss)
{
__raw_writel(BM_SSP_CTRL0_LOCK_CS, ss->regs + HW_SSP_CTRL0_SET);
__raw_writel(BM_SSP_CTRL0_IGNORE_CRC, ss->regs + HW_SSP_CTRL0_CLR);
}
static inline void mxs_spi_disable(struct mxs_spi *ss)
{
__raw_writel(BM_SSP_CTRL0_LOCK_CS, ss->regs + HW_SSP_CTRL0_CLR);
__raw_writel(BM_SSP_CTRL0_IGNORE_CRC, ss->regs + HW_SSP_CTRL0_SET);
}
static inline u32 mxs_spi_cs(unsigned cs)
{
return ((cs & 1) ? BM_SSP_CTRL0_WAIT_FOR_CMD : 0) |
((cs & 2) ? BM_SSP_CTRL0_WAIT_FOR_IRQ : 0);
}