Je me suis attaqué à l'I2C du LPC. Déjà, je connais le principe et le protocole, mais ça s'arrête la
Je me sers donc des libs de LPC, et je suis parti d'un exemple fourni avec les libs. Ça n'a pas l'air très compliqué avec la librairie, mais l'exemple fait beaucoup de chose, donc pas simple de s'y retrouver
Voila en gros ce que j'ai compris :
On a une structure I2C_XFER_T qui contient : l'adresse à laquelle on veut transmettre, l'adresse du tableau ou sont stockés les données à transmettre, ainsi que le nombre d'octets à transmettre. De même pour la lecture : un pointeur sur le tableau on l'on va stocker les données reçue, ainsi que le nombre attendu d'octet.
Ensuite, il y a deux modes : polling ou interrupt. Le polling consiste a regardé régulièrement ce qu'il se passe sur l'I2C, alors que l'interrupt interrompt l'µC dès qu'il se passe quelque chose sur l'I2C. J'aurai tendance à croire que ça concerne l'µC lorsque l'on est en slave, mais apparemment non. Et je ne sais pas trop quelle est la méthode la plus intéressante, sachant que je n'ai rien de bien rapide/critique sur le bus..
A priori, l'exemple que j'ai repris utilise le mode interrupt, car on utilise cette fonction :
qui appelle :
Code : Tout sélectionner
static void i2c_state_handling(I2C_ID_T id)
{
if (Chip_I2C_IsMasterActive(id)) {
Chip_I2C_MasterStateHandler(id);
}
else {
Chip_I2C_SlaveStateHandler(id);
}
}
Cette fonction regarde si un transfert est en cours. Si oui, elle modifie l'enum "I2C_STATUS_T". Sinon elle modifie " I2C_EVENT_T".
Ensuite l'initialisation :
Code : Tout sélectionner
static void i2c_app_init(I2C_ID_T id, int speed, int slave_address,I2C_XFER_T *xfer)
{
Init_I2C_PinMux();
address_device &= 0xFF;
xfer->slaveAddr = address_device;
xfer->rxBuff = 0;
xfer->txBuff = 0;
xfer->txSz = 0;
xfer->rxSz = 0;
/* Initialize I2C */
Chip_I2C_Init(id);
Chip_I2C_SetClockRate(id, speed);
/* Set default mode to interrupt */
i2c_set_mode(id, 0);
}
J'ai repris l'exemple, en y rajoutant l'ajoutant l'initialisation de I2C_XFER_T, bien qu'en y repensant c'est pas pratique lorsqu'il y a plusieurs adresses différentes sur le BUS. La fonction "Init_I2C_PinMux();" est appelée, je ne comprend pas trop à quoi elle sert ..
Code : Tout sélectionner
static void Init_I2C_PinMux(void)
{
Chip_IOCON_PinMuxSet(LPC_IOCON, 0, 4,
(IOCON_FUNC1 | I2C_FASTPLUS_BIT) | IOCON_DIGMODE_EN);
Chip_IOCON_PinMuxSet(LPC_IOCON, 0, 5,
(IOCON_FUNC1 | I2C_FASTPLUS_BIT) | IOCON_DIGMODE_EN);
}
Bon tout ça pour dire que j'ai écrit une fonction très simple pour lire dans un registre :
Code : Tout sélectionner
static int i2c_read_reg(I2C_XFER_T *xfer, int address_reg) {
int tmp, i;
buffer[0]=address_reg;
xfer->txSz=xfer->rxSz=1;
xfer->txBuff = buffer [0];
xfer->rxBuff = buffer [1];
Chip_I2C_MasterTransfer(i2cDev, &xfer);
return (buffer[1]);
}
La fonction est très simple, et ne gère absolument pas les erreurs, mais c'est pour le principe. ça devrait marcher, non ?