LUFA Library  151115
Writing LUFA Board Drivers

LUFA ships with several basic pre-made board drivers, to control hardware present on the supported board hardware - such as Dataflash ICs, LEDs, Joysticks, or other hardware peripherals. When compiling an application which makes use of one or more board drivers located in LUFA/Drivers/Board, you must also indicate which board hardware you are using in your project makefile. This is done by defining the BOARD macro using the -D switch passed to the compiler, with a constant of BOARD_{Name}. For example, -DBOARD=BOARD_USBKEY instructs the compiler to use the USBKEY board hardware drivers.

If your application does not use any board level drivers, you can omit the definition of the BOARD macro. However, some users may wish to write their own custom board hardware drivers which are to remain compatible with the LUFA hardware API. To do this, the BOARD macro should be defined to the value BOARD_USER. This indicates that the board level drivers should be located in a folder named "Board" located inside the application's folder.

When used, the driver stub files located in the LUFA/CodeTemplates/DriverStubs folder should be copied to the user application's Board/ directory, and filled out to include the values and code needed to control the custom board hardware. Once done, the existing LUFA board level APIs (accessed in the regular LUFA/Drivers/Board/ folder) will redirect to the user board drivers, maintaining code compatibility and allowing for a different board to be selected through the project makefile with no code changes.

Board Driver Templates

The templates for each board driver are reproduced below.

Template for USER <Board/Board.h>

/*
LUFA Library
Copyright (C) Dean Camera, 2015.
dean [at] fourwalledcubicle [dot] com
www.lufa-lib.org
*/
/*
Copyright 2015 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
The author disclaims all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
*/
#ifndef __BOARD_USER_H__
#define __BOARD_USER_H__
/* Includes: */
// TODO: Add any required includes here
/* Enable C linkage for C++ Compilers: */
#if defined(__cplusplus)
extern "C" {
#endif
/* Preprocessor Checks: */
#if !defined(__INCLUDE_FROM_BOARD_H)
#error Do not include this file directly. Include LUFA/Drivers/Board/Board.h instead.
#endif
/* Public Interface - May be used in end-application: */
/* Macros: */
// #define BOARD_HAS_BUTTONS
// #define BOARD_HAS_DATAFLASH
// #define BOARD_HAS_JOYSTICK
// #define BOARD_HAS_LEDS
/* Disable C linkage for C++ Compilers: */
#if defined(__cplusplus)
}
#endif
#endif

Template for USER <Board/Buttons.h>

/*
LUFA Library
Copyright (C) Dean Camera, 2015.
dean [at] fourwalledcubicle [dot] com
www.lufa-lib.org
*/
/*
Copyright 2015 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
The author disclaims all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
*/
#ifndef __BUTTONS_USER_H__
#define __BUTTONS_USER_H__
/* Includes: */
// TODO: Add any required includes here
/* Enable C linkage for C++ Compilers: */
#if defined(__cplusplus)
extern "C" {
#endif
/* Preprocessor Checks: */
#if !defined(__INCLUDE_FROM_BUTTONS_H)
#error Do not include this file directly. Include LUFA/Drivers/Board/Buttons.h instead.
#endif
/* Public Interface - May be used in end-application: */
/* Macros: */
#define BUTTONS_BUTTON1 // TODO: Add mask for first board button here
/* Inline Functions: */
#if !defined(__DOXYGEN__)
static inline void Buttons_Init(void)
{
// TODO: Initialize the appropriate port pins as an inputs here, with pull-ups
}
static inline void Buttons_Disable(void)
{
// TODO: Clear the appropriate port pins as high impedance inputs here
}
static inline uint8_t Buttons_GetStatus(void) ATTR_WARN_UNUSED_RESULT;
static inline uint8_t Buttons_GetStatus(void)
{
// TODO: Return current button status here, debounced if required
}
#endif
/* Disable C linkage for C++ Compilers: */
#if defined(__cplusplus)
}
#endif
#endif

Template for USER <Board/Dataflash.h>

/*
LUFA Library
Copyright (C) Dean Camera, 2015.
dean [at] fourwalledcubicle [dot] com
www.lufa-lib.org
*/
/*
Copyright 2015 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
The author disclaims all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
*/
#ifndef __DATAFLASH_USER_H__
#define __DATAFLASH_USER_H__
/* Includes: */
// TODO: Add any required includes here
/* Preprocessor Checks: */
#if !defined(__INCLUDE_FROM_DATAFLASH_H)
#error Do not include this file directly. Include LUFA/Drivers/Board/Dataflash.h instead.
#endif
/* Private Interface - For use in library only: */
#if !defined(__DOXYGEN__)
/* Macros: */
#define DATAFLASH_CHIPCS_MASK // TODO: Replace this with a mask of all the /CS pins of all Dataflashes
#define DATAFLASH_CHIPCS_DDR // TODO: Replace with the DDR register name for the board's Dataflash ICs
#define DATAFLASH_CHIPCS_PORT // TODO: Replace with the PORT register name for the board's Dataflash ICs
#endif
/* Public Interface - May be used in end-application: */
/* Macros: */
#define DATAFLASH_TOTALCHIPS 1 // TODO: Replace with the number of Dataflashes on the board, max 2
#define DATAFLASH_NO_CHIP 0
#define DATAFLASH_CHIP1 // TODO: Replace with mask with the pin attached to the first Dataflash /CS set
#define DATAFLASH_CHIP2 // TODO: Replace with mask with the pin attached to the second Dataflash /CS set
#define DATAFLASH_PAGE_SIZE // TODO: Replace with the page size for the Dataflash ICs
#define DATAFLASH_PAGES // TODO: Replace with the total number of pages inside one of the Dataflash ICs
/* Inline Functions: */
#if !defined(__DOXYGEN__)
static inline void Dataflash_Init(void)
{
DATAFLASH_CHIPCS_DDR |= DATAFLASH_CHIPCS_MASK;
DATAFLASH_CHIPCS_PORT |= DATAFLASH_CHIPCS_MASK;
}
static inline uint8_t Dataflash_TransferByte(const uint8_t Byte) ATTR_ALWAYS_INLINE;
static inline uint8_t Dataflash_TransferByte(const uint8_t Byte)
{
// TODO
}
static inline void Dataflash_SendByte(const uint8_t Byte) ATTR_ALWAYS_INLINE;
static inline void Dataflash_SendByte(const uint8_t Byte)
{
// TODO
}
static inline uint8_t Dataflash_ReceiveByte(void) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT;
static inline uint8_t Dataflash_ReceiveByte(void)
{
// TODO
}
static inline uint8_t Dataflash_GetSelectedChip(void) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT;
static inline uint8_t Dataflash_GetSelectedChip(void)
{
return (~DATAFLASH_CHIPCS_PORT & DATAFLASH_CHIPCS_MASK);
}
static inline void Dataflash_SelectChip(const uint8_t ChipMask) ATTR_ALWAYS_INLINE;
static inline void Dataflash_SelectChip(const uint8_t ChipMask)
{
DATAFLASH_CHIPCS_PORT = ((DATAFLASH_CHIPCS_PORT | DATAFLASH_CHIPCS_MASK) & ~ChipMask);
}
static inline void Dataflash_DeselectChip(void) ATTR_ALWAYS_INLINE;
static inline void Dataflash_DeselectChip(void)
{
}
static inline void Dataflash_SelectChipFromPage(const uint16_t PageAddress)
{
if (PageAddress >= (DATAFLASH_PAGES * DATAFLASH_TOTALCHIPS))
return;
#if (DATAFLASH_TOTALCHIPS == 2)
if (PageAddress & 0x01)
else
#else
#endif
}
static inline void Dataflash_ToggleSelectedChipCS(void)
{
uint8_t SelectedChipMask = Dataflash_GetSelectedChip();
Dataflash_SelectChip(SelectedChipMask);
}
static inline void Dataflash_WaitWhileBusy(void)
{
}
static inline void Dataflash_SendAddressBytes(uint16_t PageAddress,
const uint16_t BufferByte)
{
#if (DATAFLASH_TOTALCHIPS == 2)
PageAddress >>= 1;
#endif
Dataflash_SendByte(PageAddress >> 5);
Dataflash_SendByte((PageAddress << 3) | (BufferByte >> 8));
Dataflash_SendByte(BufferByte);
}
#endif
#endif

Template for USER <Board/Joystick.h>

/*
LUFA Library
Copyright (C) Dean Camera, 2015.
dean [at] fourwalledcubicle [dot] com
www.lufa-lib.org
*/
/*
Copyright 2015 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
The author disclaims all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
*/
#ifndef __JOYSTICK_USER_H__
#define __JOYSTICK_USER_H__
/* Includes: */
// TODO: Add any required includes here
/* Enable C linkage for C++ Compilers: */
#if defined(__cplusplus)
extern "C" {
#endif
/* Preprocessor Checks: */
#if !defined(__INCLUDE_FROM_JOYSTICK_H)
#error Do not include this file directly. Include LUFA/Drivers/Board/Joystick.h instead.
#endif
/* Public Interface - May be used in end-application: */
/* Macros: */
#define JOY_LEFT // TODO: Add mask to indicate joystick left position here
#define JOY_RIGHT // TODO: Add mask to indicate joystick right position here
#define JOY_UP // TODO: Add mask to indicate joystick up position here
#define JOY_DOWN // TODO: Add mask to indicate joystick down position here
#define JOY_PRESS // TODO: Add mask to indicate joystick pressed position here
/* Inline Functions: */
#if !defined(__DOXYGEN__)
static inline void Joystick_Init(void)
{
// TODO: Initialize joystick port pins as inputs with pull-ups
}
static inline void Joystick_Disable(void)
{
// TODO: Clear the joystick pins as high impedance inputs here
}
static inline uint8_t Joystick_GetStatus(void) ATTR_WARN_UNUSED_RESULT;
static inline uint8_t Joystick_GetStatus(void)
{
// TODO: Return current joystick position data which can be obtained by masking against the JOY_* macros
}
#endif
/* Disable C linkage for C++ Compilers: */
#if defined(__cplusplus)
}
#endif
#endif

Template for USER <Board/LEDs.h>

/*
LUFA Library
Copyright (C) Dean Camera, 2015.
dean [at] fourwalledcubicle [dot] com
www.lufa-lib.org
*/
/*
Copyright 2015 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
The author disclaims all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
*/
#ifndef __LEDS_USER_H__
#define __LEDS_USER_H__
/* Includes: */
// TODO: Add any required includes here
/* Enable C linkage for C++ Compilers: */
#if defined(__cplusplus)
extern "C" {
#endif
/* Preprocessor Checks: */
#if !defined(__INCLUDE_FROM_LEDS_H)
#error Do not include this file directly. Include LUFA/Drivers/Board/LEDS.h instead.
#endif
/* Public Interface - May be used in end-application: */
/* Macros: */
#define LEDS_LED1 // TODO: Add mask for first board LED here
#define LEDS_LED2 // TODO: Add mask for second board LED here
#define LEDS_LED3 // TODO: Add mask for third board LED here
#define LEDS_LED4 // TODO: Add mask for fourth board LED here
#define LEDS_ALL_LEDS (LEDS_LED1 | LEDS_LED2 | LEDS_LED3 | LEDS_LED4)
#define LEDS_NO_LEDS 0
/* Inline Functions: */
#if !defined(__DOXYGEN__)
static inline void LEDs_Init(void)
{
// TODO: Add code to initialize LED port pins as outputs here
}
static inline void LEDs_Disable(void)
{
// TODO: Clear the LED port pins as high impedance inputs here
}
static inline void LEDs_TurnOnLEDs(const uint8_t LEDMask)
{
// TODO: Add code to turn on LEDs given in the LEDMask mask here, leave others as-is
}
static inline void LEDs_TurnOffLEDs(const uint8_t LEDMask)
{
// TODO: Add code to turn off LEDs given in the LEDMask mask here, leave others as-is
}
static inline void LEDs_SetAllLEDs(const uint8_t LEDMask)
{
// TODO: Add code to turn on only LEDs given in the LEDMask mask here, all others off
}
static inline void LEDs_ChangeLEDs(const uint8_t LEDMask, const uint8_t ActiveMask)
{
// TODO: Add code to set the Leds in the given LEDMask to the status given in ActiveMask here
}
static inline void LEDs_ToggleLEDs(const uint8_t LEDMask)
{
// TODO: Add code to toggle the Leds in the given LEDMask, ignoring all others
}
static inline uint8_t LEDs_GetLEDs(void) ATTR_WARN_UNUSED_RESULT;
static inline uint8_t LEDs_GetLEDs(void)
{
// TODO: Add code to return the current LEDs status' here which can be masked against LED_LED* macros
}
#endif
/* Disable C linkage for C++ Compilers: */
#if defined(__cplusplus)
}
#endif
#endif