Mise en oeuvre de la carte Atmel AT91SAM7L-STK

Présentation

Le kit AT91SAM7L-STK rev.B dispose :

  • d’une interface RS232
  • d’une interface JTAG/ICE
  • d’un support pour 2 piles AAA
  • d’une interface ZigBee (adaptateur Atmel AT86RF230)
  • d’un afficheur LCD (10x40)
  • de cinq boutons poussoirs
  • d’une extension PIO
  • d’un bouton WakeUP (on)
  • d’un bouton Reset (off)

SAM7L128

Cette carte est équipée d’un processeur 32-bits ARM7TDMI AT91SAM7L128.

Les caractéristiques de base sont :

  • Flash : 128 kBytes
  • Max. Operating Freq. : 36 MHz
  • CPU: ARM7TDMI
  • Max I/O Pins : 80
  • SPI : 1
  • TWI (I2C) : 1
  • UART : 3
  • Segment LCD : 10x40
  • ADC : 4 canaux
  • ADC Resolution : 10 bits
  • Operating Voltage : 1.8 to 3.6 Vcc
  • Timers : 3
  • Output Compare Channels : 3
  • Input Capture Channels : 3
  • PWM Channels : 4
  • RTC : 32kHz

Le port PIO d’extension :

Documentations

La sonde Atmel SAM-ICE

Atmel SAM-ICE est un émulateur JTAG conçu pour les microcontrôleurs ARM Atmel SAMA5, SAM3, SAM4, SAM7 et SAM9. Alimenté par le port USB, il intégre un mode compatible J-Link et supporte GDB en mode serveur.

À savoir : Le JTAG (Joint Test Action Group) est le nom de la norme IEEE 1149.1 intitulée « Standard Test Access Port and Boundary-Scan Architecture ». La technique de Boundary-Scan a été conçue pour faciliter et automatiser le test des cartes électroniques numériques. Elle consiste à donner un accès auxiliaire aux broches d’entrée-sortie des composants numériques fortement intégrés. La norme JTAG est utilisée pour remplacer les émulateurs de microprocesseurs (systèmes de débug sur carte remplaçant physiquement le composant), en donnant un accès direct à l’intérieur du processeur (points d’arrêt, lecture et écriture des registres internes, des mémoires internes et externes …) sans perturber ses interactions avec l’extérieur. On nomme cette technique ICE (In-Circuit Emulator) ou ICD (In-Circuit Debugger), et elle est omniprésente sur les microprocesseurs et microcontrôleurs modernes. Le bus JTAG est également utilisé pour programmer de nombreux microcontrôleurs (grâce à la capacité du JTAG de programmer la mémoire Flash) et pour débugger un microprocesseur. Le bus JTAG est un bus série synchrone.

Sous Linux, SAM-ICE est pris en charge par OpenOCD (Open On-Chip Debugger) ou J-Link SEGGER (https://www.segger.com/jlink-software.html).

Mise en oeuvre sous Linux (testée sous Ubuntu 12.04)

On aura besoin :

  • JLink SEGGER pour flasher et débugger le programme sur la carte
  • de la chaîne de compilation croisée gcc-arm-none-eabi pour créer des programmes pour MCU ARM
$ sudo dpkg -i jlink_5.12.7_x86_64.deb
  • Test :
$ JLinkGDBServer -if JTAG -device AT91SAM7L128

Installation de gcc-arm-none-eabi

La procédure est décrite à cette adresse : http://gnuarmeclipse.github.io/toolchain/install/

  • Prérequis :
$ sudo apt-get -y install lib32z1 lib32ncurses5 lib32bz2-1.0
$ sudo apt-get -y install ia32-libs
  • Télécharger l’archive à installer :
$ cd /usr/local
$ sudo wget -c https://launchpad.net/gcc-arm-embedded/5.0/5-2016-q1-update/+download/gcc-arm-none-eabi-5_3-2016q1-20160330-linux.tar.bz2
  • Installer l’archive :
$ sudo tar xjf gcc-arm-none-eabi-5_3-2016q1-20160330-linux.tar.bz2
  • Test :
$ /usr/local/gcc-arm-none-eabi-5_3-2016q1/bin/arm-none-eabi-gcc -v
...
gcc version 5.3.1 20160307 (release) [ARM/embedded-5-branch revision 234589] (GNU Tools for ARM Embedded Processors) 

$ /usr/local/gcc-arm-none-eabi-5_3-2016q1/bin/arm-none-eabi-gcc
arm-none-eabi-gcc: fatal error: no input files
compilation terminated.

La chaîne de compilation croisée est prête à l’emploi.

Mise en oeuvre sous Windows (testée sous Windows 8)

On aura besoin :

  • du logiciel sam-ba pour flasher un programme sur la carte
  • JLink SEGGER pour gérer l’interface SAM-ICE via l’extension JTAG de la carte
  • de la chaîne de compilation croisée gcc-arm-none-eabi pour créer des programmes pour MCU ARM
  • du progamme mingw32-make de MinGW

Remarque : Certains outils sont fournis avec le CD joint au kit.

Installer :

Exemples

Remarque : j’ai démarré à partir d’un exemple fourni sur le CD qui correspond à la version 1.4 de l’API. Sinon la version 1.5 est disponible ici.

Codes sources :

Remarque : Les différents projets pour les deux systèmes Linux et Windows se distinguent seulement par leur Makekile et la façon de flasher le programme.

Mise en oeuvre du bus I2C/TWI :

I2C (Inter-Integrated Circuit) est un bus de données qui permet de relier facilement un microprocesseur et différents circuits électroniques. Conçu par Philips en 1982 pour les applications de domotique et d’électronique domestique, il a permis d’interconnecter les composants d’une télévision moderne : récepteur de la télécommande, réglages des amplificateurs basses fréquences, tuner, horloge, gestion de la prise péritel, etc.

Il existe maintenant d’innombrables périphériques exploitant ce bus, dont beaucoup de microcontrôleurs. Le poids de l’industrie de l’électronique grand public a permis des prix très bas grâce à ces nombreux composants.

Remarque : Ce bus porte parfois le nom de TWI (Two Wire Interface) chez certains constructeurs. C’est la cas ici avec Atmel.

I2C est un bus série synchrone bidirectionnel half-duplex. Le débit peut aller jusqu’à 400 Kbits/s (100 Kbits/s en mode standard).

Plusieurs équipements, soit maîtres, soit esclaves, peuvent être connectés au bus. Les échanges ont toujours lieu entre un seul maître et un (ou tous les) esclave(s), toujours à l’initiative du maître (jamais de maître à maître ou d’esclave à esclave). Cependant, rien n’empêche un composant de passer du statut de maître à esclave et réciproquement.

La connexion est réalisée par l’intermédiaire de deux lignes :

  • SDA (Serial Data Line) ou TWD : ligne de données bidirectionnelle,
  • SCL (Serial Clock Line) ou TWCK : ligne d’horloge de synchronisation unidirectionnelle (maître/esclaves) ou bidirectionnelle (multi-maîtres).

Remarque : Il ne faut également pas oublier la masse (GND) qui doit être commune aux équipements.

Le nombre maximal d’équipements est limité par le nombre d’adresses disponibles, 7 bits pour l’adresse et un bit pour définir si on écrit ou on lit (R/W), soit en théorie 128 périphériques. De nombreuses adresses sont déjà attribuées par les fabricants ce qui limite grandement le nombre d’équipements. Un mode d’adressage sur 10 bits existent mainteant.

On désire lire et/ou écrire une E/S numérique à partir d’un circuit I2C. On utilisera le circuit PCF8574 qui dispose de 8 E/S.

Documentation : PCF8574.pdf

Remarque : l’adresse de base du PCF8574 est 0x40 avec le bit R/W et 0x20 donc (0x40 >> 1) si le bit R/W (poids faible) n’intervient pas dans l’adresse du circuit I2C.

La carte AT91SAM7L-STK dispose d’un bus TWI :

On va donc utiliser le bus TWI avec les lignes PC11 (SCL) et PC10 (SDA) :

Remarque : les deux résistances de pull-up ne sont pas présentes sur la carte AT91SAM7L-STK.

//------------------------------------------------------------------------------
//         Headers
//------------------------------------------------------------------------------
#include <board.h>
#include <pit/pit.h>
#include <slcdc/slcdc.h>
#include <supc/supc.h>
#include <pio/pio.h>
#include <aic/aic.h>
#include <tc/tc.h>
#include <slcd/s7lstklcd/s7lstklcd.h>
#include <pio/pio_it.h>
#include <dbgu/dbgu.h>
#include <twi/twi.h>
#include <utility/math.h>
#include <utility/assert.h>
#include <utility/trace.h>
#include <drivers/twi/twid.h>
#include <stdio.h>
#include <string.h>

//------------------------------------------------------------------------------
//         Local definitions
//------------------------------------------------------------------------------

/// Softpack Version
#define SOFTPACK_VERSION "1.4"

/// Scrolling frequency in Hz.
#define SCROLLING_FREQUENCY     8

/// String is scrolling to the left
#define SCROLL_LEFT             0
/// String is scrolling to the right
#define SCROLL_RIGHT            1

#define LCD_OFF                 0
#define LCD_ON                  1

/// Master clock frequency in Hz
#define MCK                     32768

/// TWI clock frequency in Hz.
#define TWCK            400000

/// Slave address of AT24C chips.
#define I2C_ADDRESS     0x20

//------------------------------------------------------------------------------
//         Local variables
//------------------------------------------------------------------------------

/// Pins to configure for the application
static const Pin pPins[] = {BOARD_MAX3318E_ENABLE_FORCEOFF, BOARD_MAX3318E_DISABLE_PULLUPS};

/// Pushbutton pin instance.
const Pin pinPB1 = PIN_PUSHBUTTON_1; // CENTRE
const Pin pinPB2 = PIN_PUSHBUTTON_2; // HAUT
const Pin pinPB3 = PIN_PUSHBUTTON_3; // DROITE
const Pin pinPB4 = PIN_PUSHBUTTON_4; // BAS
const Pin pinPB5 = PIN_PUSHBUTTON_5; // GAUCHE

static unsigned char lcdScreen = LCD_ON;

/// Pio pins to configure.
static const Pin pinsTWI[] = {PINS_TWI};

/// TWI driver instance.
static Twid twid;

/// TWI buffer.
static unsigned char pData[1];

//------------------------------------------------------------------------------
//         Local functions
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
/// TWI interrupt handler. Forwards the interrupt to the TWI driver handler.
//------------------------------------------------------------------------------
void ISR_Twi(void)
{
    TWID_Handler(&twid);
}

//------------------------------------------------------------------------------
/// Configures TWI.
//------------------------------------------------------------------------------
static void ConfigureTWI(void)
{
    PIO_Configure(pinsTWI, PIO_LISTSIZE(pinsTWI));
    
    // Configure TWI
    // In IRQ mode: to avoid problems, the priority of the TWI IRQ must be max.
    // In polling mode: try to disable all IRQs if possible.
    // (in this example it does not matter, there is only the TWI IRQ active)
    AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_TWI;
    TWI_ConfigureMaster(AT91C_BASE_TWI, TWCK, BOARD_MCK);
    TWID_Initialize(&twid, AT91C_BASE_TWI);
    AIC_ConfigureIT(AT91C_ID_TWI, 0, ISR_Twi);
    AIC_EnableIT(AT91C_ID_TWI);
    
    memset(pData, 0, 1);
}

//------------------------------------------------------------------------------
/// Initializes the SLCD controller with the board parameters.
//------------------------------------------------------------------------------
static void InitializeSlcd(void)
{
    // Enable SLCD internal power supply (3V)
    SUPC_EnableSlcd(AT91C_SUPC_LCDMODE_INTERNAL);
    SUPC_SetSlcdVoltage(0x9);
    
    // Disable SLCD
    SLCDC_Disable();
    
    //  Define the number of COM and SEG, Buffer driving time; select the bias
    SLCDC_Configure(S7LSTKLCD_NUM_COMMONS,
                    S7LSTKLCD_NUM_SEGMENTS,
                    AT91C_SLCDC_BIAS_1_3,
                    AT91C_SLCDC_BUFTIME_0_percent);
    
    // Set frame rate 30 Hz
    SLCDC_SetFrameFreq(AT91C_SLCDC_PRESC_SCLK_32, AT91C_SLCDC_DIV_2);
    
    //  Enable SLCD
    SLCDC_Enable();
}

//------------------------------------------------------------------------------
/// Interrupt service routine for the Timer Counter 0. Makes the displayed
/// string scroll from left to right.
//------------------------------------------------------------------------------
static void ISR_Tc0(void)
{
    static unsigned char lastData = 0x00;
    
    TWID_Read(&twid, I2C_ADDRESS, 0, 0, pData, 1, 0);
    if(pData[0] != lastData)
    {
        printf("pData[0] = 0x%02X\r\n", pData[0]);
        lastData = pData[0];
    }
}

//------------------------------------------------------------------------------
/// Interrupt handler for pushbutton\#1.
//------------------------------------------------------------------------------
static void ISR_Bp1(void)
{
    // Check if the button has been pressed
    if (!PIO_Get(&pinPB1))
    {
        printf("Bp1 ");
        memset(pData, 0, 1);
        pData[0] = 0x01;
        TWID_Write(&twid, I2C_ADDRESS, 0, 0, pData, 1, 0);
        SLCDC_Clear();
        S7LSTKLCD_String(0, 1, "Bp 1");
        SLCDC_SetDisplayMode(AT91C_SLCDC_DISPMODE_NORMAL);
    }
}

//------------------------------------------------------------------------------
/// Interrupt handler for pushbutton\#2.
//------------------------------------------------------------------------------
static void ISR_Bp2(void)
{
    // Check if the button has been pressed
    if (!PIO_Get(&pinPB2))
    {
        printf("Bp2 ");
        memset(pData, 0, 1);
        pData[0] = 1 << 1;
        TWID_Write(&twid, I2C_ADDRESS, 0, 0, pData, 1, 0);
        SLCDC_Clear();
        S7LSTKLCD_String(0, 1, "Bp 2");
        SLCDC_SetDisplayMode(AT91C_SLCDC_DISPMODE_NORMAL);
    }
}

//------------------------------------------------------------------------------
/// Interrupt handler for pushbutton\#3.
//------------------------------------------------------------------------------
static void ISR_Bp3(void)
{
    // Check if the button has been pressed
    if (!PIO_Get(&pinPB3))
    {
        printf("Bp3 ");
        memset(pData, 0, 1);
        pData[0] = 1 << 2;
        TWID_Write(&twid, I2C_ADDRESS, 0, 0, pData, 1, 0);
        SLCDC_Clear();
        S7LSTKLCD_String(0, 1, "Bp 3");
        SLCDC_SetDisplayMode(AT91C_SLCDC_DISPMODE_NORMAL);
    }
}

//------------------------------------------------------------------------------
/// Interrupt handler for pushbutton\#4.
//------------------------------------------------------------------------------
static void ISR_Bp4(void)
{
    // Check if the button has been pressed
    if (!PIO_Get(&pinPB4))
    {
        printf("Bp4 ");
        memset(pData, 0, 1);
        pData[0] = 1 << 3;
        TWID_Write(&twid, I2C_ADDRESS, 0, 0, pData, 1, 0);
        SLCDC_Clear();
        S7LSTKLCD_String(0, 1, "Bp 4");
        SLCDC_SetDisplayMode(AT91C_SLCDC_DISPMODE_NORMAL);
    }
}

//------------------------------------------------------------------------------
/// Interrupt handler for pushbutton\#5.
//------------------------------------------------------------------------------
static void ISR_Bp5(void)
{
    // Check if the button has been pressed
    if (!PIO_Get(&pinPB5)) 
    {
        printf("Bp5 ");
        memset(pData, 0, 1);
        pData[0] = 1 << 4;
        TWID_Write(&twid, I2C_ADDRESS, 0, 0, pData, 1, 0);
        SLCDC_Clear();
        S7LSTKLCD_String(0, 1, "Bp 5");
        SLCDC_SetDisplayMode(AT91C_SLCDC_DISPMODE_NORMAL);
    }
}

//------------------------------------------------------------------------------
/// Configures the pushbuttons to generate interrupts when pressed.
//------------------------------------------------------------------------------
static void ConfigureButtons(void)
{
    // Configure pios
    PIO_Configure(&pinPB1, 1);
    PIO_Configure(&pinPB2, 1);
    PIO_Configure(&pinPB3, 1);
    PIO_Configure(&pinPB4, 1);
    PIO_Configure(&pinPB5, 1);

    // Initialize interrupts
    PIO_InitializeInterrupts(AT91C_AIC_PRIOR_LOWEST);
    PIO_ConfigureIt(&pinPB1, (void (*)(const Pin *)) ISR_Bp1);
    PIO_ConfigureIt(&pinPB2, (void (*)(const Pin *)) ISR_Bp2);
    PIO_ConfigureIt(&pinPB3, (void (*)(const Pin *)) ISR_Bp3);
    PIO_ConfigureIt(&pinPB4, (void (*)(const Pin *)) ISR_Bp4);
    PIO_ConfigureIt(&pinPB5, (void (*)(const Pin *)) ISR_Bp5);
    PIO_EnableIt(&pinPB1);
    PIO_EnableIt(&pinPB2);
    PIO_EnableIt(&pinPB3);
    PIO_EnableIt(&pinPB4);
    PIO_EnableIt(&pinPB5);
}

//------------------------------------------------------------------------------
/// Main function
//------------------------------------------------------------------------------
int main(void)
{   
    unsigned int div, tcclks;
    
    // DBGU configuration
    trace_CONFIGURE(DBGU_STANDARD, 115200, BOARD_MCK);
    
    /*const Pin pinsDbgu[] = {PINS_DBGU};
    PIO_Configure(pinsDbgu, PIO_LISTSIZE(pinsDbgu));
    DBGU_Configure(DBGU_STANDARD, 115200, BOARD_MCK);*/
    
    printf("-- Getting Started Project %s --\n\r", SOFTPACK_VERSION);
    printf("-- %s\n\r", BOARD_NAME);
    printf("-- Compiled: %s %s --\n\r", __DATE__, __TIME__);
    
    printf("Start I2C 0x%02X\n\r", I2C_ADDRESS);
    ConfigureTWI();
    ConfigureButtons();
    //PIO_Configure(pPins, PIO_LISTSIZE(pPins));
    
    // Initialize SLCD
    InitializeSlcd();
    SLCDC_Clear();
    S7LSTKLCD_String(0, 1, "I2C");
    SLCDC_SetDisplayMode(AT91C_SLCDC_DISPMODE_NORMAL);

    // Configure timer for interrupt every 250ms
    AT91C_BASE_PMC->PMC_PCER |= 1 << AT91C_ID_TC0;
    TC_FindMckDivisor(SCROLLING_FREQUENCY, MCK, &div, &tcclks);
    TC_Configure(AT91C_BASE_TC0, tcclks | AT91C_TC_CPCTRG);
    AT91C_BASE_TC0->TC_RC = (MCK / div) / SCROLLING_FREQUENCY;
    AIC_ConfigureIT(AT91C_ID_TC0, 0, ISR_Tc0);
    AIC_EnableIT(AT91C_ID_TC0);
    AT91C_BASE_TC0->TC_IER = AT91C_TC_CPCS;
    TC_Start(AT91C_BASE_TC0);

    // Test
    /*memset(pData, 0, 1);
    pData[0] = 0x55;
    TWID_Write(&twid, I2C_ADDRESS, 0, 0, pData, 1, 0);

    // Wait at least 10 ms
    unsigned int i = 0;
    for (i=0; i < 1000000; i++);

    printf("Read I2C 0x%02X\n\r", I2C_ADDRESS);
    // Read back data
    memset(pData, 0, 1);
    TWID_Read(&twid, I2C_ADDRESS, 0, 0, pData, 1, 0);
    printf("pData[0] = 0x%02X\r\n", pData[0]);*/
    
    // Infinite loop
    while(1);
}

Test sous Linux

$ unzip slcd-bp-project-1.4-at91sam7l-stk-linux.zip

$ cd slcd-bp-project-1.4-at91sam7l-stk-linux/slcd-bp-project

$ make

$ cd bin

$ JLinkExe -if JTAG -device AT91SAM7L128 -speed 5000
SEGGER J-Link Commander V5.12g (Compiled May 27 2016 17:03:43)
DLL version V5.12g, compiled May 27 2016 17:03:38

Connecting to J-Link via USB...O.K.
Firmware: J-Link ARM V8 compiled Aug 26 2015 15:08:21
Hardware version: V8.00
S/N: 28010360
License(s): RDI
OEM: SAM-ICE
VTref = 2.698V

J-Link>loadbin slcd-bp-at91sam7l-stk-at91sam7l128-flash.bin 0x00100000
Target connection not established yet but required for command.
Device position in JTAG chain (IRPre,DRPre) <Default>: -1,-1 => Auto-detect
JTAGConf>connect
ERROR while parsing value for IRPre. Using default: -1.
ERROR while parsing value for DRPre. Using default: -1.
Device "AT91SAM7L128" selected.
TotalIRLen = 4, IRPrint = 0x01
Found 1 JTAG device, Total IRLen = 4:
 #0 Id: 0x3F0F0F0F, IRLen: 04, IRPrint: 0x1, ARM7TDMI Core
ARM7 identified.
Downloading file [slcd-bp-at91sam7l-stk-at91sam7l128-flash.bin]...

**************************
WARNING: CPU is running at low speed (1872 kHz).
**************************

Comparing flash   [100%] Done.
Erasing flash     [100%] Done.
Programming flash [100%] Done.
Verifying flash   [100%] Done.
J-Link: Flash download: Flash programming performed for 2 ranges (15196 bytes)
J-Link: Flash download: Total time needed: 1.211s (Prepare: 0.038s, Compare: 0.226s, Erase: 0.000s, Program: 0.763s, Verify: 0.178s, Restore: 0.005s)
O.K.

J-Link>r
Reset delay: 0 ms
Reset type NORMAL: Using RESET pin, halting CPU after Reset
J-Link>exit

Appuyez sur le bouton Reset (off) puis sur le bouton WakeUP (on).

Remarque : vous pouvez utiliser un script pour automatiser le flashage et le lancement du rogramme (cf. Annexe n°1 et 2)

Test sous Windows

Décompresser l’archive slcd-bp-project-1.4-at91sam7l-stk-windows.zip

Lancer cmd.exe

Se déplacer dans le dossier slcd-bp-project-1.4-at91sam7l-stk-windows/slcd-bp-project

Taper make (ou mingw32-make)

Lancer Sam-ba

Choisir le fichier slcd-bp-at91sam7l-stk-at91sam7l128-flash.bin puis cliquer sur Send File (Répondre Non ensuite)

Cliquer sur Execute après avoir sélectionner Boot from Flash

Quitter Sam-ba et Appuyer sur le bouton Reset (off) puis sur le bouton WakeUP (on).

Embedded Studio

Embedded Studio est un EDI (Environnement de Développement Intégré ou IDE pour Integrated Development Environment) C/C++ pour les microcontrôleurs ARM.

Glossaire

MCU
MCU (MicroController Unit) est un microcontrôleur (µc ou uc). C’est un circuit intégré qui rassemble les éléments essentiels d’un ordinateur : processeur, mémoires (mémoire morte pour le programme, mémoire vive pour les données), unités périphériques et interfaces d’entrées-sorties. Les microcontrôleurs se caractérisent par un plus haut degré d’intégration, une plus faible consommation électrique, une vitesse de fonctionnement plus faible et un coût réduit par rapport aux microprocesseurs polyvalents utilisés dans les ordinateurs personnels. Les microcontrôleurs sont fréquemment utilisés dans les systèmes embarqués. Lire : https://fr.wikipedia.org/wiki/Microcontr%C3%B4leur.
Système embarqué
Un système embarqué est défini comme un système électronique et informatique autonome, souvent temps réel, spécialisé dans une tâche bien précise. Le terme désigne aussi bien le matériel informatique que le logiciel utilisé. Ses ressources sont généralement limitées. Cette limitation est généralement d’ordre spatial (encombrement réduit) et énergétique (consommation restreinte).
ARM
ARM est une société britannique spécialisée dans le développement d’architectures 32 bits de type RISC. Fondée sous la forme d’une coentreprise par Acorn Computers, Apple Computer (maintenant Apple Inc.) et VLSI Technology, ARM développe également un grand nombre de blocs de propriété intellectuelle (IP). Elle est basée sur un modèle économique particulier de la microélectronique : la conception de propriétés intellectuelles (Intellectual Properties). Ainsi il n’est pas possible d’acheter un processeur ARM comme c’est le cas pour Intel. Les cœurs ARM sont intégrés au sein de systèmes sur puces (SoC) complets. Les cœurs de processeurs ARM sont très présents dans les systèmes embarqués (téléphone mobile, console portable, tablette électronique).
Architecture ARM
Les architectures ARM sont des architectures matérielles RISC 32 bits (ARMv1 à ARMv7) et 64 bits (ARMv8)1 développées par ARM Ltd depuis 1990 et introduites à partir de 1983 par Acorn Computers. Dotés d’une architecture relativement plus simple que d’autres familles de processeurs, et bénéficiant d’une faible consommation, les processeurs ARM sont devenus dominants dans le domaine de l’informatique embarquée, en particulier la téléphonie mobile et les tablettes. Ces processeurs sont fabriqués sous licence par un grand nombre de constructeurs.
Mémoire Flash
La mémoire flash est une mémoire de masse à semi-conducteurs ré-inscriptible, c’est-à-dire une mémoire possédant les caractéristiques d’une mémoire vive mais dont les données ne disparaissent pas lors d’une mise hors tension. Ainsi, la mémoire flash stocke les bits de données dans des cellules de mémoire, mais les données sont conservées en mémoire lorsque l’alimentation électrique est coupée. La technique flash se décline sous deux principales formes : flash NOR et NAND, selon le type de porte logique utilisée pour chaque cellule de stockage. Sa durée de vie est limitée par le nombre de cycles d’écriture.
Toolchain
Une chaîne de compilation (toolchain) désigne l’ensemble des paquets utilisés dans le processus de compilation d’un programme, pour un processeur donné. Le compilateur n’est qu’un élément de cette chaîne, laquelle varie selon l’architecture matérielle cible. Une chaîne de compilation croisée est une chaîne compilée pour fonctionner sur l’architecture de processeurs de la machine hôte, mais qui va compiler des logiciels pour une architecture cible différente.
Compilation croisée
La compilation croisée fait donc référence aux chaînes de compilation capables de traduire un code source en code objet dont l’architecture processeur diffère de celle où la compilation est effectuée. Ces chaînes sont principalement utilisés en informatique industrielle et dans les systèmes embarqués.
make
make est un logiciel traditionnel d’UNIX. C’est un “moteur de production” : il sert à appeler des commandes créant des fichiers. À la différence d’un simple script shell, make exécute les commandes seulement si elles sont nécessaires. Le but est d’arriver à un résultat (logiciel compilé ou installé, documentation créée, etc.) sans nécessairement refaire toutes les étapes. make fut à l’origine développé par le docteur Stuart Feldman, en 1977. Ce dernier travaillait alors pour Bell Labs. make est un outil indispensable aux développeurs car :
  • make assure la compilation séparée automatisée : plus besoin de taper une série de commandes
  • make permet de ne recompiler que le code modifié : optimisation du temps et des ressources
  • make utilise un fichier distinct contenant les règles de fabrication (Makefile) : mémorisation de règles spécifiques longues et complexes à retaper
  • make permet d’utiliser des commandes (ce qui permet d’assurer des tâches de nettoyage, d’installation, d’archivage, etc …) : une seule commande pour différentes tâches
  • make utilise des variables, des directives, … : facilite la souplesse, le portage et la réutilisation
Makefile
Le fichier Makefile contient la description des opérations nécessaires pour générer une application. Pour faire simple, il contient les règles à appliquer lorsque les dépendances ne sont plus respectées. Le fichier Makefile sera lu et exécuté par la commande make. Une règle est une suite d’instructions qui seront exécutées pour construire une cible si la cible n’existe pas ou si des dépendances sont plus récentes. La syntaxe d’une règle est la suivante :
cible : dépendance(s)
<TAB>commande(s)
LCD
LCD(Liquid Crystal Display) est un écran à cristaux liquides qui permet la création d’écran plat à faible consommation d’électricité. Aujourd’hui ces écrans sont utilisés dans presque tous les affichages électroniques. Les premiers afficheurs LCD datent du début des années 1970. Lire l’article sur les écrans à cristaux liquides sur Wikipedia.
Sam-ba
Le logiciel SAM-BA est un ensemble d’outils pour la programmation des microcontrôleurs ARM fourni par Atmel.
MinGW
MinGW ou Mingw32 (Minimalist GNU for Windows) est une adaptation des logiciels de développement et de compilation du GNU (GCC - GNU Compiler Collection), à la plate-forme Win32.
PIO
PIO (Parallel Input Output) est un port parallèle d’entrée/sortie. Chaque ligne peut être utilisée comme une entrée ou une sortie standard.
Bus TWI/I2C (compléments)
Le codage utilisé sur le bus TWI/I2C est de type NRZ (non retour à 0) :

Le niveau (« HIGH » ou « LOW ») de la ligne SDA doit être maintenu stable pendant le niveau « HIGH » sur la ligne SCL pour la lecture du bit.

Il existe cinq vitesses de transmission :

  • « Standard mode » ≤ 100 kbit/s,
  • « Fast mode » ≤ 400 kbit/s,
  • « Fast plus mode » ≤ 1 Mbit/s,
  • « High-speed mode » ≤ 3,4 Mbit/s,
  • « Ultra-fast mode » ≤ 5 Mbit/s.

Le bus étant synchrone, c’est le maître qui impose l’horloge via la ligne SCL.

Échange maître/esclave
Le message peut être décomposé en deux parties :
  • Le maître est l’émetteur, l’esclave est le récepteur :
    • émission d’une condition de START par le maître (« S »),
    • émission de l’octet d’adresse par le maître pour désigner un esclave, avec le bit R/W à 0,
    • réponse de l’esclave par un bit d’acquittement ACK (ou de non-acquittement NACK),
    • émission d’un octet de commande par le maître pour l’esclave,
    • réponse de l’esclave par un bit d’acquittement ACK (ou de non-acquittement NACK),
    • émission d’une condition de RESTART par le maître (« RS »),
    • émission de l’octet ou des octets d’adresse par le maître pour désigner le même esclave, avec le bit R/W à 1.
  • Le maître devient récepteur, l’esclave devient émetteur :
    • émission d’un octet de données par l’esclave pour le maître,
    • réponse du maître par un bit d’acquittement ACK (ou de non-acquittement NACK),
    • (émission d’autres octets de données par l’esclave avec acquittement du maître),
    • pour le dernier octet de données attendu par le maître, il répond par un NACK pour mettre fin au dialogue,
    • émission d’une condition de STOP par le maître (« P »).

La condition de START est une transgression de la règle de codage des bits qui est utilisée par le maître pour signifier le début d’une trame. Cette condition est caractérisée par le passage de la ligne SDA du niveau « HIGH » au niveau « LOW » pendant que la ligne « SCL » est maintenue au niveau « HIGH ».

La condition de STOP est une transgression de la règle de codage des bits qui est utilisée par le maître pour signifier la fin d’une trame. Cette condition est caractérisée par le passage de la ligne SDA du niveau « LOW » au niveau « HIGH » pendant que la ligne SCL est maintenue au niveau « HIGH ».

Le récepteur positionne le bit d’acquittement à :

  • « ACK », en forçant la ligne SDA au niveau « LOW », pour signaler la bonne réception de l’octet, équivalent à un bit à 0,
  • « NACK », en laissant la ligne SDA au niveau « HIGH », pour signaler un défaut dans la réception de l’octet, équivalent à un bit à 1.
Adressage I2C
L’octet d’adressage peut être scindé en deux parties :
  • les sept premiers bits correspondent à l’adresse proprement dite,
  • le dernier bit est nommé R/W :
    • s’il est à 0, le maître signale qu’il va envoyer des octets, et donc que l’esclave doit les lire,
    • s’il est à 1, le maître indique qu’il veut recevoir des octets, et donc que l’esclave doit les fournir.

On peut également considérer que l’adresse est codée sur les 8 bits, chaque esclave a alors deux adresses, l’adresse paire qui sert à lui envoyer des données, l’adresse impaire pour lui demander d’en envoyer.

Généralement, les fabricants des circuits I2C fixent une partie de l’adresse pour permettre d’identifier le type de circuit et laissent une partie libre permettant de relier plusieurs circuits du même type sur le bus.

Par exemple, le circuit I2C de 8 bits E/S (I/O) est déclinée en deux versions donnant deux adresses de base :

  • PCF8574 dont les 7 bits d’adresses sont : 0100 A2A1A0 -> 0x4.
  • PCF8574A dont les 7 bits d’adresses sont : 0111 A2A1A0 -> 0x7.

Le fabricant a laissé libre les 3 bits d’adresses de poids faible (A2 A1 A0) ce qui permettra de relier 2^3 = 8 circuits sur un même bus.

Annexe n°1 : le script run.sh

Le script run.sh permet de flasher le programme sur la carte :

$ vim run.sh
#!/bin/bash

JLINK=JLinkExe
DEVICE=AT91SAM7L128
SPEED=5000
FORMAT="data"

if [ $# -eq 1 ]
then
   if !(test -f bin/$1)
   then
      echo "Erreur fichier $1"
   else
      if [ ! -x "`which $JLINK 2>&-`" ]
      then
         echo "Erreur $JLINK absent"
      else
         file "bin/$1" | grep -i "$FORMAT" > /dev/null 2>&1
         if [ ${?} -eq "0" ]
         then
            $JLINK -if JTAG -device $DEVICE -speed auto -jtagconf -1,-1 -autoconnect 1 -CommanderScript jlink.cfg
         else
            echo "Erreur format fichier $1"
         fi
      fi
   fi
else
   echo "Syntaxe : $(basename $0) fichier.bin"
   echo ""
fi

Test :

$ ./run.sh 
Syntaxe : run.sh fichier.bin

$ ./run.sh slcd-twi-at91sam7l-stk-at91sam7l128-flash.bin

Annexe n°2 : le fichier de configuration jlink.cfg

Le fichier de configuration jlink.cfg :

r
h
loadbin ./bin/slcd-twi-at91sam7l-stk-at91sam7l128-flash.bin,0x00100000
r
g
qc

Retour