parent
a1ccdb1bd9
commit
10cab3390a
|
@ -73,15 +73,21 @@ typedef enum {
|
||||||
#define MSG_W(a, d) (static_cast<uint16_t>((MSG_SET_ADDR(a) | MSG_SET_DATA(d))))
|
#define MSG_W(a, d) (static_cast<uint16_t>((MSG_SET_ADDR(a) | MSG_SET_DATA(d))))
|
||||||
#define MSG_R(a) (static_cast<uint16_t>((MSG_SET_ADDR(MSG_READ_ADDR) | MSG_SET_SUBADDR(d))))
|
#define MSG_R(a) (static_cast<uint16_t>((MSG_SET_ADDR(MSG_READ_ADDR) | MSG_SET_SUBADDR(d))))
|
||||||
|
|
||||||
/* In frame */
|
/* Both DIN and DO */
|
||||||
/* D0 - parity */
|
/* D0 - parity */
|
||||||
#define MSG_GET_PARITY(rx) (((rx) >> 0) & 0x01)
|
#define MSG_GET_PARITY(x) (((x) >> 0) & 0x01)
|
||||||
|
/* D14:D10 - Addr of DATA IN or DATA OUT */
|
||||||
|
#define MSG_GET_ADDR(x) (((x) >> 10) & 0x1f)
|
||||||
/* D8:D1 - DATA IN */
|
/* D8:D1 - DATA IN */
|
||||||
#define MSG_GET_DATA(rx) (((rx) >> 1) & 0xff)
|
#define MSG_GET_DATA(x) (((x) >> 1) & 0xff)
|
||||||
|
|
||||||
|
/* DIN / to chip */
|
||||||
|
/* D8:D1 or 5 bits of subaddr in case of read access */
|
||||||
|
#define MSG_GET_SUBADDR(tx) (MSG_GET_DATA(tx) & 0x1f)
|
||||||
|
|
||||||
|
/* DOUT / from chip */
|
||||||
/* D 9 - W/R flag, 1 if we read */
|
/* D 9 - W/R flag, 1 if we read */
|
||||||
#define MSG_GET_WR(rx) (((rx) >> 9) & 0x01)
|
#define MSG_GET_WR(rx) (((rx) >> 9) & 0x01)
|
||||||
/* D14:D10 - Addr of DATA IN */
|
|
||||||
#define MSG_GET_ADDR(rx) (((rx) >> 10) & 0x1f)
|
|
||||||
/* D15 - SPI error flag */
|
/* D15 - SPI error flag */
|
||||||
#define MSG_GET_SPIERROR(rx) (((rx) >> 15) & 0x01)
|
#define MSG_GET_SPIERROR(rx) (((rx) >> 15) & 0x01)
|
||||||
|
|
||||||
|
@ -148,8 +154,10 @@ struct L9779 : public GpioChip {
|
||||||
|
|
||||||
l9779_drv_state drv_state;
|
l9779_drv_state drv_state;
|
||||||
|
|
||||||
/* last accessed register, for validation on next SPI access */
|
/* last accesed register */
|
||||||
uint8_t last_reg;
|
uint8_t last_addr;
|
||||||
|
/* last requested subaddr in case of read */
|
||||||
|
uint8_t last_subaddr;
|
||||||
|
|
||||||
/* chip needs reintialization due to some critical issue */
|
/* chip needs reintialization due to some critical issue */
|
||||||
bool need_init;
|
bool need_init;
|
||||||
|
@ -210,17 +218,30 @@ int L9779::spi_validate(uint16_t rx)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t reg = MSG_GET_DATA(rx);
|
/* check that correct register is returned */
|
||||||
|
if (last_subaddr != REG_INVALID) {
|
||||||
|
/* MISO DO returns 1 at D9 bit and 5bit sub address in
|
||||||
|
* ADD[4:0] field */
|
||||||
|
if (!MSG_GET_WR(rx)) {
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
if (MSG_GET_ADDR(rx) != last_subaddr) {
|
||||||
|
/* unexpected SPI answer */
|
||||||
|
spi_err++;
|
||||||
|
|
||||||
/* TODO: also check WR bit */
|
/* should ve restart? */
|
||||||
if ((last_reg != REG_INVALID) && (last_reg != reg)) {
|
//need_init = true;
|
||||||
/* unexpected SPI answer */
|
|
||||||
spi_err++;
|
|
||||||
|
|
||||||
/* should ve restart? */
|
return -1;
|
||||||
//need_init = true;
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return -1;
|
/* LOCK_UNLOCK_SW_RST */
|
||||||
|
if (last_addr == 0x0c) {
|
||||||
|
/* BIT(0) = LOCK flag */
|
||||||
|
/* START_REACT */
|
||||||
|
} else if (last_addr == 0x0d) {
|
||||||
|
/* BIT(0) = OUT_DIS */
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -259,11 +280,15 @@ int L9779::spi_rw(uint16_t tx, uint16_t *rx_ptr)
|
||||||
if (rx_ptr)
|
if (rx_ptr)
|
||||||
*rx_ptr = rx;
|
*rx_ptr = rx;
|
||||||
|
|
||||||
/* validate reply and save last accessed register */
|
/* validate reply */
|
||||||
ret = spi_validate(rx);
|
ret = spi_validate(rx);
|
||||||
last_reg = MSG_GET_ADDR(tx);
|
/* save last accessed register */
|
||||||
|
last_addr = MSG_GET_ADDR(this->tx);
|
||||||
|
if (last_addr == MSG_READ_ADDR)
|
||||||
|
last_subaddr = MSG_GET_SUBADDR(this->tx);
|
||||||
|
else
|
||||||
|
last_subaddr = REG_INVALID;
|
||||||
|
|
||||||
/* no errors for now */
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
|
@ -275,14 +300,6 @@ int L9779::spi_rw_array(const uint16_t *tx, uint16_t *rx, int n)
|
||||||
uint16_t rxdata;
|
uint16_t rxdata;
|
||||||
SPIDriver *spi = cfg->spi_bus;
|
SPIDriver *spi = cfg->spi_bus;
|
||||||
|
|
||||||
/**
|
|
||||||
* 15.1 SPI Protocol
|
|
||||||
*
|
|
||||||
* after a read or write command: the address and content of the selected register
|
|
||||||
* is transmitted with the next SPI transmission (for not existing addresses or
|
|
||||||
* wrong access mode the data is always 0)
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Acquire ownership of the bus. */
|
/* Acquire ownership of the bus. */
|
||||||
spiAcquireBus(spi);
|
spiAcquireBus(spi);
|
||||||
/* Setup transfer parameters. */
|
/* Setup transfer parameters. */
|
||||||
|
@ -304,9 +321,14 @@ int L9779::spi_rw_array(const uint16_t *tx, uint16_t *rx, int n)
|
||||||
this->rx = rxdata;
|
this->rx = rxdata;
|
||||||
this->spi_cnt++;
|
this->spi_cnt++;
|
||||||
|
|
||||||
/* validate reply and save last accessed register */
|
/* validate reply */
|
||||||
ret = spi_validate(rxdata);
|
ret = spi_validate(rxdata);
|
||||||
last_reg = getRegisterFromResponse(tx[i]);
|
/* save last accessed register */
|
||||||
|
last_addr = MSG_GET_ADDR(this->tx);
|
||||||
|
if (last_addr == MSG_READ_ADDR)
|
||||||
|
last_subaddr = MSG_GET_SUBADDR(this->tx);
|
||||||
|
else
|
||||||
|
last_subaddr = REG_INVALID;
|
||||||
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
break;
|
break;
|
||||||
|
@ -431,7 +453,8 @@ int L9779::chip_reset() {
|
||||||
*/
|
*/
|
||||||
chThdSleepMilliseconds(3);
|
chThdSleepMilliseconds(3);
|
||||||
|
|
||||||
last_reg = REG_INVALID;
|
last_addr = REG_INVALID;
|
||||||
|
last_subaddr = REG_INVALID;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue