之前写的这篇文档只是简单验证一下IC-MUx的使用。并没有深入的去了解这款芯片,说实战话,供应商的技术支持是真的不行(简单吐槽一下)。搞的我这边不得不使用逻辑分析器去抓取上位机的数据进行验证。

(1)激活操作功能:在出始化的阶段需要通过ACTIVATE去激活芯片。通过发送0xB0、0x83去激活芯片,芯片会返回0xB0、0x20进行应答。

手册上面没有提到与ACTIVATE register相关的任何操作。所以具体应该写那边位去激活芯片也不明确。
文档中提到,如果不激活芯片的情况下去通讯,Read REGISTER (single), Write REGISTER (single),SDAD status and SDAD transmission都会导致REGISTER status/data里面的ERROR bit会报错。
ACTIVATE激活之后,0xAD里面的低四位会重新置位(清0)。

(2)读取寄存器状态。每次进行SPI操作的时候都需要进行状态访问来查看上一次的访问是否失败

通过OPCODE = 0xAD。一般是0xAD、0x00、0x00。
返回0xAD、0x01、0x0。其中0x1表示VALID = 1,表示上一次的数据是有效的。其中0x00的表示读取到的数据(读寄存器操作才会有效)。

**(3)写寄存器操作功能:**写寄存器的OPCODE是0xD2。指令:OPCODE + ADDR + CODE。
比如软件复位是0xD2、0x75、0x07就是对应写寄存器,写地址0x75,写命令是0x07是软复位操作。通过0xAD、0x00、0x00来判断写操作是否生效。比如返回了0xAD、0x01、0x0。


(4)读寄存器操作功能:读寄存器的OPCODE是0x97,指令:OPCODE + ADDR
比如:0x97+0x74去获取编码器的型号,然后通过0xAD、0x00、0x00来查看读操作是否生效和获取数据。返回数据是0xAD、0x01、0x15。



下面的代码仅供参考:
uint8_t wdata[4] = {0xA6,0xFF,0xFF,0xFF};
uint8_t rHdata[4] = {0};
uint8_t rLdata[4] = {0};
uint32_t EncoderFault;
static void spi_xfer(SPI_HandleTypeDef *hspi, uint8_t *txbuf, uint8_t *rxbuf, uint16_t size, uint32_t wait_ms)
{
if(hspi->Instance == SPI1)
{
SPI1_CS_L;
HAL_SPI_TransmitReceive(hspi, txbuf, rxbuf, size, 2);
SPI1_CS_H;
}
if(hspi->Instance == SPI2)
{
SPI2_CS_L;
HAL_SPI_TransmitReceive(hspi, txbuf, rxbuf, size, 2);
SPI1_CS_H;
}
if(wait_ms) HAL_Delay(wait_ms);
}
static bool icmu_activate(SPI_HandleTypeDef *hspi)
{
bool ret = false;
uint8_t txbuf[2] = {0xB0, 0x83}, rxbuf[2] = {0};
for(uint8_t i = 0; i < 3 ; i++)
{
spi_xfer(hspi, txbuf, rxbuf, 2, 1);
if(rxbuf[1] == 0x20)
{
ret = true;
break;
}
HAL_Delay(1);
}
return ret;
}
static bool icmu_read_reg(SPI_HandleTypeDef *hspi, uint8_t addr, uint8_t *rxbuf)
{
bool ret = false;
uint8_t txbuf1[2] = {0x97, addr}, rxbuf1[2] = {0};
uint8_t txbuf2[3] = {0xAD, 0x00, 0x00}, rxbuf2[3] = {0};
spi_xfer(hspi, txbuf1, rxbuf1, 2, 1);
for(uint8_t i = 0; i < 3 ; i++)
{
spi_xfer(hspi, txbuf2, rxbuf2, 3, 1);
if(rxbuf2[1] & 0x0C)
return false;
if(rxbuf2[1] & 0x02)
continue;
if(rxbuf2[1] & 0x01)
{
ret = true;
break;
}
}
*rxbuf = rxbuf2[2];
return ret;
}
static bool icmu_write_reg(SPI_HandleTypeDef *hspi, uint8_t addr,uint8_t data,uint8_t *rxbuf)
{
bool ret = false;
uint8_t txbuf1[3] = {0xD2, addr,data}, rxbuf1[3] = {0};
uint8_t txbuf2[3] = {0xAD, 0x00, 0x00}, rxbuf2[3] = {0};
spi_xfer(hspi, txbuf1, rxbuf1, 3, 1);
for(uint8_t i = 0; i < 3 ; i++)
{
spi_xfer(hspi, txbuf2, rxbuf2, 3, 1);
if(rxbuf2[1] & 0x0C)
return false;
if(rxbuf2[1] & 0x02)
continue;
if(rxbuf2[1] & 0x01)
{
ret = true;
break;
}
}
*rxbuf = rxbuf2[2];
return ret;
}
static bool soft_reset(SPI_HandleTypeDef *hspi)
{
bool ret = false;
uint8_t rxbuf;
if(icmu_write_reg(hspi,0x75,0x07,&rxbuf))
{
if(rxbuf == 0x07)
{
ret = true;
}
}
return ret;
}
static void Encoder1_Init(void)
{
uint8_t rxbuf;
uint8_t i;
for(i = 0; i < 3; i++)
{
if(!icmu_activate(&hspi1))
{
EncoderFault |= 0x00000080;
return;
}
if(icmu_read_reg(&hspi1,0x76,&rxbuf))
{
if(rxbuf != 0x00)
{
if(rxbuf & 0x10)
EncoderFault |= 0x00000001;
if(rxbuf & 0x0F)
EncoderFault |= 0x00000002;
}
rxbuf = 0x00;
}
if(icmu_read_reg(&hspi1,0x77,&rxbuf))
{
if(rxbuf != 0x0)
{
if(rxbuf & 0x37)
EncoderFault |= 0x00000004;
if(rxbuf & 0x08)
EncoderFault |= 0x00000008;
if(rxbuf & 0x40)
EncoderFault |= 0x00000010;
if(rxbuf & 0x80)
EncoderFault |= 0x00000020;
}
rxbuf = 0x00;
}
if(EncoderFault == 0x1)
{
if(soft_reset(&hspi1))
EncoderFault = 0;
else
EncoderFault |= 0x00000040;
}
else if(EncoderFault == 0x0)
{
break;
}
else
{
return;
}
}
rxbuf = 0;
if(icmu_read_reg(&hspi1,0x1E,&rxbuf))
{
if(rxbuf & 0x1)
{
EncoderFault |= 0x00000100;
}
}
}
static void Encoder2_Init(void)
{
uint8_t rxbuf;
uint8_t i;
for(i = 0; i < 3; i++)
{
if(!icmu_activate(&hspi2))
{
EncoderFault |= 0x00800000;
return;
}
if(icmu_read_reg(&hspi2,0x76,&rxbuf))
{
if(rxbuf != 0x00)
{
if(rxbuf & 0x10)
EncoderFault |= 0x00010000;
if(rxbuf & 0x0F)
EncoderFault |= 0x00020000;
}
rxbuf = 0x00;
}
if(icmu_read_reg(&hspi2,0x77,&rxbuf))
{
if(rxbuf != 0x0)
{
if(rxbuf & 0x37)
EncoderFault |= 0x00040000;
if(rxbuf & 0x08)
EncoderFault |= 0x00080000;
if(rxbuf & 0x40)
EncoderFault |= 0x00100000;
if(rxbuf & 0x80)
EncoderFault |= 0x00200000;
}
rxbuf = 0x00;
}
if(EncoderFault == 0x1)
{
if(soft_reset(&hspi2))
EncoderFault = 0;
else
EncoderFault |= 0x00400000;
}
else if(EncoderFault == 0x0)
{
break;
}
else
{
return;
}
}
rxbuf = 0;
if(icmu_read_reg(&hspi2,0x1E,&rxbuf))
{
if(!(rxbuf & 0x1))
{
EncoderFault |= 0x01000000;
}
}
}
bool Encoder1_Homing(void)
{
bool ret = false;
uint8_t rxbuf;
if(icmu_write_reg(&hspi1,0x75,0x08,&rxbuf))
{
if(rxbuf == 0x08)
ret = true;
}
return ret;
}
bool Encoder1_WriteEEPROM(void)
{
uint8_t rxbuf,txbuf[8];
if(!icmu_read_reg(&hspi1,0x78,&txbuf[0])) return false;
if(!icmu_read_reg(&hspi1,0x79,&txbuf[1])) return false;
if(!icmu_read_reg(&hspi1,0x7A,&txbuf[2])) return false;
if(!icmu_read_reg(&hspi1,0x7B,&txbuf[3])) return false;
if(!icmu_read_reg(&hspi1,0x7C,&txbuf[4])) return false;
if(!icmu_read_reg(&hspi1,0x7D,&txbuf[5])) return false;
if(!icmu_read_reg(&hspi1,0x7E,&txbuf[6])) return false;
if(!icmu_read_reg(&hspi1,0x7F,&txbuf[7])) return false;
icmu_write_reg(&hspi1,0x42,0x00,&rxbuf);
icmu_write_reg(&hspi1,0x43,0x00,&rxbuf);
icmu_write_reg(&hspi1,0x78,txbuf[0],&rxbuf);
if(rxbuf != txbuf[0]) return false;
icmu_write_reg(&hspi1,0x79,txbuf[1],&rxbuf);
if(rxbuf != txbuf[1]) return false;
icmu_write_reg(&hspi1,0x7A,txbuf[2],&rxbuf);
if(rxbuf != txbuf[2]) return false;
icmu_write_reg(&hspi1,0x7B,txbuf[3],&rxbuf);
if(rxbuf != txbuf[3]) return false;
icmu_write_reg(&hspi1,0x7C,txbuf[4],&rxbuf);
if(rxbuf != txbuf[4]) return false;
icmu_write_reg(&hspi1,0x7D,txbuf[5],&rxbuf);
if(rxbuf != txbuf[5]) return false;
icmu_write_reg(&hspi1,0x7E,txbuf[6],&rxbuf);
if(rxbuf != txbuf[6]) return false;
icmu_write_reg(&hspi1,0x7F,txbuf[7],&rxbuf);
if(rxbuf != txbuf[7]) return false;
icmu_write_reg(&hspi1,0x75,0x01,&rxbuf);
if(rxbuf != 0x01) return false;
rxbuf = 0x0;
HAL_Delay(1000);
if(icmu_read_reg(&hspi1,0x76,&rxbuf))
{
if(rxbuf != 0x00)
{
if(rxbuf & 0x10)
EncoderFault |= 0x00000001;
if(rxbuf & 0x0F)
EncoderFault |= 0x00000002;
}
rxbuf = 0x00;
}
HAL_Delay(10);
if(icmu_read_reg(&hspi1,0x77,&rxbuf))
{
if(rxbuf != 0x0)
{
if(rxbuf & 0x37)
EncoderFault |= 0x00000004;
if(rxbuf & 0x08)
EncoderFault |= 0x00000008;
if(rxbuf & 0x40)
EncoderFault |= 0x00000010;
if(rxbuf & 0x80)
EncoderFault |= 0x00000020;
}
rxbuf = 0x00;
}
HAL_Delay(10);
icmu_read_reg(&hspi1,0x78,&rxbuf);
if(rxbuf == txbuf[0])
return true;
return false;
}
void Encoder_Init(void)
{
Encoder1_Init();
Encoder2_Init();
}