Primeiros passos com a Stellaris Launchpad

- por Sergio Prado

Categorias: FreeRTOS, Hardware Tags: , , , , ,

A Stellaris Launchpad é uma plataforma de avaliação de baixo custo da Texas Instruments para microcontroladores da linha ARM Cortex-M4F.

A placa contém o microcontrolador LM4F120H5QR, um Cortex-M4 com suporte à ponto flutuante e que roda à 80MHz, com 256K de flash, 32K de RAM, e diversas interfaces de comunicação e controle como UART, SSI, I2C, CAN, USB e ADC.

O kit possui uma interface USB device, dois botões de usuário, um led RGB e um debugger integrado através de uma conexão USB (ICDI – In-Circuit Debug Interface), dispensando o uso de qualquer ferramenta adicional de gravação e debugging.

E seguindo a linha das outras Launchpads, o kit possui dois barramentos de pinos laterais que são compatíveis com as BoosterPacks, placas/módulos adicionais para expandir as funcionalidades da plataforma, como display, RF, controle de motor, áudio, botões touch, etc.

Que tal darmos uma olhada no ambiente de desenvolvimento e escovar alguns bits com esta plaquinha?

AMBIENTE DE DESENVOLVIMENTO

A TI fornece uma versão gratuita do Code Composer Studio para trabalhar com esta Launchpad. É só baixar do site da Texas aqui. Infelizmente ainda não esta disponível a versão para Linux, então todos os testes que fiz foi em uma máquina Windows.

Baixe o pacote e instale o CCS e a StellarisWare, uma biblioteca que a Texas fornece gratuitamente para facilitar a nossa vida (falaremos mais sobre ela daqui a pouco). Na dúvida com relação ao procedimento de instalação, consulte este link da Texas. No meu caso, precisei instalar os drivers da interface de debug manualmente no “Gerenciador de dispositivos” do Windows, apontando para o diretório “Software/ICDI” do pacote de instalação do CCS.

Com os drivers instalados corretamente, ao conectar a placa no PC serão criadas três conexões: uma portal serial (Stellaris Virtual Serial Port) e duas conexões com a interface de debug (Stellaris ICDI JTAG/SWD Interface e Stellaris ICDI DFU Interface).

O PRIMEIRO PROJETO

Abra o CCS e crie um novo projeto conforme abaixo:

  • Acesse o menu “File -> New -> CCS Project“.
  • Digite o nome do projeto em “Project name“.
  • Selecione “Family” como “ARM“, “Variant” como “Cortex M” e escolha “Stellaris LM4F120H5QR“.
  • Em “Connection“, selecione “Stellaris In-circuit Debug Interface“.
  • No tipo de projeto, selecione “Empty Project (with main.c)
  • Clique em “Finish“.

Será criado um projeto para a Stellaris Launchpad com a função main() vazia.

Antes de começar a desenvolver a aplicação, você precisa também incluir o diretório onde se encontra o arquivo de cabeçalho com as definições do microcontrolador:

  • Acesse o menu “Project -> Properties“.
  • Selecione “Build -> Arm Compiler -> Include Options“.
  • Clique no sinal de mais da opção “Add dir to #include search path”, selecione “File System” e inclua o diretório “inc” que se encontra dentro do diretório de instalação da biblioteca StellarisWare.
  • Clique em “OK“.

Vamos começar escrevendo um pisca-led para testar nosso ambiente. O led RGB da placa esta ligado aos pinos 1, 2 e 3 do PORTF da CPU, conforme abaixo:

Led vermelho....PORTF 1
Led azul........PORTF 2
Led verde.......PORTF 3

Na dúvida, você pode consultar o manual da Launchpad clicando aqui.

Este é o nosso código para piscar o led RGB:

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
#include "lm4f120h5qr.h"
 
#define LED_RED     0x2
#define LED_BLUE    0x4
#define LED_GREEN   0x8
#define LEDS_MASK   0xE
 
void delay()
{
    unsigned int i;
 
    for (i = 0; i < 1000000; i++);
}
 
void set_led(int led)
{
    GPIO_PORTF_DATA_R &= ~LEDS_MASK;
    GPIO_PORTF_DATA_R |= led;
}
 
void main(void) 
{
    // enable GPIO clock
    SYSCTL_RCGC2_R = SYSCTL_RCGC2_GPIOF;
 
    // set direction as output
    GPIO_PORTF_DIR_R = LED_RED | LED_BLUE | LED_GREEN;
 
    // enable digital I/O
    GPIO_PORTF_DEN_R = LED_RED | LED_BLUE | LED_GREEN;
 
    // blink RGB led
    for (;;) {
        set_led(LED_RED);
        delay();
 
        set_led(LED_BLUE);
        delay();
 
        set_led(LED_GREEN);
        delay();
    }
}

USANDO A STELLARISWARE

A StellarisWare é um framework de software desenvolvido pela Texas para facilitar e aumentar a produtividade no desenvolvimeno de projetos baseados em microcontroladores da linha Stellaris. Ela contém a implementação de todos os drivers de acesso aos diversos periféricos do microcontrolador, além de um conjunto de bibliotecas gráficas, stack USB completo, funções matemáticas, bootloader, CMSIS, etc.

Vamos então converter nosso projeto para usar a StellarisWare. Para isso, vamos abrir e compilar o projeto da StellarisWare:

  • Acesse o menu “Project -> Import Existing CCS Eclipse Project“.
  • Clique em “Browse” e selecione o diretório “driverlib” dentro do diretório de instalação da StellarisWare.
  • Selecione “driverlib-cm4f“.
  • Clique em “Finish“.

Selecione agora o projeto aberto com o botão direito e clique em “Build“.

O próximo passo é adicionar a biblioteca no seu projeto pisca-led. Para isso, selecione o projeto e execute os procedimentos abaixo:

  • Acesse o menu “Project -> Properties“.
  • Selecione “Build -> ARM Linker -> File Search Path“.
  • Clique em adicionar na opção “Include library file or command file as input“.
  • Clique em “Workspace” e selecione “driverlib-cm4f/Debug/driverlib-cm4f.lib“.
  • Clique em “OK“.

Por último, você precisa adicionar o diretório de includes da StellarisWare:

  • Acesse o menu “Project -> Properties“.
  • Selecione “Build -> Arm Compiler -> Include Options“.
  • Clique no sinal de mais da opção “Add dir to #include search path“, selecione “File System” e inclua o diretório “driverlib” que se encontra dentro do diretório de instalação da biblioteca StellarisWare.
  • Clique em “OK“.

Agora é só reescrever a aplicação usando as funções da biblioteca:

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
#include "hw_gpio.h"
#include "hw_memmap.h"
#include "hw_sysctl.h"
#include "hw_types.h"
#include "gpio.h"
#include "sysctl.h"
 
#define LED_RED     GPIO_PIN_1
#define LED_BLUE    GPIO_PIN_2
#define LED_GREEN   GPIO_PIN_3
#define LEDS_MASK   (LED_RED|LED_BLUE|LED_GREEN)
 
void delay()
{
    SysCtlDelay(4000000);
}
 
void set_led(int led)
{
    GPIOPinWrite(GPIO_PORTF_BASE, LEDS_MASK, led);
}
 
void main(void)
{
    // system clock running at 50 MHz
    SysCtlClockSet(SYSCTL_SYSDIV_4|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ|SYSCTL_OSC_MAIN);
 
    // enable PORTF as GPIO
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
 
    // set direction as output
    GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, LED_RED|LED_BLUE|LED_GREEN);
 
    // blink RGB led
    for (;;) {
        set_led(LED_RED);
        delay();
 
        set_led(LED_BLUE);
        delay();
 
        set_led(LED_GREEN);
        delay();
    }
}

STELLARIS LAUNCHPAD COM O FREERTOS

Nosso último teste será com o FreeRTOS, e aqui não teremos nenhum trabalho. A StellarisWare já provê uma aplicação de demonstração completa para trabalhar com o FreeRTOS. Basta importar o projeto disponível no diretório da biblioteca em “boards\ek-lm4f120xl\freertos_demo“.

Esta aplicação de demonstração pisca o led RGB em uma determinada frequência. O botão SW1 é usado para selecionar a cor do led que será piscado e o botão SW2 é usado para selecionar a frequência. Para isso, duas tarefas são criadas, uma para gerenciar o led e outra para gerenciar o botão:

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
unsigned long LEDTaskInit(void)
{
    ...
 
    if(xTaskCreate(LEDTask, (signed portCHAR *)"LED", LEDTASKSTACKSIZE, NULL,
                   tskIDLE_PRIORITY + PRIORITY_LED_TASK, NULL) != pdTRUE)
    {
        return(1);
    }
 
    ...
}
 
unsigned long SwitchTaskInit(void)
{
    ...
 
    if(xTaskCreate(SwitchTask, (signed portCHAR *)"Switch",
                   SWITCHTASKSTACKSIZE, NULL, tskIDLE_PRIORITY +
                   PRIORITY_SWITCH_TASK, NULL) != pdTRUE)
    {
        return(1);
    }
 
    ...
}

A tarefa de botão faz polling nos botões a cada 25ms, e usa um queue para enviar uma mensagem para a tarefa de led quando um botão for pressionado:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
static void SwitchTask(void *pvParameters)
{
    ...
 
    while(1)
    {
        ucCurButtonState = ButtonsPoll(0, 0);
 
        if(ucCurButtonState != ucPrevButtonState)
        {
            ...
 
            xQueueSend(g_pLEDQueue, &ucMessage, portMAX_DELAY);
 
            ...
        }
 
        vTaskDelayUntil(&ulLastTime, ulSwitchDelay / portTICK_RATE_MS);
    }
}

E a tarefa de led verifica se recebeu uma mensagem da tarefa de botão para alterar os parâmetros de led e frequência, e pisca o led selecionado na frequência configurada:

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
static void LEDTask(void *pvParameters)
{
    ...
 
    while(1)
    {
        if(xQueueReceive(g_pLEDQueue, &cMessage, 0) == pdPASS)
        {
            if(cMessage == LEFT_BUTTON)
            {
               // change led color
               ... 
            }
 
            if(cMessage == RIGHT_BUTTON)
            {
                // change led frequency
                ...
            }
        }
 
        RGBEnable();
        vTaskDelayUntil(&ulWakeTime, ulLEDToggleDelay / portTICK_RATE_MS);
 
        RGBDisable();
        vTaskDelayUntil(&ulWakeTime, ulLEDToggleDelay / portTICK_RATE_MS);
    }
}

Para notificar os eventos (tarefas criadas, botão pressionado, mudanças da cor do led, mudança da frequência, etc), uma mensagem é enviada à porta serial, que deve estar configurada como 115200,8n1. Para gerenciar o acesso à este recurso compartilhado, as duas tarefas usam um semáforo:

1
2
3
4
5
6
7
    ...
 
    xSemaphoreTake(g_pUARTSemaphore, portMAX_DELAY);
    UARTprintf("Led blinking frequency is %d ms.\n", (ulLEDToggleDelay * 2));
    xSemaphoreGive(g_pUARTSemaphore);
 
    ...

Pelo baixíssimo custo e pela capacidade de processamento e memória, este kit pode ser a porta de entrada para quem esta migrando de 8 para 32 bits, onde as aplicações são mais complexas, envolvendo stacks TCP/IP, USB, bibliotecas gráficas e integração com RTOS.

O kit vem com a placa e um cabo micro USB, e custa no momento $12.99 no site da Texas. Isso significa que você irá pagar em torno de R$26,00, já que a Texas cobre os custos com frete e impostos. É um preço fantástico para um kit com ARM Cortex-M4F. Agora não tem desculpa para não aprender a trabalhar com ARM, não é verdade? :)

Para comprar este brinquedinho, acesse a loja online da Texas clicando aqui.

Happy Hacking!

Sergio Prado

Navegue
Creative Commons Este trabalho de Sergio Prado é licenciado pelo
Creative Commons BY-NC-SA 3.0.