board.cpp
Go to the documentation of this file.
1 /*
2  * Pavel Kirienko, 2014 <pavel.kirienko@gmail.com>
3  * Board initialization for Olimex LPC11C24
4  */
5 
6 #include "board.hpp"
7 #include <chip.h>
8 #include <cstdlib>
9 #include <cstring>
10 #include <numeric>
11 
12 static constexpr unsigned long PDRUNCFGUSEMASK = 0x0000ED00U;
13 static constexpr unsigned long PDRUNCFGMASKTMP = 0x000000FFU;
14 
15 const std::uint32_t OscRateIn = 12000000;
17 
19 
20 namespace board
21 {
22 namespace
23 {
24 
25 constexpr unsigned TargetSystemCoreClock = 48000000;
26 
27 constexpr unsigned ErrorLedPort = 1;
28 constexpr unsigned ErrorLedPin = 10;
29 
30 constexpr unsigned StatusLedPort = 1;
31 constexpr unsigned StatusLedPin = 11;
32 
33 struct PinMuxGroup
34 {
35  unsigned pin : 8;
36  unsigned modefunc : 24;
37 };
38 
39 constexpr PinMuxGroup pinmux[] =
40 {
41  { IOCON_PIO1_10, IOCON_FUNC0 | IOCON_MODE_INACT }, // Error LED
42  { IOCON_PIO1_11, IOCON_FUNC0 | IOCON_MODE_INACT }, // Status LED
44 };
45 
46 
47 void sysctlPowerDown(unsigned long powerdownmask)
48 {
49  unsigned long pdrun = LPC_SYSCTL->PDRUNCFG & PDRUNCFGMASKTMP;
50  pdrun |= (powerdownmask & PDRUNCFGMASKTMP);
51  LPC_SYSCTL->PDRUNCFG = pdrun | PDRUNCFGUSEMASK;
52 }
53 
54 void sysctlPowerUp(unsigned long powerupmask)
55 {
56  unsigned long pdrun = LPC_SYSCTL->PDRUNCFG & PDRUNCFGMASKTMP;
57  pdrun &= ~(powerupmask & PDRUNCFGMASKTMP);
58  LPC_SYSCTL->PDRUNCFG = pdrun | PDRUNCFGUSEMASK;
59 }
60 
61 void initWatchdog()
62 {
63  Chip_WWDT_Init(LPC_WWDT); // Initialize watchdog
64  sysctlPowerUp(SYSCTL_POWERDOWN_WDTOSC_PD); // Enable watchdog oscillator
65  Chip_Clock_SetWDTOSC(WDTLFO_OSC_0_60, 4); // WDT osc rate 0.6 MHz / 4 = 150 kHz
66  Chip_Clock_SetWDTClockSource(SYSCTL_WDTCLKSRC_WDTOSC, 1); // Clocking watchdog from its osc, div rate 1
67  Chip_WWDT_SetTimeOut(LPC_WWDT, 37500); // 1 sec (hardcoded to reduce code size)
68  Chip_WWDT_SetOption(LPC_WWDT, WWDT_WDMOD_WDRESET); // Mode: reset on timeout
70 }
71 
72 void initClock()
73 {
74  sysctlPowerUp(SYSCTL_POWERDOWN_SYSOSC_PD); // Enable system oscillator
75  for (volatile int i = 0; i < 1000; i++) { }
76 
78  sysctlPowerDown(SYSCTL_POWERDOWN_SYSPLL_PD);
79 
80  /*
81  * Setup PLL for main oscillator rate (FCLKIN = 12MHz) * 4 = 48MHz
82  * MSEL = 3 (this is pre-decremented), PSEL = 1 (for P = 2)
83  * FCLKOUT = FCLKIN * (MSEL + 1) = 12MHz * 4 = 48MHz
84  * FCCO = FCLKOUT * 2 * P = 48MHz * 2 * 2 = 192MHz (within FCCO range)
85  */
87  sysctlPowerUp(SYSCTL_POWERDOWN_SYSPLL_PD);
88  while (!Chip_Clock_IsSystemPLLLocked()) { }
89 
91 
93 
95 
97 
98  while (SystemCoreClock != TargetSystemCoreClock) { } // Loop forever if the clock failed to initialize properly
99 }
100 
101 void initGpio()
102 {
103  LPC_SYSCTL->SYSAHBCLKCTRL |= 1 << SYSCTL_CLOCK_IOCON;
104  LPC_SYSCTL->SYSAHBCLKCTRL |= 1 << SYSCTL_CLOCK_GPIO;
105 
106  for (unsigned i = 0; i < (sizeof(pinmux) / sizeof(PinMuxGroup)); i++)
107  {
108  LPC_IOCON->REG[pinmux[i].pin] = pinmux[i].modefunc;
109  }
110 
111  LPC_GPIO[ErrorLedPort].DIR |= 1 << ErrorLedPin;
112  LPC_GPIO[StatusLedPort].DIR |= 1 << StatusLedPin;
113 }
114 
115 void initUart()
116 {
118  Chip_UART_SetBaud(LPC_USART, 115200);
120 }
121 
122 void init()
123 {
126 
127  initWatchdog();
128  initClock();
129  initGpio();
130  initUart();
131 
132  resetWatchdog();
133 }
134 
135 } // namespace
136 
137 void die()
138 {
139  static const volatile unsigned& DHCSR = *reinterpret_cast<unsigned*>(0xE000EDF0U);
140 
141  syslog("FATAL\r\n");
142 
143  while (true)
144  {
145  if ((DHCSR & 1U) != 0)
146  {
147  __asm volatile ("bkpt #0\n"); // Break into the debugger
148  }
149  }
150 }
151 
152 #if __GNUC__
153 __attribute__((optimize(0))) // Optimization must be disabled lest it hardfaults in the IAP call
154 #endif
156 {
157  unsigned aligned_array[5] = {}; // out_uid may be unaligned, so we need to use temp array
158  unsigned iap_command = 58;
159  reinterpret_cast<void(*)(void*, void*)>(0x1FFF1FF1)(&iap_command, aligned_array);
160  std::memcpy(out_uid, &aligned_array[1], 16);
161 }
162 
163 void setStatusLed(bool state)
164 {
165  LPC_GPIO[StatusLedPort].DATA[1 << StatusLedPin] = static_cast<unsigned long>(!state) << StatusLedPin;
166 }
167 
168 void setErrorLed(bool state)
169 {
170  LPC_GPIO[ErrorLedPort].DATA[1 << ErrorLedPin] = static_cast<unsigned long>(!state) << ErrorLedPin;
171 }
172 
174 {
176 }
177 
178 void syslog(const char* msg)
179 {
180  Chip_UART_SendBlocking(LPC_USART, msg, static_cast<int>(std::strlen(msg)));
181 }
182 
183 } // namespace board
184 
185 extern "C"
186 {
187 
188 void SystemInit();
189 
191 {
192  board::init();
193 }
194 
195 }
SYSCTL_BODINTVAL_RESERVED1
@ SYSCTL_BODINTVAL_RESERVED1
Definition: sysctl_11xx.h:259
board::resetWatchdog
void resetWatchdog()
Definition: board.cpp:173
board::setStatusLed
void setStatusLed(bool state)
Definition: board.cpp:163
LPC_USART
#define LPC_USART
Definition: chip.h:159
LPC_SYSCTL
#define LPC_SYSCTL
Definition: chip.h:181
SystemCoreClock
std::uint32_t SystemCoreClock
Initialized to default clock value, will be changed on init.
Definition: board.cpp:18
SystemInit
void SystemInit()
Definition: board.cpp:190
Chip_Clock_SetupSystemPLL
STATIC INLINE void Chip_Clock_SetupSystemPLL(uint8_t msel, uint8_t psel)
Set System PLL divider values.
Definition: clock_11xx.h:54
SYSCTL_MAINCLKSRC_PLLOUT
@ SYSCTL_MAINCLKSRC_PLLOUT
Definition: clock_11xx.h:192
board::syslog
void syslog(const char *msg)
Definition: board.cpp:178
PDRUNCFGMASKTMP
static constexpr unsigned long PDRUNCFGMASKTMP
Definition: board.cpp:13
LPC_GPIO
#define LPC_GPIO
Definition: chip.h:192
uavcan::uint32_t
std::uint32_t uint32_t
Definition: std.hpp:26
IOCON_FUNC0
#define IOCON_FUNC0
Definition: iocon_11xx.h:166
OscRateIn
const std::uint32_t OscRateIn
External crystal.
Definition: board.cpp:15
Chip_WWDT_Start
STATIC INLINE void Chip_WWDT_Start(LPC_WWDT_T *pWWDT)
Enable WWDT activity.
Definition: wwdt_11xx.h:190
SYSCTL_PLLCLKSRC_MAINOSC
@ SYSCTL_PLLCLKSRC_MAINOSC
Definition: clock_11xx.h:73
Chip_Clock_IsSystemPLLLocked
STATIC INLINE bool Chip_Clock_IsSystemPLLLocked(void)
Read System PLL lock status.
Definition: clock_11xx.h:63
SYSCTL_CLOCK_IOCON
@ SYSCTL_CLOCK_IOCON
Definition: clock_11xx.h:253
IOCON_PIO1_10
@ IOCON_PIO1_10
Definition: iocon_11xx.h:81
IOCON_FUNC1
#define IOCON_FUNC1
Definition: iocon_11xx.h:167
board::UniqueIDSize
static constexpr unsigned UniqueIDSize
Definition: board.hpp:15
modefunc
unsigned modefunc
Definition: board.cpp:36
Chip_WWDT_SetOption
STATIC INLINE void Chip_WWDT_SetOption(LPC_WWDT_T *pWWDT, uint32_t options)
Enable watchdog timer options.
Definition: wwdt_11xx.h:166
Chip_WWDT_SetTimeOut
STATIC INLINE void Chip_WWDT_SetTimeOut(LPC_WWDT_T *pWWDT, uint32_t timeout)
Set WDT timeout constant value used for feed.
Definition: wwdt_11xx.h:107
LPC_IOCON
#define LPC_IOCON
Definition: chip.h:180
Chip_WWDT_Feed
STATIC INLINE void Chip_WWDT_Feed(LPC_WWDT_T *pWWDT)
Feed watchdog timer.
Definition: wwdt_11xx.h:119
SYSCTL_POWERDOWN_SYSPLL_PD
#define SYSCTL_POWERDOWN_SYSPLL_PD
Definition: sysctl_11xx.h:634
board::die
void die()
Definition: board.cpp:137
Chip_Clock_SetSystemPLLSource
void Chip_Clock_SetSystemPLLSource(CHIP_SYSCTL_PLLCLKSRC_T src)
Set System PLL clock source.
Definition: clock_11xx.c:90
Chip_SYSCTL_EnableBODReset
STATIC INLINE void Chip_SYSCTL_EnableBODReset(void)
Enable brown-out detection reset.
Definition: sysctl_11xx.h:296
board
Definition: board.cpp:20
IOCON_MODE_INACT
#define IOCON_MODE_INACT
Definition: iocon_11xx.h:174
uavcan::uint8_t
std::uint8_t uint8_t
Definition: std.hpp:24
Chip_UART_TXEnable
STATIC INLINE void Chip_UART_TXEnable(LPC_USART_T *pUART)
Enable transmission on UART TxD pin.
Definition: uart_11xx.h:300
board::readUniqueID
void readUniqueID(std::uint8_t out_uid[UniqueIDSize])
Definition: board.cpp:155
Chip_Clock_SetWDTOSC
STATIC INLINE void Chip_Clock_SetWDTOSC(CHIP_WDTLFO_OSC_T wdtclk, uint8_t div)
Setup Watchdog oscillator rate and divider.
Definition: clock_11xx.h:164
Chip_WWDT_Init
void Chip_WWDT_Init(LPC_WWDT_T *pWWDT)
Initialize the Watchdog timer.
Definition: wwdt_11xx.c:56
WDTLFO_OSC_0_60
@ WDTLFO_OSC_0_60
Definition: clock_11xx.h:140
SYSCTL_BODRSTLVL_2_06V
@ SYSCTL_BODRSTLVL_2_06V
Definition: sysctl_11xx.h:249
Chip_Clock_SetSysClockDiv
STATIC INLINE void Chip_Clock_SetSysClockDiv(uint32_t div)
Set system clock divider.
Definition: clock_11xx.h:220
Chip_Clock_GetSystemClockRate
uint32_t Chip_Clock_GetSystemClockRate(void)
Return system clock rate.
Definition: clock_11xx.c:281
board.hpp
Chip_UART_SetBaud
uint32_t Chip_UART_SetBaud(LPC_USART_T *pUART, uint32_t baudrate)
Sets best dividers to get a target bit rate (without fractional divider)
Definition: uart_11xx.c:146
Chip_UART_Init
void Chip_UART_Init(LPC_USART_T *pUART)
Initializes the pUART peripheral.
Definition: uart_11xx.c:58
SYSCTL_CLOCK_GPIO
@ SYSCTL_CLOCK_GPIO
Definition: clock_11xx.h:239
Chip_Clock_SetMainClockSource
void Chip_Clock_SetMainClockSource(CHIP_SYSCTL_MAINCLKSRC_T src)
Set main system clock source.
Definition: clock_11xx.c:124
IOCON_MODE_PULLUP
#define IOCON_MODE_PULLUP
Definition: iocon_11xx.h:176
FLASHTIM_50MHZ_CPU
@ FLASHTIM_50MHZ_CPU
Definition: fmc_11xx.h:75
PDRUNCFGUSEMASK
static constexpr unsigned long PDRUNCFGUSEMASK
Definition: board.cpp:12
pin
unsigned pin
Definition: board.cpp:35
__attribute__
__attribute__((gnu_inline)) inline void spi_start(uint8_t data)
Definition: spi.h:74
board::setErrorLed
void setErrorLed(bool state)
Definition: board.cpp:168
uavcan_kinetis::clock::init
void init()
Definition: clock.cpp:43
chip.h
SYSCTL_POWERDOWN_WDTOSC_PD
#define SYSCTL_POWERDOWN_WDTOSC_PD
Definition: sysctl_11xx.h:633
WWDT_WDMOD_WDRESET
#define WWDT_WDMOD_WDRESET
Definition: wwdt_11xx.h:79
Chip_FMC_SetFLASHAccess
STATIC INLINE void Chip_FMC_SetFLASHAccess(FMC_FLASHTIM_T clks)
Set FLASH access time in clocks.
Definition: fmc_11xx.h:85
IOCON_PIO1_11
@ IOCON_PIO1_11
Definition: iocon_11xx.h:82
LPC_WWDT
#define LPC_WWDT
Definition: chip.h:158
IOCON_HYS_EN
#define IOCON_HYS_EN
Definition: iocon_11xx.h:178
SYSCTL_POWERDOWN_SYSOSC_PD
#define SYSCTL_POWERDOWN_SYSOSC_PD
Definition: sysctl_11xx.h:632
IOCON_PIO1_7
@ IOCON_PIO1_7
Definition: iocon_11xx.h:78
Chip_UART_SendBlocking
int Chip_UART_SendBlocking(LPC_USART_T *pUART, const void *data, int numBytes)
Transmit a byte array through the UART peripheral (blocking)
Definition: uart_11xx.c:97
Chip_SYSCTL_SetBODLevels
STATIC INLINE void Chip_SYSCTL_SetBODLevels(CHIP_SYSCTL_BODRSTLVL_T rstlvl, CHIP_SYSCTL_BODRINTVAL_T intlvl)
Set brown-out detection interrupt and reset levels.
Definition: sysctl_11xx.h:275
ExtRateIn
const std::uint32_t ExtRateIn
Clock rate on the CLKIN pin This value is defined externally to the chip layer and contains the value...
Definition: board.cpp:16


uavcan_communicator
Author(s):
autogenerated on Fri Dec 13 2024 03:10:02