An dieser Stelle sollen am Beispiel des SAML21 die erforderlichen Portierungen gezeigt werden. Im Verzeichnis „Template“ sind die Konstrukte für die boardspezifischen Anpassungen gegeben. Das sind hier vor allem die Files board.h und hardware_setup.c, wie im Folgenden gezeigt:
board.h
#ifndef _BOARD_H_
#define _BOARD_H_
// Get board and chip defines
#endif /* _BOARD_H_ */
hardware_setup.c
/*********************************************************
(C) 2014 EEMBC(R) and ULPBench(TM). All rights reserved.
EEMBC ULPBench Software is a product of EEMBC and is provided
under the terms of the ULPBench License that is distributed
with the official EEMBC ULPBench Software release.
The Software is the proprietary intellectual property of EEMBC
and its members and is protected under all applicable laws,
including all applicable copyright laws.
If you received this EEMBC ULPBench Software
without the accompanying ULPBench License,
you must discontinue use and download the official release
from http://www.eembc.org/benchmark/ulp_sl.php.
**********************************************************/
//=============================================================================
// Platform.c
//
// Platform-specific declarations
//=============================================================================
//=============================================================================
// board/chip defines
#include „board.h“
#include „TesTPI.h“
#include „CoreProfile.h“
//=============================================================================
void RTC_Start( void )
{
// $$$ Code to init the RTC.
}
void hardware_setup_part1( void )
{
// $$$ init device phase 1 (device specific startup)
RTC_Start();
}
void hardware_setup_part2( void )
{
// $$$ init device phase 2 (device specific, after TES started)
}
//=============================================================================
/*__interrupt*/ void pltTimer_ISR (void)
{
tesTimerInterrupt();
// $$$ Code to finish Sleep mode.
}
Die erforderlichen Einstellungen für einen Atmel SAML21 zeigt die folgende Portierung. Es wird unmittelbar deutlich, dass detaillierte Kenntnisse des jeweiligen Mikrocontrollers auf Registerebene erforderlich sind, um diese Portierungen vornehmen zu können. Die jeweils gewählte Konfiguration beeinflusst den erreichten EEMBC ULPBench-Score direkt.
board.h
#ifndef _BOARD_H_
#define _BOARD_H_
// Get board and chip defines
#include <compiler.h>
#include <gclk.h>
#include <port.h>
#endif /* _BOARD_H_ */
hardware_setup.c für SAML21
/*********************************************************
(C) 2014 EEMBC(R) and ULPBench(TM). All rights reserved.
EEMBC ULPBench Software is a product of EEMBC and is provided
under the terms of the ULPBench License that is distributed
with the official EEMBC ULPBench Software release.
The Software is the proprietary intellectual property of EEMBC
and its members and is protected under all applicable laws,
including all applicable copyright laws.
If you received this EEMBC ULPBench Software
without the accompanying ULPBench License,
you must discontinue use and download the official release
from http://www.eembc.org/benchmark/ulp_sl.php.
**********************************************************/
//=============================================================================
// Platform.c
//
// Platform-specific declarations
//=============================================================================
//=============================================================================
// board/chip defines
#include „board.h“
#include „TesTPI.h“
#include „CoreProfile.h“
//=============================================================================
void RTC_Start( void )
{
// $$$ Code to init the RTC.
//clock for RTC : Xosc32k
OSC32KCTRL->RTCCTRL.bit.RTCSEL = OSC32KCTRL_RTCCTRL_RTCSEL(OSC32KCTRL_RTCCTRL_RTCSEL_XOSC32K_Val);
RTC->MODE0.CTRLA.bit.SWRST=1;
while(RTC->MODE0.SYNCBUSY.bit.SWRST>0);
RTC->MODE0.INTENSET.reg = RTC_MODE0_INTENCLR_CMP0;
RTC->MODE0.COMP[0].reg = 32768;
while(RTC->MODE0.SYNCBUSY.bit.COMP0>0);
//Mode 0
RTC->MODE0.CTRLA.reg = RTC_MODE0_CTRLA_MODE(0)|RTC_MODE0_CTRLA_PRESCALER(RTC_MODE0_CTRLA_PRESCALER_DIV1_Val);
RTC->MODE0.CTRLA.reg = RTC_MODE0_CTRLA_ENABLE|RTC_MODE0_CTRLA_MATCHCLR|RTC_MODE0_CTRLA_MODE(0)|RTC_MODE0_CTRLA_PRESCALER(RTC_MODE0_CTRLA_PRESCALER_DIV1_Val);
while(RTC->MODE0.SYNCBUSY.bit.ENABLE>0);
}
//Initialise BOD33 in sampling mode for RUN and STANDBY
//Threshold is set at approximately
void BOD_init_sampled(void)
{
while(SUPC->STATUS.bit.B33SRDY==0);
SUPC->BOD33.reg = SUPC_BOD33_HYST | SUPC_BOD33_ACTION_INT | SUPC_BOD33_RUNSTDBY | SUPC_BOD33_LEVEL(30) | SUPC_BOD33_PSEL_DIV2;
while(SUPC->STATUS.bit.B33SRDY==0);
SUPC->BOD33.reg = SUPC_BOD33_HYST | SUPC_BOD33_ACTION_INT | SUPC_BOD33_RUNSTDBY | SUPC_BOD33_LEVEL(30) | SUPC_BOD33_PSEL_DIV2 | SUPC_BOD33_STDBYCFG;
while(SUPC->STATUS.bit.B33SRDY==0);
SUPC->BOD33.reg = SUPC_BOD33_ENABLE | SUPC_BOD33_HYST | SUPC_BOD33_ACTION_INT | SUPC_BOD33_RUNSTDBY | SUPC_BOD33_LEVEL(30) | SUPC_BOD33_PSEL_DIV2 | SUPC_BOD33_STDBYCFG;
while(SUPC->STATUS.bit.B33SRDY==0);
//RevA1 errata ref #13918 workaround below
SUPC->INTFLAG.reg = SUPC_INTFLAG_BOD33DET;
SUPC->BOD33.reg = SUPC_BOD33_ENABLE | SUPC_BOD33_HYST | SUPC_BOD33_ACTION_RESET | SUPC_BOD33_RUNSTDBY | SUPC_BOD33_LEVEL(30) | SUPC_BOD33_PSEL_DIV2 | SUPC_BOD33_STDBYCFG| SUPC_BOD33_ACTCFG;
while(SUPC->STATUS.bit.B33SRDY==0);
}
void hardware_setup_part1( void )
{
PORT->Group[1].DIR.reg |= (1<<0); //PB00 is an output
PORT->Group[1].DIR.reg |= (1<<1); //PB01 is an output
//Enable XOSC32K (for RTC)
OSC32KCTRL->XOSC32K.reg = OSC32KCTRL_XOSC32K_ENABLE | OSC32KCTRL_XOSC32K_XTALEN|\
OSC32KCTRL_XOSC32K_EN32K|\
OSC32KCTRL_XOSC32K_RUNSTDBY | OSC32KCTRL_XOSC32K_STARTUP(4);
while(OSC32KCTRL->STATUS.bit.XOSC32KRDY==0);
// $$$ init device phase 1 (device specific startup)
RTC_Start();
//Running at 12MHz in PL0, requires 1 waistate on flash
NVMCTRL->CTRLB.bit.RWS = 1;
//Use xMHz system clock
OSCCTRL->OSC16MCTRL.bit.FSEL=2;
//Workaround for errata #13674
SUPC->VREF.reg |= 1<<8;
//nLDO/Buck : Select Buck
SUPC->VREG.bit.SEL = 1;
while(SUPC->STATUS.bit.VREGRDY==0);
//Use BOD for voltage integrity
BOD_init_sampled();
//Enable RTC interrupts
NVIC_ClearPendingIRQ(RTC_IRQn);
NVIC_SetPriority(RTC_IRQn, 3);
NVIC_EnableIRQ(RTC_IRQn);
// global interrupt enable
cpu_irq_enable();
}
void hardware_setup_part2( void )
{
// $$$ init device phase 2 (device specific, after TES started)
}
//=============================================================================
/*__interrupt*/ void pltTimer_ISR (void)
{
tesTimerInterrupt();
// $$$ Code to finish Sleep mode.
}
void RTC_Handler(void)
{
volatile uint32_t i;
RTC->MODE0.INTFLAG.reg = RTC_MODE0_INTFLAG_CMP0;
NVIC_ClearPendingIRQ(RTC_IRQn);
tesTimerInterrupt();
}