IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Voir le flux RSS

Le blog de f-leb

PSoC 4 : ma carte configurée en esclave I2C, et pilotée par une Raspberry Pi - Partie 4

Noter ce billet
par , 29/04/2020 à 21h41 (1290 Affichages)
Partie 4 - Programmation de la carte esclave, test de la communication I2C

L’API en langage C du bloc SCB (Serial Communication Block) est très bien documentée chez Infineon/Cypress : PSoC 4 Serial Communication Block (SCB).

Pour les échanges I2C entre maître et esclave, deux buffers pour la lecture (ReadBuffer) et l’écriture (WriteBuffer) doivent être configurés.

Nom : buffers-i2c.PNG
Affichages : 1703
Taille : 365,8 Ko

La structure des données échangées est simple (pas de code de début ou fin de trame, pas de somme de contrôle d’intégrité du paquet échangé).

Lors d’une transaction, le Raspberry Pi (maïtre) pourra transférer 2 octets vers la carte esclave PSoC 4, à récupérer dans le buffer WriteBuffer : un code couleur (1 : rouge, 2 : vert, 3 : bleu) suivi de l’intensité de la couleur choisie entre 0 et 255. Par exemple, la séquence 0x01 suivi d’un 0xFF signifie qu’il faut allumer la composante rouge au maximum (les autres composantes restent inchangées).

En lecture, le Raspberry Pi (maître) pourra connaître en une seule transaction l’état des composantes RVB en lisant le contenu transféré du buffer ReadBuffer : 3 octets contenant respectivement les valeurs entre 0 et 255 des composantes Rouge, Vert, et Bleu respectivement.

On choisit une configuration au démarrage de la carte PSoC, par exemple R=0x00, V=0xFF et B=0x00 pour la LED allumée en vert.

Code c : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
...
/* buffers I2CSlave en lecture et écriture */
uint8 i2cReadBuffer [RD_BUFFER_SIZE];
uint8 i2cWriteBuffer[WR_BUFFER_SIZE];
...
 
    /* Led verte allumée initialement */
    PWM_Red_WriteCompare(LED_OFF);     i2cReadBuffer [0] = LED_OFF;
    PWM_Green_WriteCompare(LED_ON);    i2cReadBuffer [1] = LED_ON; 
    PWM_Blue_WriteCompare(LED_OFF);    i2cReadBuffer [2] = LED_OFF;
 
    /* Initialisation des buffers et démarrage de l'esclave I2C */
    I2CS_I2CSlaveInitReadBuf (i2cReadBuffer,  RD_BUFFER_SIZE);
    I2CS_I2CSlaveInitWriteBuf(i2cWriteBuffer, WR_BUFFER_SIZE);
    I2CS_Start();
...

Dans la boucle principale (polling), l’API permet de consulter en permanence l’état des buffers (position du pointeur symbolisée par la petite flèche bleue sur le schéma ci-dessus) et donc de connaître le statut des transferts (notamment s’ils sont complétés ou non) :

Code c : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
/* Le maître (RPi) a-t-il fini de transférer les données
        dans le buffer WriteBuffer ? (écriture maïtre vers esclave ) */
        if (0u != (I2CS_I2CSlaveStatus() & I2CS_I2C_SSTAT_WR_CMPLT))
        {
            /* Le paquet reçu par l'esclave a-t-il la bonne taille ? */
            if (WR_BUFFER_SIZE == I2CS_I2CSlaveGetWriteBufSize())
            {
...

Le code complet et commenté :
Code c : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#include <project.h>
 
/* Constantes LED */
#define LED_ON              (0xFFu)
#define LED_OFF             (0x00u)
 
/* Constantes codes couleur */
#define RED     (0x01u)
#define GREEN   (0x02u)
#define BLUE    (0x03u)
 
/* Taille des buffers, et taille du paquet */
#define WR_BUFFER_SIZE      (0x02u)
#define RD_BUFFER_SIZE      (0x03u)
 
/* Initialisation variable erreur détectée */
uint8 errorDetected = 0u;
 
/* buffers I2CSlave en lecture et écriture */
uint8 i2cReadBuffer [RD_BUFFER_SIZE];
uint8 i2cWriteBuffer[WR_BUFFER_SIZE];
 
/*******************************************************************************
* Gestionnaire d'erreur
*******************************************************************************/
void HandleError(void)
{
    /* Désactiver les interruptions globales */
    CyGlobalIntDisable;
 
    /* Boucle infinie */
    while(1){}
}
 
/*******************************************************************************
* Gestion des buffers en lecture et écriture
*******************************************************************************/
static void HandleBuffers(void)
{
    errorDetected = 0u;
 
        /* Le maître (RPi) a-t-il fini de transférer les données
        dans le buffer WriteBuffer ? (écriture maïtre vers esclave ) */
        if (0u != (I2CS_I2CSlaveStatus() & I2CS_I2C_SSTAT_WR_CMPLT))
        {
            /* Le paquet reçu par l'esclave a-t-il la bonne taille ? */
            if (WR_BUFFER_SIZE == I2CS_I2CSlaveGetWriteBufSize())
            {
                uint8_t color = i2cWriteBuffer[1]; /* intensité couleur entre 0 et 255 */
                switch (i2cWriteBuffer[0]) { /* 1er octet du buffer=code couleur */
                    /* Activation de la couleur choisie */
                    case RED :
                      PWM_Red_WriteCompare(color);
                    break;
 
                    case GREEN :
                      PWM_Green_WriteCompare(color);
                    break;
 
                    case BLUE :
                      PWM_Blue_WriteCompare(color);
                    break;
 
                    default :
                        errorDetected = 1;                   
                }                
            }
            /* erreur si donnée invalide */
            else
            {
                errorDetected = 1;
            }  
 
            /* Mise à jour du buffer ReadBuffer */
            i2cReadBuffer[0] = (uint8) PWM_Red_ReadCompare();
            i2cReadBuffer[1] = (uint8) PWM_Green_ReadCompare();
            i2cReadBuffer[2] = (uint8) PWM_Blue_ReadCompare();
 
            /* Réinitialisation du buffer WriteBuffer et de son statut
            Le pointeur est repositionné en début de tableau */
            I2CS_I2CSlaveClearWriteBuf();
            (void) I2CS_I2CSlaveClearWriteStatus();
        }
 
        /* Le maître a-t-il lu le contenu du buffer ReadBuffer ? */
        if (0u != (I2CS_I2CSlaveStatus() & I2CS_I2C_SSTAT_RD_CMPLT))
        {
            /* Réinitialisation du buffer ReadBuffer et de son statut */
            I2CS_I2CSlaveClearReadBuf();
            (void) I2CS_I2CSlaveClearReadStatus();
        }     
}
/*****************************************************************************
* main : démarrage des composants, gestion de l'I2C 
******************************************************************************/
int main()
{ 
    /* Démarrage des générateurs de signaux PWM pour la led RVB */
    PWM_Red_Start();
    PWM_Green_Start();
    PWM_Blue_Start();
 
    /* Led verte allumée initialement */
    PWM_Red_WriteCompare(LED_OFF);     i2cReadBuffer [0] = LED_OFF;
    PWM_Green_WriteCompare(LED_ON);    i2cReadBuffer [1] = LED_ON; 
    PWM_Blue_WriteCompare(LED_OFF);    i2cReadBuffer [2] = LED_OFF;
 
    /* Initialisation des buffers et démarrage de l'esclave I2C */
    I2CS_I2CSlaveInitReadBuf (i2cReadBuffer,  RD_BUFFER_SIZE);
    I2CS_I2CSlaveInitWriteBuf(i2cWriteBuffer, WR_BUFFER_SIZE);
    I2CS_Start();
 
    /* Activation des interruptions globales */
    CyGlobalIntEnable;
 
    /* Surveillance permanente des buffers */
    for (;;)
    {
        HandleBuffers();
 
        if(errorDetected == 1)
        {
            //HandleError();
        } 
    }    
}

Comment tester la communication I2C avec la carte PSoC 4 configurée en esclave I2C ?

Les concepteurs de la carte ont eu la bonne idée d’implémenter une interface USB-I2C pour permettre la communication avec un PC qui jouera le rôle de maître via la connexion USB.

Nom : kitprog-i2c-usb.PNG
Affichages : 222
Taille : 54,8 Ko

Sur le PC, l’outil Bridge Control Panel fourni avec l’EDI simulera le Raspberry Pi (maître) en permettant d’échanger des trames I2C (mais aussi des trames série ou SPI) avec la carte PSoC esclave.

Nom : bridgeControlPanel.PNG
Affichages : 245
Taille : 323,9 Ko

Dans la fenêtre d’édition, des lignes de commande, chacune correspondant à une transaction I2C en écriture (‘w’ pour write) ou en lecture (‘r’ pour read), terminée par un stop (le ‘p’ en fin de commande).
La première ligne r 08 x x x p permet de réclamer trois octets (les ‘x’) au composant esclave à l’adresse 0x08.
Plus bas, la réponse r 08+ 00+ FF+ 00+ p de l’esclave, avec les trois composantes Rouge=0x00, Vert=0xFF et Bleu=0x00 conformément à la programmation de l’esclave, et correspondant à la configuration au démarrage de la carte avec sa LED allumée en vert.

Ensuite, avec les trois lignes :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
w 08 01 ff p
w 08 03 80 p
w 08 02 40 p
On configure les couleurs, dans l’ordre :
  • rouge (code couleur=0x01, intensité=0xFF)
  • bleu (code couleur=0x03, intensité=0x80)
  • vert (code couleur=0x02, intensité=0x40)


Cette combinaison allumera notre LED RVB d’un magnifique magenta.
Et si après celà, on requiert une dernière fois les composantes RVB :
La réponse est bien conforme :
La communication maître-esclave est maintenant fonctionnelle. L’étape suivante va être de confier le rôle du maître à la carte Raspberry Pi.

Envoyer le billet « PSoC 4 : ma carte configurée en esclave I2C, et pilotée par une Raspberry Pi - Partie 4 » dans le blog Viadeo Envoyer le billet « PSoC 4 : ma carte configurée en esclave I2C, et pilotée par une Raspberry Pi - Partie 4 » dans le blog Twitter Envoyer le billet « PSoC 4 : ma carte configurée en esclave I2C, et pilotée par une Raspberry Pi - Partie 4 » dans le blog Google Envoyer le billet « PSoC 4 : ma carte configurée en esclave I2C, et pilotée par une Raspberry Pi - Partie 4 » dans le blog Facebook Envoyer le billet « PSoC 4 : ma carte configurée en esclave I2C, et pilotée par une Raspberry Pi - Partie 4 » dans le blog Digg Envoyer le billet « PSoC 4 : ma carte configurée en esclave I2C, et pilotée par une Raspberry Pi - Partie 4 » dans le blog Delicious Envoyer le billet « PSoC 4 : ma carte configurée en esclave I2C, et pilotée par une Raspberry Pi - Partie 4 » dans le blog MySpace Envoyer le billet « PSoC 4 : ma carte configurée en esclave I2C, et pilotée par une Raspberry Pi - Partie 4 » dans le blog Yahoo

Mis à jour 24/05/2023 à 17h39 par f-leb

Catégories
Raspberry Pi , Programmation , C , Infineon/Cypress PSoC

Commentaires