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 }
static constexpr unsigned long PDRUNCFGUSEMASK
Definition: board.cpp:12
std::uint8_t uint8_t
Definition: std.hpp:24
#define LPC_WWDT
Definition: chip.h:158
#define WWDT_WDMOD_WDRESET
Definition: wwdt_11xx.h:79
void Chip_UART_Init(LPC_USART_T *pUART)
Initializes the pUART peripheral.
Definition: uart_11xx.c:58
void setErrorLed(bool state)
Definition: board.cpp:168
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
__attribute__((gnu_inline)) inline void spi_start(uint8_t data)
Definition: spi.h:74
void Chip_WWDT_Init(LPC_WWDT_T *pWWDT)
Initialize the Watchdog timer.
Definition: wwdt_11xx.c:56
unsigned modefunc
Definition: board.cpp:36
#define IOCON_FUNC1
Definition: iocon_11xx.h:167
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
STATIC INLINE void Chip_FMC_SetFLASHAccess(FMC_FLASHTIM_T clks)
Set FLASH access time in clocks.
Definition: fmc_11xx.h:85
#define SYSCTL_POWERDOWN_WDTOSC_PD
Definition: sysctl_11xx.h:633
std::uint32_t SystemCoreClock
Initialized to default clock value, will be changed on init.
Definition: board.cpp:18
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
void setStatusLed(bool state)
Definition: board.cpp:163
#define IOCON_HYS_EN
Definition: iocon_11xx.h:178
void Chip_Clock_SetSystemPLLSource(CHIP_SYSCTL_PLLCLKSRC_T src)
Set System PLL clock source.
Definition: clock_11xx.c:90
STATIC INLINE void Chip_SYSCTL_EnableBODReset(void)
Enable brown-out detection reset.
Definition: sysctl_11xx.h:296
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
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
const std::uint32_t OscRateIn
External crystal.
Definition: board.cpp:15
STATIC INLINE bool Chip_Clock_IsSystemPLLLocked(void)
Read System PLL lock status.
Definition: clock_11xx.h:63
#define SYSCTL_POWERDOWN_SYSPLL_PD
Definition: sysctl_11xx.h:634
#define IOCON_MODE_PULLUP
Definition: iocon_11xx.h:176
void resetWatchdog()
Definition: board.cpp:173
Definition: board.cpp:20
#define IOCON_MODE_INACT
Definition: iocon_11xx.h:174
std::uint32_t uint32_t
Definition: std.hpp:26
static constexpr unsigned long PDRUNCFGMASKTMP
Definition: board.cpp:13
STATIC INLINE void Chip_Clock_SetSysClockDiv(uint32_t div)
Set system clock divider.
Definition: clock_11xx.h:220
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
void die()
Definition: board.cpp:137
uint32_t Chip_Clock_GetSystemClockRate(void)
Return system clock rate.
Definition: clock_11xx.c:281
static constexpr unsigned UniqueIDSize
Definition: board.hpp:15
STATIC INLINE void Chip_UART_TXEnable(LPC_USART_T *pUART)
Enable transmission on UART TxD pin.
Definition: uart_11xx.h:303
STATIC INLINE void Chip_WWDT_Feed(LPC_WWDT_T *pWWDT)
Feed watchdog timer.
Definition: wwdt_11xx.h:119
#define LPC_SYSCTL
Definition: chip.h:181
unsigned pin
Definition: board.cpp:35
#define IOCON_FUNC0
Definition: iocon_11xx.h:166
void Chip_Clock_SetMainClockSource(CHIP_SYSCTL_MAINCLKSRC_T src)
Set main system clock source.
Definition: clock_11xx.c:124
#define LPC_IOCON
Definition: chip.h:180
STATIC INLINE void Chip_WWDT_SetOption(LPC_WWDT_T *pWWDT, uint32_t options)
Enable watchdog timer options.
Definition: wwdt_11xx.h:166
#define SYSCTL_POWERDOWN_SYSOSC_PD
Definition: sysctl_11xx.h:632
void SystemInit()
Definition: board.cpp:190
void syslog(const char *msg)
Definition: board.cpp:178
#define LPC_USART
Definition: chip.h:159
STATIC INLINE void Chip_WWDT_Start(LPC_WWDT_T *pWWDT)
Enable WWDT activity.
Definition: wwdt_11xx.h:190
void readUniqueID(std::uint8_t out_uid[UniqueIDSize])
Definition: board.cpp:155
STATIC INLINE void Chip_Clock_SetupSystemPLL(uint8_t msel, uint8_t psel)
Set System PLL divider values.
Definition: clock_11xx.h:54
#define LPC_GPIO
Definition: chip.h:192


uavcan_communicator
Author(s):
autogenerated on Wed Jan 11 2023 03:59:39