Codebase für LPC1xxx

Aus der Mikrocontroller.net Artikelsammlung, mit Beiträgen verschiedener Autoren (siehe Versionsgeschichte)
Wechseln zu: Navigation, Suche

Codebase für LPC11xx und LPC13xx

Für die Cortex-M0 und -M3 Familien existieren verschiedene Basispakete die als Startausstattung sehr gut geeignet sind. Auf microbuilder.eu findet man eine sehr interessante Version inklusive Dokumentation.

Neben weiteren, interessanten Infos findet man dort eine Beta-Version 0.8 für den LPC1114 vom 14. April 2012 (auch wenn dort 2011 steht!) und eine Beta-Version 1.1.1 für den LPC1343 vom 14. April 2012.

(Achtung: die aktuellste Version findet sich immer unter dem dort auch gezeigten "github"-Link)

Die Original-Dokumentation kann auf der rechten Seite unter "Code Base/Documentation" angewählt werden.

Natürlich können die Funktionen die unter LPC1343 gesammelt werden auch für z.B. den LPC1313 eingesetzt werden, jedoch könnte das Ergebnis beim ansprechen von eigentlich nicht vorhandener Peripherie unvorhersehbar sein.

Der hier folgende Text ist zum gegenwärtigen Zeitpunkt (Januar 2012) im Wesentlichen eine Übersetzung der Seite von microbilder.eu

Allgemeine Informationen zum Aufbau der Code Base

Der Aufbau der Dateien wird am Beispiel für den weiter fortgeschrittenen Stand zur LPC13xx Familie beschrieben, sollte aber weitgehend auch für den LPC1114 anwendbar sein. Die Beispiele der Code-Base beziehen sich auf ein Referenzboard von "microbuilder.eu" das hier verfügbar ist.

Download des im Folgenden beschriebenen Code-Packages als github-Zip hier... immer als aktuellste Version

Ziel ist, auf dem aktuellen Stand aufzusetzen, bereits vorhandene Grundfunktionen zu erweitern und neue hinzuzufügen, Mitarbeit ist herzlich willkommen.


Lizenz

Der Author, microBuilder SARL, hat seine Libs unter eine "modifizierte BSD-Lizenz gestellt", die Nutzung und Modifikation erlaubt, sofern der in jedem File enthaltene Paragraph zur Lizenzbeschreibung erhalten bleibt. Details sind aus jedem beliebigen File der Code Base zu entnehmen.

Unterstütze Peripherieeinheiten

(Stand Januar 2012)

  • CPU (vorerst nur auf 72MHz gesetzt)
  • ADC (Analog zu Digital Konverter)
  • GPIO (Standard Eingänge und Ausgänge)
  • I2C (Generischer I2C Code, interrupt betrieben)
  • PMU (Power Management, Sleep-Modi)
  • PWM (Pulsweiten Modulation)
  • SSP (Generischer SSP/SPI Code)
  • Systick (Verwendung des 24-bit Systick Timers)
  • Timer16 (Die 16-bit Timer)
  • Timer32 (Die 32-bit Timer)
  • UART (UART code, interrupt betrieben)
  • USBCDC (USB / Serial Port Emulation)
  • USBHID-ROM (ROM-based USB HID)
  • WDT (Watchdog Timer)



Enthaltene Treiber für externe HW

(Stand Januar 2012)

  • EEPROM/AT25040 (SPI EEPROM)
  • EEPROM/MCP24AA (I2C EEPROM)
  • SENSORS/LM75B (I2C Temp Sensor)
  • CHIBI - Ein einfacher, Open Source Wireless Stack von Freaklabs für Sensorknoten. In diesem Beispiel für den AT86RF212 Transceiver (868MHz) konfiguriert.
  • FATFS - Eine Portierung von Chan's FATFS das bereits FAT32, und einen einfachen MMC Treiber zum lesen von SDHC Karten beinhaltet
  • ILI9325 - Treiber für einen auf ILI9325/ILI9328 Controller (8-bit Interface erforderlich) basierten 240x320 TFT LCD.
  • ST7565 - Treiber für ein 128x64 pixel Bitmap Display
  • SSD1306 - Treiber für ein 128x64 OLED Display (bit-banged SPI mode)
  • TCS3414 - TAOS RGB Sensor
  • ISL12022M - Temperaturkompensierter RTC
  • TSL2561 - TAOS Beleuchtungssensor
  • PN532 - 13.56MHz RFID/NFC Transceiver (im moment mit serh limitierter Funktionalität)
  • STEPPER - Basis Treiber für einen Bipolar Schrittmotor mit L293D oder SN754410N

Struktur der Code Base

oder "wo finde ich was"

Die LPC1343 Code Base hat - nach einiger Gewöhnungszeit - einen recht einfachen Aufbau:

  • Alle bauteilespezifischen Informationen incl. der internen Peripherie befinden sich im Verzeichnis "core".
  • Treiber für externe HW ist im Verzeichnis "drivers" zusammengefaßt.
  • Die Files zur Projekt- und Systemkonfiguration befinden sich im Root-Verzeichnis.
  • Projektfiles für CodeLite (kostenlos) und Rowley Associates Crossworks (kommerziell) stehen im "build" Verzeichnis, und obwohl beide IDEs den gleichen Code verwenden können benutzen sie zum Compilieren nicht die gleiche Toolchain. "Crossworks for Arm" nutze eine eigene GCC Toolchain und einen eigenen Startup Code aber nicht das Makefile im Root-Verzeichnis. Mit CodeLite kann man auch ohne entsprechende Investitionen in HW und SW schon recht angenehm arbeiten

LPC134x.h

Um den Umgang mit der Code Base so einfach wie möglich zu machen wurde ein neues Header-File erzeugt. Obwohl bereits diverse Header-Files für den LPC1343 existieren war der Wunsch die sogenannten "magic-numbers" im Code zu eliminieren. Daher wurde ein "eigenes" erzeugt. Die 134x.h Datei enthält daher für fast jedes Bit das gesetzt oder gelöscht werden kann auch eine entsprechende Definition. Es bedeutet natürlich einen großen Arbeitsaufwand all diese Informationen in ein Header-File zu pakcen, das Resultat ist jedoch ein einfach lesbarer Code, speziell wenn jemand Anderer ihn geschrieben hat.

Was sind diese "Magic Numbers"? Unter "Magic Numbers" versteht man hier den Zugriff auf ein Register ohne "define" also die direkte Angabe einer Zahl in beliebigem Format. Klar, die Eingabe ist kürzer und erzeugt den gleichen Code, aber welche Zeile ist wohl ein halbes Jahr später einfacher zu lesen??

UART_U0LCR = 0x83;

UART_U0LCR = (UART_U0LCR_Word_Length_Select_8Chars |
              UART_U0LCR_Stop_Bit_Select_1Bits |
              UART_U0LCR_Parity_Disabled |
              UART_U0LCR_Break_Control_Disabled |
              UART_U0LCR_Divisor_Latch_Access_Enabled);


projectconfig.h

"projectconfig.h" enthält diverse Aufzählungen die innerhalb eines Projektes benutzt werden wie eine Übersicht über die verwendeten Pins, die CPU_Clock, die Zeit für den System-Tick, Baudraten, SSP, USB, ...


Core Peripherie (core/...)

Alle Funktionen zum initialisieren der internen Peripherie sowie ein kleines Beispiel ist im Verzeichnis "core" enthalten.


External Hardware (drivers/...)

Jeden Code, der mit der externen Hardware irgendwie interagiert findet man im Verzeichnis "drivers".

Core/CPU

Die maximale Taktfrequenz des LPC1343 ist 72MHz. Beim Start-Up ist automatisch die max. Taktfrequenz (72MHz), und ein externer Quarz mit 12MHz eingestellt. (Der LPC13xx enthält auch einen internen 12MHz Oszillator, der aber nicht so genau wie ein externer Quarz sein kann. Für USB ist die Genauigkeit definitiv nicht ausreichend.) Um den Stromverbrauch zu minimieren werden alle Pins auf GPIO und "Eingang" gesetzt. Der interne Pull-Up Widerstand ist dabei immer in "pull up" Modus. Dies bedeutet, daß alle Pins nach dem Start der CPU auf "High" gesetzt sind. Um diese Voreinstellungen zu ändern muß cpuInit entsprechend angepaßt werden.


cpuInit

void cpuInit (void)

Initialisiert die System-Taktfrequenz, auf max. Speed (12MHz x 6 = 72MHz)und benutzt einen externen Quarz als Taktquelle. Dies sollte die erste Funktion sein, die ausgeführt wird, da sich die CPU sonst nicht wie erwartet verhalten wird. Alle Pins sind auf GPIO mit aktiviertem internen Pull-up gesetzt.

Übergabeparameter: Keine

 
#include "core/cpu/cpu.h"

int main(void)
{
  cpuInit();

  // Enter permanent loop
  while(1);
}

cpuGetDeviceID

cpuDeviceID_t cpuGetDeviceID (void)

Liest die CPU-ID aus Übergabeparameter: Keine

Rückgabewert:

cpuDeviceID_LPC1311, cpuDeviceID_LPC1313, cpuDeviceID_LPC1342, cpuDeviceID_LPC1343 oder cpuDeviceID_Unknown

#include "core/cpu/cpu.h"

int main(void)
{
  cpuInit();

  cpuDeviceID_t id = cpuGetDeviceID();

  if (id == cpuDeviceID_LPC1343)
  {
    // Part is either LPC1343FBD48 or LPC1343FHN33
  }

  // Enter permanent loop
  while(1);
}

Core/ADC

Der LPC1343 enthält einen 8-Kanal, 10-Bit Analog/Digital Wandler (ADC), der zwischen 0 und 3,6V messen kann. (Achtung: Vcc - meist 3,3V - nicht überschreiten. Jeder Kanal kann separat, oder alle 8 Kanäle nacheinander im 'Burst' Mode gewandelt werden. Derzeit ist der 'Burst' Mode nicht in SW umgesetzt.


adcInit

void adcInit (void)

Initialisiert den A/D Konverter und konfiguriert die Kanäle 0..3 für 10-Bit. Übergabeparameter: Keine


Siehe Beispiel für adcRead

adcRead

uint32_t adcRead (uint8_t channelNum)

Diese Funktion startet eine AD-Wandlung für einen einzigen Kanal (0..7) und gibt das Ergebnis zurück (0..1023). Übergabeparameter:

   * uint8_t channelNum: Der Kanal [0..7] der abgetastet werden soll


Rückgabewert:

0, wenn ein Überlauf entsteht, ansonsten ein 10-Bit Wert der das Ergebnis der Wandlung enthält.

Warnung: In adcInit werden nur die Kanäle 0..3 als AD-Wandler Input konfiguriert.

 
#include "core/cpu/cpu.h"
#include "core/adc/adc.h"

void main (void)
{
  cpuInit();
  adcInit();

  uint32_t results = 0;  
  while(1)
  {
    // Get A/D conversion results from A/D channel 0
    results = adcRead(0);
  }
}

Core/GPIO

GPIO (General Purpose Input/Output) bezeichnet einen digitalen Ein-/Ausgang (I/O). JederPin kann unabhängig von Anderen beliebig als Eingang oder als Ausgang konfiguriert werden. Zusätzlich kann jeder GPIO Pin am LPC13xx als externer Interrupt Eingang konfiguriert werden. Wenn sich ein Pegel an einem solchen Pin ändert wird. Zusätzlich besitzt jeder GPIO einen internen Widerstand, der sowohl als Pull-up, als Pull-down oder als Repeater konfiguriert werden kann. Dieser interne Widerstand ist auch abschaltbar. Details hierzu bitte im Datenblatt nachschlagen. Dieser Widerstand sorgt nicht nur für eine Verringerung der erforderlichen Bauteile für so ein System, er erhöht außerdem die Flexibilität, erfordert aber auch mehr Sorgfalt bei der Pinkonfiguration


gpioInit

void gpioInit (void)

Initialisiert GPIO und schaltet den GPIO interrupt handler für alle GPIO Ports ein. Übergabeparameter: Keine


Siehe Beispiel für gpioSetValue

gpioSetDir

void gpioSetDir (uint32_t portNum, uint32_t bitPos, gpioDirection_t dir)

Setzt die Richtung (input/output) für einen bestimmten Port Pin. Übergabeparameter:

   * portNum: die gpio Port Nummer [0..3]
   * bitPos: die Bit Position für den gpio pin [0..11]
   * dir: die Pin Richtung (gpioDirection_Input or gpioDirection_Output)


Siehe Beispiel für gpioSetValue

gpioSetValue

void gpioSetValue (uint32_t portNum, uint32_t bitPos, uint32_t bitVal)

Setzt einen Wert für einen bestimmten Port Pin (nur relevant, wenn eder Pin als Ausgang konfiguriert wurde). Übergabeparameter:

   * portNum: die gpio Port Nummer [0..3]
   * bitPos: die Bit Position für den gpio pin [0..11]
   * bitVal: Enthält den neuen Pegen high (1) oder low (0).


#include "core/cpu/cpu.h"
#include "core/gpio/gpio.h"

int main (void)
{
  cpuInit();
  gpioInit();

  // Set GPIO1.8 to output
  gpioSetDir(1, 8, gpioDirection_Output);
  // Disable the internal pullup/down resistor on P1.8
  gpioSetPullup(&IOCON_PIO1_8, gpioPullupMode_Inactive);
  // Set GPIO1.8 high
  gpioSetValue(1, 8, 1);

  while(1);
}

gpioGetValue

uint32_t gpioGetValue (uint32_t portNum, uint32_t bitPos)

Liest einen bestimmten Port Pin aus. Übergabeparameter:

   * portNum: die gpio Port Nummer [0..3]
   * bitPos: die Bit Position für den gpio pin [0..11]


Rückgabewert:

1 wenn der Pin gerade high, oder 0 wenn der Pin gerade low ist. Warnung:

Alle GPIO Pins des LPC1343 haben interne Pull-up/Pull-down widerstände die beliebig konfiguriert werden können. By default, schaltet der LPC1343 nach dem Reset die pull-up Widerstände an den meisten Pins EIN. Hintergrund dieser Vorgehensweise ist, daß der Stromverbrauch geringer ist, wenn die Pins einen definierten Pegel haben, statt zu "floaten". Dies hat jedoch den Nachteil, daß der zurückgelesene Pegel nicht unbedingt mit dem erwarteten Pegen zu tun haben muss.


#include "core/cpu/cpu.h"
#include "core/gpio/gpio.h"

int main (void)
{
  cpuInit();
  gpioInit();

  // Set GPIO1.8 to input
  gpioSetDir(1, 8, gpioDirection_Input);
  // Disable the internal pullup/down resistor on P1.8
  gpioSetPullup (&IOCON_PIO1_8, gpioPullupMode_Inactive);

  uint32_t results = 0;
  while(1)
  {
    // Read the current state of GPIO1.8 (1 = high, 0 = low)
    results = gpioGetValue(1, 8);
  }
}

gpioSetPullup

void gpioSetPullup (volatile uint32_t *ioconReg, gpioPullupMode_t mode)

Alle GPIO Pins des LPC1343 haben interne Pull-up/Pull-down widerstände die beliebig konfiguriert werden können. Diese Funktion kann dazu verwendet werden den Betriebsmodus der integrierten Widerstände auszufählen (inactive, pull-up, pull-down, or repeater) Übergabeparameter:

  • *ioconReg: Pointer auf das IOCON Register um den Pin zu wählen (zB. 'IOCON_PIO1_8' für GPIO 1.8, 'IOCON_PIO2_2' für GPIO 2.2, etc.). Achtung: Da dies ein Pointer ist, muß die Adresse (und nicht der Wert) des Registers übergeben werden. Dies wird erreicht in dem ein '&' vor das entsprechende IOCON Register gesetzt wird, z.B.: 'gpioSetPullup(&IOCON_PIO2_2, gpioPullupMode_Inactive);'.
 * mode: Betriebsmodus des internen Widerstandes (gpioPullupMode_Inactive, gpioPullupMode_PullDown, gpioPullupMode_PullUp or gpioPullupMode_Repeater).


Warnung: Der LPC13xx setzt den Pull-up Widerstand direkt nach dem Reset automatisch. , Um Schwierigkeiten zu vermeiden wird empfohlen alle Pins immer explizit zu definieren.


#include "core/cpu/cpu.h"
#include "core/gpio/gpio.h"

int main (void)
{
  cpuInit();
  gpioInit();

  // Set GPIO1.8, 1.9, 1.10 and 1.11 to input
  gpioSetDir(1, 8, gpioDirection_Input);
  gpioSetDir(1, 9, gpioDirection_Input);
  gpioSetDir(1, 10, gpioDirection_Input);
  gpioSetDir(1, 11, gpioDirection_Input);

  // Enable the pull-down resistor on P1.8
  gpioSetPullup (&IOCON_PIO1_8, gpioPullupMode_PullDown);
  // Enable the pull-up resistor on P1.9
  gpioSetPullup (&IOCON_PIO1_9, gpioPullupMode_PullUp);
  // Disable the internal resistor resistor on P1.10
  gpioSetPullup (&IOCON_PIO1_10, gpioPullupMode_Inactive);
  // Set P1.11 to 'Repeater' (remembers the last state explicitly set)
  gpioSetPullup (&IOCON_PIO1_11, gpioPullupMode_Repeater);

  while(1);
}

gpioSetInterrupt

void gpioSetInterrupt (uint32_t portNum, uint32_t bitPos, gpioInterruptSense_t sense, gpioInterruptEdge_t edge, gpioInterruptEvent_t event)

Jeder GPIO Pin des LPC1343 kann als externe Interrupt Quelle definiert werden. Die Funktion gpioSetInterrupt erlaubt die Festlegung, welcher Pin als Interruptquelle fungieren soll, und spezifiziert die Randbedingungen, unter denen ein Interrupt ausgelöst wird(Pin geht von H==>L oder von L==>H, ...). Abhängig von der portNum, wird der Interrupt durch den PIOINTx_IRQHandler gehandhabt , wobei 'x' der Portnummer entspricht (PIOINT1_IRQHandler wird benutzt wenn der Interrupt z.B. an GPIO Pin 1.8, ausgelöst wird). Übergabeparameter:

   * portNum: die gpio Port Nummer [0..3]
   * bitPos: die Bit Position für den gpio pin [0..11]
   * sense: Flanken, oder Level-sensitive(gpioInterruptSense_Edge oder gpioInterruptSense_Level).
   * edge: bei Flanke: Flanken-sensitive als Einfache Flanke (gpioInterruptEdge_Single) oder beide Flanken (gpioInterruptEdge_Double).
   * event: bei Level:, High oder Low Level (gpioInterruptEvent_ActiveHigh) (gpioInterruptEvent_ActiveLow). 


#include "core/cpu/cpu.h"
#include "core/gpio/gpio.h"

int main (void)
{
    cpuInit();
    gpioInit();

    // Set GPIO1.8 to input
    gpioSetDir(1, 8, gpioDirection_Input);
    // Disable the internal pullup/down resistor on P1.8
    gpioSetPullup (&IOCON_PIO1_8, gpioPullupMode_Inactive);
    // Setup an interrupt on GPIO1.8
    gpioSetInterrupt(1,                               // Port
                     8,                               // Pin
                     gpioInterruptSense_Edge,         // Edge Sensitive
                     gpioInterruptEdge_Single,        // Single Edge
                     gpioInterruptEvent_ActiveHigh);  // Active High
    // Enable the interrupt
    gpioIntEnable(1, 8);

    while (1);
}

gpioIntEnable

void gpioIntEnable (uint32_t portNum, uint32_t bitPos)

Erlaubt einen Interrupt am spezifizierten GPIO-Pin. Übergabeparameter:

   * portNum: die gpio Port Nummer [0..3]
   * bitPos: die Bit Position für den gpio pin [0..11]


Siehe Beispiel für gpioSetInterrupt.


gpioIntDisable

void gpioIntDisable (uint32_t portNum, uint32_t bitPos)

Schaltet einen Interrupt am spezifizierten GPIO-Pin aus. Übergabeparameter:

   * portNum: die gpio Port Nummer [0..3]
   * bitPos: die Bit Position für den gpio pin [0..11]


Siehe Beispiel für gpioSetInterrupt.

gpioIntClear

void gpioIntClear (uint32_t portNum, uint32_t bitPos)

Löscht den Interrupt am spezifizierten Pin. Diese Funktion sollte nur aus der Interrupt-Service Routine aufgerufen werden, wenn der Interrupt aufgetreten ist. Übergabeparameter:

   * portNum: die gpio Port Nummer [0..3]
   * bitPos: die Bit Position für den gpio pin [0..11]
// IRQ Handler for GPIO Port 1
void PIOINT1_IRQHandler(void)
{
  uint32_t regVal;

  // Check if pin 1.8 raised the interrupt  
  regVal = gpioIntStatus(1, 8);
  if (regVal)
  {
    // Do Something
    ...
    // Clear the interrupt
    gpioIntClear(1, 8);
  }		
  return;
}

Siehe Beispiel für for gpioSetInterrupt to configure an interrupt.

gpioIntStatus

uint32_t gpioIntStatus (uint32_t portNum, uint32_t bitPos)

Liest den Interrupt Status des spezifizierten Port-Pins. Übergabeparameter:

   * portNum: die gpio Port Nummer [0..3]
   * bitPos: die Bit Position für den gpio pin [0..11]


Rückgabewert:

'1' wenn ein Interrupt an diesem Pin aufgetreten ist ansonsten '0'.

Siehe Beispiel für gpioIntClear.

Core/PMU

Konfiguriert die Power Management Unit (PMU) um den Sleep, Deep-sleep und Power-Down Modus. Jeder GPIO Pin kann so konfiguriert werden, um den Prozessor aus dem Sleep Mode aufzuwecken, aber nur ein low-level an Pin 1.4 (WAKEUP) kann den LPC aus dem Power-Down aufwecken.


pmuInit

void pmuInit(void)

Initialisiert die Power Management Unit und Konfiguriert Pin 0.1 so, da er als Wakeup-Quelle für Sleep oder Deep-Sleep Mode fungieren kann. Übergabeparameter: Keine


Notes Jeder GPIO Pin kann so konfiguriert werden, um den Prozessor aus dem Sleep Mode -- ausgelöst durch pmuSleep oder pmuDeepSleep-- aufzuwecken, aber nur ein low-level an Pin 1.4 (WAKEUP) kann den LPC aus dem Power-Down -- ausgelöst durch pmuPowerDown -- aufwecken.

Im oment ist nur P0.1 als Wakeup Quelle konfiguriert, aber in pmuSleep besteht die Möglichkeit durch auskommentieren beliebige, andere Pins zu wählen, sofern auch die entsprechende GPIO Konfiguration passend gesetzt ist.

Siehe Beispiel für pmuSleep, pmuDeepSleep and pmuPowerDown.


pmuSleep

void pmuSleep(void)

Diese Function versetzt den LPC in den Sleep Mode. Jeder GPIO-Pin kann verwendet werden um den LPC wieder aufzuwecken, der Pin muß entsprechend in pmuInit konfiguriert werden. Übergabeparameter: Keine


#include "core/cpu/cpu.h"
#include "core/pmu/pmu.h"

int main(void)
{
    cpuInit();

    // Configure wakeup sources before going into sleep/deep-sleep.
    // By default, pin 0.1 is configured as wakeup source (falling edge)
    pmuInit();

    // Enter sleep mode
    pmuSleep();

    while(1)
    {
        // Wait for an interrupt to wake the device up
    }
}

pmuDeepSleep

void pmuDeepSleep( uint32_t sleepCtrl, uint32_t wakeupSeconds )

Diese Function versetzt den LPC in den Deep-Sleep Mode. AJeder GPIO-Pin kann verwendet werden um den LPC wieder aufzuwecken, der Pin muß entsprechend in pmuInit konfiguriert werden. Der sleepCtrl Parameter wird benötigt umd festzulegen welche Peripherieeinheiten in den Sleep-Mode versetzt werden sollen, siehe SCB_PDSLEEPCFG Register für Details). Optional kann ein Wert ungleich null , in wakeupSeconds bereitgestellt werden, der den Prozessor nach der eingestellten Zeit wieder aufweckt. Dabei wird der 32-bit Timer 0 und Pin 0.1 (CT32B0_MAT2) benutzt.

Übergabeparameter:

   * sleepCtrl: hierüber werden die gesetzten Peripherieeinheiten gezielt in Sleep-Mode gesetzt.
   * wakeupSeconds: Ist dieser Wert größer 0 wird der Prozessor automatisch bach dieser Zeit in Sekunden wieder aufgeweckt. 


#include "core/cpu/cpu.h"
#include "core/pmu/pmu.h"

int main(void)
{
    cpuInit();

    uint32_t pmuRegVal;

    // Configure wakeup sources before going into sleep/deep-sleep.
    // By default, pin 0.1 is configured as wakeup source (falling edge)
    pmuInit();

    // Inidicate which peripherals should be disabled in deep-sleep
    pmuRegVal = SCB_PDSLEEPCFG_IRCOUT_PD | 
                SCB_PDSLEEPCFG_IRC_PD | 
                SCB_PDSLEEPCFG_FLASH_PD | 
                SCB_PDSLEEPCFG_USBPLL_PD | 
                SCB_PDSLEEPCFG_SYSPLL_PD | 
                SCB_PDSLEEPCFG_SYSOSC_PD | 
                SCB_PDSLEEPCFG_ADC_PD | 
                SCB_PDSLEEPCFG_BOD_PD;

    // Enter deep sleep mode and wakeup after 10 seconds
    pmuDeepSleep(pmuRegVal, 10);

    while(1)
    {
    }
}

pmuPowerDown

void pmuPowerDown( void )

Diese Function konfiguriert das PMU Control Register so, daß der LPC in den deep power-down mode geht. Achtung: Alle Register außer der vier Register (PMU_GPREG0..3) verlieren ihren Inhalt während der Prozessor im Deep-Power Down Mode ist. die 3,3V dürfen dazu nicht wegfallen Übergabeparameter: Keine


Warnung: Der LPC kann NUR durch einen Low-level an Pin P1.4 (WAKEUP aufgeweckt werden).

#include "core/cpu/cpu.h"
#include "core/pmu/pmu.h"

int main(void)
{
    cpuInit();
    pmuInit();

    // Enter power-down mode
    pmuPowerDown();

    while(1)
    {
        // Device was woken up by WAKEUP pin
    }
}


Core/SSP

Generischer Code für SSP/SPI Kommunikation. Der SSP Block wird als SPI Master Mode initialisiert


sspInit

void sspInit (uint32_t portNum, sspClockPolarity_t polarity, sspClockPhase_t phase)

Initialisiert den SSP Port. By default, SSP wird als SPI frame-format mit 8-bit Data initialisiert. Pin 2.11 wird als serial clock (SCK) verwendet, und SSEL (0.2) ist als GPIO initialisiert, um manuell den SPI Port ein- bzw. Auszuschalten Überlauf und Timeout Interrupts sind beide ein. Übergabeparameter:

   * portNum: Port Number. ( Standardmäßig 0, es sei denn auf einem LPC1313/1.)
   * polarity: Clock High (sspClockPolarity_High) oder Low (sspClockPolarity_Low)als inaktiven Pegel.
   * phase: Bit Start mit steigender Flanke (sspClockPhase_RisingEdge) oder mit fallender Flanke sspClockPhase_FallingEdge) bei Pegelwechsel von SCK.


Notes

sspSelect() und sspDeselect() macros wurden ssp.h definiert, um SSEL kontrollieren zu können, ohne deß der dafür definierte Pin bekannt ist line Siehe Beispiel für sspSend


sspSend

void sspSend (uint32_t portNum, uint8_t *buf, uint32_t length)

Sendet einen Datenblock an den SSP Port Übergabeparameter:

   * portNum: Port Number. ( Standardmäßig 0, es sei denn auf einem LPC1313/1.)
   * *buf: Pointer auf den Datenpuffer
   * length: Block Länge des Datenpuffers


#include "core/cpu/cpu.h"
#include "core/ssp/ssp.h"

#define SSP_FIFOSIZE		8

int main(void)
{
    cpuInit();
    sspInit(0, sspClockPolarity_High, sspClockPhase_RisingEdge);

    uint8_t request[SSP_FIFOSIZE];
    uint8_t response[SSP_FIFOSIZE];

    // Send 0x9C to the slave device and wait for a response

    // Fill request buffer
    request[0] = 0x80 | 0x1C;

    // Enable CS line
    ssp0Select();

    // Send the 'request' data (1 byte)
    sspSend(0, (uint8_t *)&request, 1);

    // Wait for the response (1 byte)
    sspReceive(0, (uint8_t *)&response, 1);

    // Disable CS line
    ssp0Deselect();
}

sspReceive

void sspReceive(uint32_t portNum, uint8_t *buf, uint32_t length)

Empfängt einen Datenblock an den SSP Port Übergabeparameter:

   * portNum: Port Number. ( Standardmäßig 0, es sei denn auf einem LPC1313/1.)
   * *buf: Pointer auf den Datenpuffer
   * length: Block Länge des Datenpuffers


Siehe Beispiel für sspSend


Core/Systick

Steuert den 24-bit 'system tick' Timer, der sowohl als normaler Timer, alsauch als System-Timer für ein real-time Betriebssystem (FreeRTOS, Crossworks CTL, etc.) verwendet werden kann.


systickInit

void systickInit (uint32_t delayMs)

Initialisiert den Systick Timer in Millisekunden (typischer Wert = 10ms). Dies führt alle z.B. 10ms zu einem Systtick Interrupt und dazu, daß eine unsigned 32-Bit Variable mit dem Namen "msTicks" um 1 hochgezählt wird wenn der Interrupt ausgelöst wird. Übergabeparameter:

   * delayMs: Indicates the length of time in millaseconds between each system 'tick'.

Siehe Beispiel für systickDelay.


systickDelay

void systickDelay (uint32_t delayTicks)

Führt zu einem den Prozessor blockierenden Wartezeit von einer spezifizierten Anzahl an Systick Timer Ticks. Die Länge der Pause hängt von der in der systickInit Function definierten Interruptzeit ab. Übergabeparameter:

   * delayTicks: The number of systick ticks to wait.
#include "core/cpu/cpu.h"
#include "core/systick/systick.h"

int main (void)
{
  // Initialise the cpu
  cpuInit();
  // Initialise the systick timer with one tick every 10 millaseconds
  systickInit(10);

  while(1)
  {
    // Wait 15 ticks on the systick timer (meaning 150ms)
    systickDelay(15);
    // Do something ...
  }
}


Core/Timer16

Steuert alle 16-Bit Timers auf dem LPC1343. Achtung: bei 72MHz deckt ein 16-Bit Timer nur eine Zeit von knapp 0.91mS (or 910uS) ab:

1 mS = CFG_CPU_CCLK / 1000

    = 72000000 / 1000
    = 72000 'ticks'

Der Maximalwert eines 16-Bit Timers ist 0xFFFF (65535) also 0.910208ms.


timer16Init

void timer16Init(uint8_t timerNum, uint16_t timerInterval)

Initialisiert einen 16-bit timer mit seiner Interruptzeit. Jedes mal, wenn der Zeiraum abgelaufen ist wird der Timer-Interrupt ausgelöst, und die Zählervariable um eins hochgezählt. (z.B. mit Timer CT16B0, wird der 'timer16_0_counter' Inkrementiert). Übergabeparameter:

   * timerNum: Der 16-Bit Timer der initialisiert werden soll [0..1]
   * timerInterval: Die Anzahl an Takt-'ticks' zwischen den Interrupts [0..65534]


Warnung Vorsicht bei der Konfiguration der Timer, da die Pins mehrfach mit anderer Peripherie gemultiplext werden, je nach Initialisierung.Diese Funktion dient nur der besseren Veranschaulichung und muß unbedingt an die jeweiligen Randbedingungen angepaßt werden.

#include "/core/cpu/cpu.h"
#include "/core/timer16/timer16.h"

// Instantiated in timer16.c
extern volatile uint32_t timer16_0_counter;

int main(void)
{
    cpuInit();

    // Initialise timer0 with a delay of 0xFFFF, which will cause the
    // timer interrupt to fire every 65535 ticks and increment
    // timer16_0_counter by 1
    timer16Init(0, 0xFFFF);

    // Enable the timer
    timer16Enable(0);

    // At this point timer16_0_counter should start incrementing by 1
    // every 65535 ticks

    while(1)
    {
        // If the timer has been fired 10 times, disabled the timer
        if (timer16_0_counter == 10)
        {
            timer16Disable(0);
        }
    }
}

timer16DelayTicks

void timer16DelayTicks(uint8_t timerNum, uint16_t delayInTicks)

Führt zu einer blockierenden Pause für die definierte Anzahl an Takt-ticks. Übergabeparameter:

   * timerNum: Der 16-Bit Timer der initialisiert werden soll [0..1]
   * delayInTicks: Anzahl an Takt ticks die pausiert werden soll [0..65534]


Notes Die genaue Zeitdauer der Pause hängt von der Taktrate des System-Taktes ab.

#include "/core/cpu/cpu.h"
#include "/core/timer16/timer16.h"

int main(void)
{
    cpuInit();

    // Initialise timer 0 ... delay is provided but not used here
    timer16Init(0, 0xFFFF);

    // Enable the timer
    timer16Enable(0);

    while(1)
    {
        // Cause blocking delay for 36000 ticks (0.5mS @ 72MHz)
        // Note: The delay must be 65534 or less (16-bit value)
        timer16DelayTicks(0, 36000);
    }
}

timer16DelayUS

void timer16DelayUS(uint8_t timerNum, uint16_t delayInUS)

Führt zu einer blockierenden Pause für die definierte Anzahl an Mikrosecunden. Übergabeparameter:

   * timerNum: Der betreffende 16-Bit Timer [0..1]
   * delayInUS: Anzahl der Mikrosekonden, die gewartet werden soll


Warnung Die maximale Wartezeit bei 72MHz beträgt 910uS (0xFFFF / 72 = 910), or 0.91ms

#include "/core/cpu/cpu.h"
#include "/core/timer16/timer16.h"

int main(void)
{
    cpuInit();

    // Initialise timer 0 ... delay is provided but not used here
    timer16Init(0, 0xFFFF);

    // Enable the timer
    timer16Enable(0);

    while(1)
    {
        // Cause blocking delay for 500 microseconds (0.5mS)
        timer16DelayUS(0, 500);
    }
}

timer16Enable

void timer16Enable(uint8_t timerNum)

Schaltet den spezifizierten Timer ein (erlaubt die Auslösung der konfigurierten Interrupts) Übergabeparameter:

   * timerNum: Der betreffende 16-Bit Timer [0..1]


Siehe Beispiel für timer16Init void timer16Disable(uint8_t timerNum)

Schaltet den spezifizierten Timer aus (verbietet die Auslösung der konfigurierten Interrupts) Übergabeparameter:

   * timerNum: Der betreffende 16-Bit Timer [0..1]


Siehe Beispiel für timer16Init

timer16Reset

void timer16Reset(uint8_t timerNum)

Setzt den spezifizierten Timer zurück. Übergabeparameter:

   * timerNum: The 16-bit timer to reset [0..1]


Core/Timer32

Steuert alle 32-Bit Timers auf dem LPC1343. Achtung: der 32-bit timers ermöglicht einen deutlich längeren Timerinterrupt als der 16-Bit Timer. z.B.

1 mS = CFG_CPU_CCLK / 1000

    = 72000000 / 1000
    = 72000 'ticks'

Der Maximalwert eines 32-Bit Timers ist, 0xFFFFFFFF (4,294,967,295), gleichbedeutend mit 59652ms (etwas weniger als eine Minute, im Vergleich ~0.91ms mit einem 16 Bit Timer @ 72MHz).

Sowohl die 16-Bit, alsauch die 32-Bit Timer können in verbindung mit einem externen Pin eingesetzt werden. z.B. setzen/löschen eines Pins, wenn ein "Match" eintritt. Jeses Matchregisters jedes Timers kann auch als PWM Register verwendet werden und ein entsprechendes PWM-Verhältnis ausgeben zu können.


timer32Init

void timer32Init(uint8_t timerNum, uint32_t timerInterval)

Initialisiert einen 32-bit timer mit seiner Interruptzeit. Jedes mal, wenn der Zeiraum abgelaufen ist wird der Timer-Interrupt ausgelöst, und die Zählervariable um eins hochgezählt. (z.B. mit Timer CT16B0, wird der 'timer16_0_counter' Inkrementiert). Übergabeparameter:

   * timerNum: Der 32-Bit Timer der initialisiert werden soll [0..1]
   * timerInterval: Die Anzahl an Takt-'ticks' zwischen den Interrupts [0..4,294,967,294]

Warnung: Vorsicht bei der Konfiguration der Timer, da die Pins mehrfach mit anderer Peripherie gemultiplext werden, je nach Initialisierung.Diese Funktion dient nur der besseren Veranschaulichung und muß unbedingt an die jeweiligen Randbedingungen angepaßt werden.

#include "/core/cpu/cpu.h"
#include "/core/timer32/timer32.h"

// Instantiated in timer32.h
extern volatile uint32_t timer32_0_counter;

int main(void)
{
    cpuInit();

    // Initialise timer0 with a delay of 72000, which will cause the
    // timer interrupt to fire every 1mS @ 72MHz and increment
    // timer32_0_counter by 1
    timer32Init(0, 72000);

    // Enable the timer
    timer32Enable(0);

    // At this point timer32_0_counter should start incrementing by 1
    // every 72000 ticks

    while(1)
    {
        // If the timer has been fired 10 times, disabled the timer
        if (timer32_0_counter == 10)
        {
            timer32Disable(0);
        }
    }
}

timer32Delay

void timer32Delay(uint8_t timerNum, uint32_t delay)

Führt zu einer blockierenden Pause für die definierte Anzahl an Takt-ticks. Übergabeparameter:

   * timerNum: Der 16-Bit Timer der initialisiert werden soll [0..1]
   * delayInTicks: Anzahl an Takt ticks die pausiert werden soll 


Notes Die genaue Zeitdauer der Pause hängt von der Taktrate des System-Taktes ab.


Warning Die max. delay-Zeit hängt von 'timerInterval' Wert ab, der bei der Timer initialisierung verwendet wird (siehe timer32Init).

#include "/core/cpu/cpu.h"
#include "/core/timer32/timer32.h"

int main(void)
{
    cpuInit();

    // Initialise timer 0 with 1 millisecond 'ticks'
    timer32Init(0, TIMER32_CCLK_1MS);

    // Enable the timer
    timer32Enable(0);

    while(1)
    {
        // Cause a blocking delay for 1.5 seconds (1500 milliseconds)
        timer32Delay(0, TIMER32_DELAY_1MS * 1500);
    }
}

timer32Enable

void timer32Enable(uint8_t timerNum)

Schaltet den spezifizierten Timer ein (erlaubt die Auslösung der konfigurierten Interrupts) Übergabeparameter:

   * timerNum: Der betreffende 32-Bit Timer [0..1]


Siehe Beispiel für timer32Init

timer32Disable

void timer32Disable(uint8_t timerNum)

Schaltet den spezifizierten Timer aus (verbietet die Auslösung der konfigurierten Interrupts) Übergabeparameter:

   * timerNum: Der betreffende 32-Bit Timer [0..1]


Siehe Beispiel für timer32Init

timer32Reset

void timer32Reset(uint8_t timerNum)

Setzt den spezifizierten Timer zurück. Übergabeparameter:

   * timerNum: Der betreffende 32-Bit Timer [0..1]

Core/UART

Ermöglicht es einfache Teste über RS232, USB oder FTDI232RL zu senden oder zu empfangen. Jeder eingehende Text wird in einem FIFO gespeichert sodaß Datenverlust nicht auftreten sollte.

uart_pcb_t

uart_pcb_t *uartGetPCB ()

Liefert einen Pointer auf den Protokollblock des UART's. Damit kann der Status des UART ermittelt werden, und damit ob der UART initialisiert wurde, ob auf Daten gewartet oder gerade gesendet wird und um eine Referenz auf den Empfangs-FIFO zu erhalten.

Übergabeparameter: Keine

// Make sure that UART is initialised
uart_pcb_t *pcb = uartGetPCB();
if (!pcb->initialised)
{
  uartInit(CFG_UART_BAUDRATE);
}

uartInit

void uartInit (uint32_t baudrate)

Initialisiert den UART mit einer spezifischen Baud-Rate. Übergabeparameter:

   * baudRate: Die Baud-Rate, mit der der UART konfiguriert werden soll (z.B. '57600').
#include "core/cpu/cpu.h"
#include "core/uart/uart.h"

#define UARTBUFFERSIZE 5

int main(void)
{
    cpuInit();
    uartInit(57600);

    uint8_t uartBuffer[UARTBUFFERSIZE] = { 'T', 'e', 's', 't', '\n' };

    while(1)
    {  
        // Constantly send contents of uartBuffer
        uartSend((uint8_t *)uartBuffer, UARTBUFFERSIZE);
    }
}

uartSend

void uartSend (uint8_t *bufferPtr, uint32_t length)

Sendet den Inhalt des Puffers über den UART. Übergabeparameter:

   * *bufferPtr: Pointer zum Text Buffer
   * length: Die Größe des Text Buffers


Siehe Beispiel für uartInit

uartSendByte

void uartSendByte (uint8_t byte)

Schickt ein einzelnes Byte an den UART. Übergabeparameter:

   * byte: Das zu sendende Byte
// Send 0xFF over UART
uartSendByte(0xFF);

// Send 'B' over UART (note single quotes)
uartSendByte('B');

uartRxBufferInit

void uartRxBufferInit ()

Initialisiert den RX FIFO buffer. Übergabeparameter: Keine

No example current available.


uartRxBufferRead

uint8_t uartRxBufferRead ()

Liest ein Byte aus dem RX Buffer. Diese Funktion liefert ein Byte zurück, das durch den Array Index spezifiziert wird. Erreicht der Pointer die max. Buddergröße, beginnt er wieder bei '0'. Übergabeparameter: Keine

Siehe Beispiel für uartRxBufferWrite.

uartRxBufferWrite

void uartRxBufferWrite(uint8_t data)

Schreibt ein Byte in den RX Buffer.

Note: Normalerweise ist es nicht notwendig diese Funktion zu benutzen, da alle eingehenden Daten über den UART Interrupt laufen, und jedes Byte in den RX-Buffer geschrieben wird. Übergabeparameter:

   * uint8_t data: Byte, das in den RX Buffer geschrieben werden soll.
#include "core/cpu/cpu.h"
#include "core/uart/uart.h"

int main(void)
{
    cpuInit();
    uartInit(57600);

    // Add 0xFF to the RX buffer
    uartRxBufferWrite(0xFF);

    // Check if the buffer is empty (it shouldn't be!)
    while (uartRxBufferDataPending())
    {
      // Retrieve the first available character in the buffer
      uint8_t c = uartRxBufferRead();
    }

    ...
}

uartRxBufferClearFIFO

void uartRxBufferClearFIFO ()

Löscht die RX und TX Pointer und setzt die Längen auf Null. Übergabeparameter: Keine

No example currently available.

uartRxBufferDataPending

void uartRxBufferDataPending()

Stellt fest, ob Daten im FIFO sind. Wenn ein odermehr Bytes im FIFO enthalten sind, wird eine '1' zurückgeliefert Ist der Puffer leern wird eine '0' zurückgeliefert. Übergabeparameter: Keine

Siehe das Beispiel für uartRxBufferWrite.

Core/USBHID-ROM

Der LPC1343 enthält eine ROM-basierte Unterstützung für HID (Human Interface Device) und MSCD (Mass Storage Device) was einem eine relativ einfache Möglichkeit liefert USB Klassen schnell und effizient zu implementieren. Eine einfache HID implementierung ist in der Code-Base enthaltenund beinhaltet die Basis-Kommunikation zwischen dem LPC1343 und einem PC or USB-Host Device. In diesem Beispiel wird das Device so konfiguriert, daß "1-Byte! telegramme geschickt werden können. Achtung: dieses Beispiel ist auf das bei microbuilder.eu verfügbare LPC1343 Reference Board abgestimmt.

Dieser ROM-basierte HID Driver macht es wirklich außergewöhnlich bequem, ist aber weniger flexibel als ein vollständig SW-basierter USB/HID Stack. Der Hauptunterschied ist, daß man hier auf einen "single Report" limitiert ist. Ein vollständig SW-basierter Stack ist auf der NXP-Website verfügbar. Ein möglicher Kompromiß zwischen Aufwand und flexibilität ist, daß z.B. immer zwei oder mehre Byte-Reports verschickt werden, wobei das erste Byte als eine adt "Komando-ID" bestimmt, wie die nachfolgenden Bytes interpretiert werden sollen. Speicher-Einschränkung: Der ROM-basierte HID Treiber verwendet 0x10000050 to 0x10000180 des On-Chip RAM, was bedeutet, daß im Linkter entsprechend eingestellt werden muß , daß diese Sektion nicht verwendet werden darf.

usbHIDInit

void usbHIDInit (void)

Initialisiert das Device für USB HID Support und versucht einen Verbindungsaufbau zum Host. Das Device ist als 1 Byte Report konfiguriert.

Übergabeparameter: Keine

#include "core/cpu/cpu.h"
#include "core/usbhid-rom/usbhid.h"
#include "core/gpio/gpio.h"

int main(void)
{
    cpuInit();

    // Set GPIO2.10 (LED) as output
    gpioSetDir(2, 10, gpioDirection_Output);
    // Disable LED (set high)
    gpioSetValue (2, 10, 1);

    // Initialise and connect USB
    usbHIDInit();

    // The device should enumerate on the PC, and
    // the LED on 2.10 can be enabled by sending 0x01

    while (1)
    {
    }
}

usbHIDGetInReport

void usbHIDGetInReport (uint8_t src[], uint32_t length)

Setzt die HID im Report (vom LPC1343 zum USB host). Übergabeparameter:

   * src[]: Ein Byte-Array für die Report Daten
   * length: Länge des src


Warnung The signature for this method (uint8_t src[], uint32_t length) should not be modified, and this method should never be called directly. All interrupts and report exchanges are handled by the rom-based drivers. The only thing that should be modified in these methods is the code inside them that either generates or handles the appropriate byte data. See the example for usbHIDInit

usbHIDSetOutReport

void usbHIDSetOutReport (uint8_t dst[], uint32_t length)

Sezt den HID-out Report (Vom USB-Host zum LPC1343). Übergabeparameter:

   * src[]: Ein Byte-Array für die Report Daten
   * length: Länge des src


Warnung The signature for this method (uint8_t dst[], uint32_t length) should not be modified, and this method should never be called directly. All interrupts and report exchanges are handled by the rom-based drivers. The only thing that should be modified in these methods is the code inside them that either generates or handles the appropriate byte data. See the example for usbHIDInit

Core/WDT

Der LPC1343 enthält einen Watchdog-Timer der benutzt werden kann das Sytem am laufen zu halten. Damit wird festgestellt, ob der LPC abgestürzt ist, oder nicht. Der 'Watchdog' ist so konfiguriert, daß er alle 'x' Ticks des System-Taktes getriggert werden muss. Wenn dies nicht stattfindet, können verschiedene Aktionen ausgelöst werden, (z.B. System-Reset, oder die Auslösung eines Interrupts). Die Grundeinstellung des in der Code-Base vorhandenen Codes setzt den Watchdog auf eine Togglerate von 250kHz, also einmal alle 250.000 Taktzyklen, und hier wird nur der WDT_IRQHandler ausgelöst.


wdtInit

void wdtInit (void)

Initialisiert den Watchdog Timer und den interrupt.

Übergabeparameter: Keine

#include "core/cpu/cpu.h"
#include "core/wdt/wdt.h"

int main(void)
{
    cpuInit();
    wdtInit();

    // Pat the watchdog to start it
    wdtFeed();

    while(1)
    {
        // Keep the watchdog happy by regularly feeding it
        wdtFeed();

        // Any delay here > 250,000 ticks (~3.5mS @ 72MHz)
        // will cause the watchdog to raise an interrupt, which
        // will be handled by WDT_IRQHandler
    }
}


wdtFeed

void wdtFeed (void)

Toggelt den Watchdog um einen Timeout zu verhindern.

Übergabeparameter: Keine


Siehe Beispiel für wdtInit

Links