MT7628的spi_test不通问题
1、 以前做过一个用mt7628平台实现LoRa网关的项目,遇到了sx1302_hal_master无法跑通的问题。
经过一系列分析、调试,最终确定原因如下:
这个问题的原因是mt7628的spi总线驱动文件spi-mt7621.c中没有实现全双工,或者全双工实现的有问题,导致mt7628的spi每次只能发送16的字节。
而spi_test以及sx1302_hal_master都要用到全双工,尤其是后者,全双工和半双工都要用到,因此会导致不通。
下面是我修改的全双工驱动:
#define ONETXRX 16
static int mt7621_spi_transfer_full_duplex(struct spi_master *master,
struct spi_message *m)
{
struct mt7621_spi *rs = spi_master_get_devdata(master);
struct spi_device *spi = m->spi;
unsigned int speed = spi->max_speed_hz;
struct spi_transfer *t = NULL;
int status = 0;
int i, j,k,len = 0;
int total=0; //add
int rx_len = 0;
u32 txdata[64] = { 0 };
u32 rxdata[64] = { 0 };
u32 val = 0;
mt7621_spi_wait_till_ready(spi);
list_for_each_entry(t, &m->transfers, transfer_list)
{
const u8 *buf = t->tx_buf;
if (t->rx_buf)
rx_len += t->len;
if (!buf)
continue;
for (i = 0; i < t->len; i++, len++)
txdata[len / 4] |= buf[i] << (8 * (len & 3));
if (speed > t->speed_hz)
speed = t->speed_hz;
}
if (mt7621_spi_prepare(spi, speed)) {
status = -EIO;
goto msg_done;
}
total=len;
while(total>ONETXRX)
{
for (i = 0;i < ONETXRX; i += 4,j += 4)
mt7621_spi_write(rs, MT7621_SPI_DATA0 + i, txdata[j / 4]);
val |= ONETXRX * 8;
val |= (ONETXRX * 8) << 12;
mt7621_spi_write(rs, MT7621_SPI_MOREBUF, val);
mt7621_spi_set_cs(spi, 1);
val = mt7621_spi_read(rs, MT7621_SPI_TRANS);
val |= SPI_CTL_START;
mt7621_spi_write(rs, MT7621_SPI_TRANS, val);
mt7621_spi_wait_till_ready(spi);
mt7621_spi_set_cs(spi, 0);
for (i = 0; i < ONETXRX; i += 4,k+=4)
rxdata[k / 4] = mt7621_spi_read(rs, MT7621_SPI_DATA4 + i);
total-=ONETXRX;
}
if(total>0)
{
for (i = 0;i < total; i += 4,j += 4)
mt7621_spi_write(rs, MT7621_SPI_DATA0 + i, txdata[j / 4]);
val |= total * 8;
val |= (total * 8) << 12;
mt7621_spi_write(rs, MT7621_SPI_MOREBUF, val);
mt7621_spi_set_cs(spi, 1);
val = mt7621_spi_read(rs, MT7621_SPI_TRANS);
val |= SPI_CTL_START;
mt7621_spi_write(rs, MT7621_SPI_TRANS, val);
mt7621_spi_wait_till_ready(spi);
mt7621_spi_set_cs(spi, 0);
for (i = 0; i < total; i += 4,k+=4)
rxdata[k / 4] = mt7621_spi_read(rs, MT7621_SPI_DATA4 + i);
}
m->actual_length = rx_len;
len = 0;
list_for_each_entry(t, &m->transfers, transfer_list) {
u8 *buf = t->rx_buf;
if (!buf)
continue;
for (i = 0; i < t->len; i++, len++)
buf[i] = rxdata[len / 4] >> (8 * (len & 3));
}
msg_done:
m->status = status;
spi_finalize_current_message(master);
return 0;
}
该驱动我做项目的时候是通的,后来虚拟机出了问题,变成砖头了,没法打开,这是我找了半天找到的一段代码,仅作参考。