tweak twi init
This commit is contained in:
parent
4e0f66eb01
commit
0302d9bdb0
@ -34,7 +34,7 @@
|
|||||||
/*
|
/*
|
||||||
* while ((cldiv = ((MCK / (2 * TWI)) -3) / (1 << ckdiv)) > 255)
|
* while ((cldiv = ((MCK / (2 * TWI)) -3) / (1 << ckdiv)) > 255)
|
||||||
* ckdiv++ ;
|
* ckdiv++ ;
|
||||||
*
|
*
|
||||||
* works for TWI >= 100kHz
|
* works for TWI >= 100kHz
|
||||||
*/
|
*/
|
||||||
#define TWI_CLK(x) (((MCK / (2 * (x))) -3)<<8 | ((MCK / (2 * (x))) -3))
|
#define TWI_CLK(x) (((MCK / (2 * (x))) -3)<<8 | ((MCK / (2 * (x))) -3))
|
||||||
@ -56,34 +56,34 @@ static void twi_isr(void)
|
|||||||
/* get status */
|
/* get status */
|
||||||
uint32_t status = *AT91C_TWI_SR;
|
uint32_t status = *AT91C_TWI_SR;
|
||||||
status &= *AT91C_TWI_IMR;
|
status &= *AT91C_TWI_IMR;
|
||||||
|
|
||||||
/* NACK - disable all interrupts and go to state TWI_ERROR */
|
/* NACK - disable all interrupts and go to state TWI_ERROR */
|
||||||
if (status & AT91C_TWI_NACK) {
|
if (status & AT91C_TWI_NACK) {
|
||||||
*AT91C_TWI_IDR = AT91C_TWI_TXCOMP | AT91C_TWI_RXRDY | AT91C_TWI_TXRDY | AT91C_TWI_NACK;
|
*AT91C_TWI_IDR = AT91C_TWI_TXCOMP | AT91C_TWI_RXRDY | AT91C_TWI_TXRDY | AT91C_TWI_NACK;
|
||||||
twi_state = TWI_ERROR;
|
twi_state = TWI_ERROR;
|
||||||
|
|
||||||
// TODO: TWI_BLMC_UPDATE?
|
// TODO: TWI_BLMC_UPDATE?
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* tx register ready for new data */
|
/* tx register ready for new data */
|
||||||
if (status & AT91C_TWI_TXRDY) {
|
if (status & AT91C_TWI_TXRDY) {
|
||||||
if (twi_count != twi_size) {
|
if (twi_count != twi_size) {
|
||||||
/* feed next byte */
|
/* feed next byte */
|
||||||
*AT91C_TWI_THR = twi_data[twi_count++];
|
*AT91C_TWI_THR = twi_data[twi_count++];
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
/* wait for TXCOMP */
|
/* wait for TXCOMP */
|
||||||
*AT91C_TWI_IDR = AT91C_TWI_RXRDY | AT91C_TWI_TXRDY;
|
*AT91C_TWI_IDR = AT91C_TWI_RXRDY | AT91C_TWI_TXRDY;
|
||||||
*AT91C_TWI_IER = AT91C_TWI_TXCOMP | AT91C_TWI_NACK;
|
*AT91C_TWI_IER = AT91C_TWI_TXCOMP | AT91C_TWI_NACK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* rx register has data */
|
/* rx register has data */
|
||||||
if (status & AT91C_TWI_RXRDY) {
|
if (status & AT91C_TWI_RXRDY) {
|
||||||
/* get data */
|
/* get data */
|
||||||
twi_data[twi_count++] = *AT91C_TWI_RHR;
|
twi_data[twi_count++] = *AT91C_TWI_RHR;
|
||||||
|
|
||||||
/* transfer complete? */
|
/* transfer complete? */
|
||||||
if (twi_count == twi_size) {
|
if (twi_count == twi_size) {
|
||||||
/* send STOP and wait for TXCOMP */
|
/* send STOP and wait for TXCOMP */
|
||||||
@ -92,29 +92,29 @@ static void twi_isr(void)
|
|||||||
*AT91C_TWI_IER = AT91C_TWI_TXCOMP | AT91C_TWI_NACK;
|
*AT91C_TWI_IER = AT91C_TWI_TXCOMP | AT91C_TWI_NACK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* transfer really complete? */
|
/* transfer really complete? */
|
||||||
if (status & AT91C_TWI_TXCOMP) {
|
if (status & AT91C_TWI_TXCOMP) {
|
||||||
|
|
||||||
/* are we doing a blmc update? */
|
/* are we doing a blmc update? */
|
||||||
if (twi_state == TWI_BLMC_UPDATE) {
|
if (twi_state == TWI_BLMC_UPDATE) {
|
||||||
uint32_t addr = (*AT91C_TWI_MMR >> 16) & 0x7F;
|
uint32_t addr = (*AT91C_TWI_MMR >> 16) & 0x7F;
|
||||||
if (addr != TWI_ADDR_BL4) {
|
if (addr != TWI_ADDR_BL4) {
|
||||||
/* increase address */
|
/* increase address */
|
||||||
*AT91C_TWI_MMR += (1<<16);
|
*AT91C_TWI_MMR += (1<<16);
|
||||||
|
|
||||||
/* send next value to next blmc */
|
/* send next value to next blmc */
|
||||||
*AT91C_TWI_THR = *twi_data++;
|
*AT91C_TWI_THR = *twi_data++;
|
||||||
} else {
|
} else {
|
||||||
// TODO:
|
// TODO:
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
*AT91C_TWI_IDR = AT91C_TWI_TXCOMP | AT91C_TWI_RXRDY | AT91C_TWI_TXRDY | AT91C_TWI_NACK;
|
*AT91C_TWI_IDR = AT91C_TWI_TXCOMP | AT91C_TWI_RXRDY | AT91C_TWI_TXRDY | AT91C_TWI_NACK;
|
||||||
twi_state = TWI_IDLE;
|
twi_state = TWI_IDLE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t twi_setpwm(uint8_t *values)
|
uint32_t twi_setpwm(uint8_t *values)
|
||||||
{
|
{
|
||||||
@ -128,21 +128,21 @@ uint32_t twi_setpwm(uint8_t *values)
|
|||||||
|
|
||||||
*AT91C_TWI_MMR = (TWI_ADDR_BL1 << 16) | AT91C_TWI_IADRSZ_1_BYTE;
|
*AT91C_TWI_MMR = (TWI_ADDR_BL1 << 16) | AT91C_TWI_IADRSZ_1_BYTE;
|
||||||
*AT91C_TWI_IADR = CMD_SET_PWM;
|
*AT91C_TWI_IADR = CMD_SET_PWM;
|
||||||
|
|
||||||
*AT91C_TWI_THR = *twi_data++;
|
*AT91C_TWI_THR = *twi_data++;
|
||||||
*AT91C_TWI_IER = AT91C_TWI_TXRDY | AT91C_TWI_NACK;
|
*AT91C_TWI_IER = AT91C_TWI_TXRDY | AT91C_TWI_NACK;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t twi_cmd(uint8_t addr, struct blmc_cmd *cmd)
|
uint32_t twi_cmd(uint8_t addr, struct blmc_cmd *cmd)
|
||||||
{
|
{
|
||||||
if (twi_state != TWI_IDLE)
|
if (twi_state != TWI_IDLE)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
/* TODO: locking needed? */
|
/* TODO: locking needed? */
|
||||||
twi_state = TWI_GENERIC_CMD;
|
twi_state = TWI_GENERIC_CMD;
|
||||||
|
|
||||||
/* read transfer, or write transfer with payload */
|
/* read transfer, or write transfer with payload */
|
||||||
if (cmd->mode & BLMC_CMD_READ || cmd->size != 0) {
|
if (cmd->mode & BLMC_CMD_READ || cmd->size != 0) {
|
||||||
/* set address, direction, argument count and command bytes */
|
/* set address, direction, argument count and command bytes */
|
||||||
@ -156,7 +156,7 @@ uint32_t twi_cmd(uint8_t addr, struct blmc_cmd *cmd)
|
|||||||
*AT91C_TWI_MMR = (addr << 16) | (cmd->mode & 0xFF) << 8;
|
*AT91C_TWI_MMR = (addr << 16) | (cmd->mode & 0xFF) << 8;
|
||||||
*AT91C_TWI_IADR = (cmd->cmd) >> 8;
|
*AT91C_TWI_IADR = (cmd->cmd) >> 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* isr needs data & size parameters */
|
/* isr needs data & size parameters */
|
||||||
twi_data = cmd->data;
|
twi_data = cmd->data;
|
||||||
twi_size = cmd->size;
|
twi_size = cmd->size;
|
||||||
@ -165,14 +165,14 @@ uint32_t twi_cmd(uint8_t addr, struct blmc_cmd *cmd)
|
|||||||
if (cmd->mode & BLMC_CMD_READ) {
|
if (cmd->mode & BLMC_CMD_READ) {
|
||||||
*AT91C_TWI_CR = AT91C_TWI_START;
|
*AT91C_TWI_CR = AT91C_TWI_START;
|
||||||
*AT91C_TWI_IER = AT91C_TWI_RXRDY | AT91C_TWI_NACK;
|
*AT91C_TWI_IER = AT91C_TWI_RXRDY | AT91C_TWI_NACK;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
*AT91C_TWI_THR = (twi_size != 0) ? cmd->data[twi_count++] : (cmd->cmd & 0xFF);
|
*AT91C_TWI_THR = (twi_size != 0) ? cmd->data[twi_count++] : (cmd->cmd & 0xFF);
|
||||||
*AT91C_TWI_IER = AT91C_TWI_TXRDY | AT91C_TWI_NACK;
|
*AT91C_TWI_IER = AT91C_TWI_TXRDY | AT91C_TWI_NACK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* wait for end
|
* wait for end
|
||||||
* TODO: locking needed?
|
* TODO: locking needed?
|
||||||
* TODO: timeout?
|
* TODO: timeout?
|
||||||
*/
|
*/
|
||||||
@ -181,7 +181,7 @@ uint32_t twi_cmd(uint8_t addr, struct blmc_cmd *cmd)
|
|||||||
twi_state = TWI_IDLE;
|
twi_state = TWI_IDLE;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -235,13 +235,17 @@ void at91_twi_init(void)
|
|||||||
|
|
||||||
/* SDA & SCL from Peripheral A, Open Drain, no Pullup */
|
/* SDA & SCL from Peripheral A, Open Drain, no Pullup */
|
||||||
AT91S_PIO *pio = AT91C_BASE_PIOA;
|
AT91S_PIO *pio = AT91C_BASE_PIOA;
|
||||||
pio->PIO_ASR = AT91C_PA3_TWD | AT91C_PA4_TWCK;
|
|
||||||
pio->PIO_PDR = AT91C_PA3_TWD | AT91C_PA4_TWCK;
|
/* do a software reset (bus not connected) */
|
||||||
|
*AT91C_TWI_CR = AT91C_TWI_SWRST;
|
||||||
|
|
||||||
pio->PIO_MDER = AT91C_PA3_TWD | AT91C_PA4_TWCK;
|
pio->PIO_MDER = AT91C_PA3_TWD | AT91C_PA4_TWCK;
|
||||||
pio->PIO_PPUDR = AT91C_PA3_TWD | AT91C_PA4_TWCK;
|
pio->PIO_PPUDR = AT91C_PA3_TWD | AT91C_PA4_TWCK;
|
||||||
|
pio->PIO_ASR = AT91C_PA3_TWD | AT91C_PA4_TWCK;
|
||||||
|
pio->PIO_PDR = AT91C_PA3_TWD | AT91C_PA4_TWCK;
|
||||||
|
|
||||||
/* set TWI Clock */
|
/* set TWI Clock */
|
||||||
*AT91C_TWI_CWGR = TWI_CLK(200000) | (5<<16);
|
*AT91C_TWI_CWGR = TWI_CLK(400000); //| (5<<16);
|
||||||
|
|
||||||
/* disable all (known) interrupts */
|
/* disable all (known) interrupts */
|
||||||
*AT91C_TWI_IDR = AT91C_TWI_TXCOMP | AT91C_TWI_RXRDY | AT91C_TWI_TXRDY | AT91C_TWI_NACK;
|
*AT91C_TWI_IDR = AT91C_TWI_TXCOMP | AT91C_TWI_RXRDY | AT91C_TWI_TXRDY | AT91C_TWI_NACK;
|
||||||
|
Loading…
Reference in New Issue
Block a user