mbed-os

Fork of mbed-os by erkin yucel

Committer:
elessair
Date:
Sun Oct 23 15:10:02 2016 +0000
Revision:
0:f269e3021894
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
elessair 0:f269e3021894 1 /**
elessair 0:f269e3021894 2 ***************************************************************************
elessair 0:f269e3021894 3 * @file ncs36510_init.c
elessair 0:f269e3021894 4 * @brief Initialization of Orion SoC
elessair 0:f269e3021894 5 * @internal
elessair 0:f269e3021894 6 * @author ON Semiconductor
elessair 0:f269e3021894 7 * $Rev:
elessair 0:f269e3021894 8 * $Date: $
elessair 0:f269e3021894 9 ******************************************************************************
elessair 0:f269e3021894 10 * Copyright 2016 Semiconductor Components Industries LLC (d/b/a “ON Semiconductor”).
elessair 0:f269e3021894 11 * All rights reserved. This software and/or documentation is licensed by ON Semiconductor
elessair 0:f269e3021894 12 * under limited terms and conditions. The terms and conditions pertaining to the software
elessair 0:f269e3021894 13 * and/or documentation are available at http://www.onsemi.com/site/pdf/ONSEMI_T&C.pdf
elessair 0:f269e3021894 14 * (“ON Semiconductor Standard Terms and Conditions of Sale, Section 8 Software”) and
elessair 0:f269e3021894 15 * if applicable the software license agreement. Do not use this software and/or
elessair 0:f269e3021894 16 * documentation unless you have carefully read and you agree to the limited terms and
elessair 0:f269e3021894 17 * conditions. By using this software and/or documentation, you agree to the limited
elessair 0:f269e3021894 18 * terms and conditions.
elessair 0:f269e3021894 19 *
elessair 0:f269e3021894 20 * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
elessair 0:f269e3021894 21 * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
elessair 0:f269e3021894 22 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
elessair 0:f269e3021894 23 * ON SEMICONDUCTOR SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL,
elessair 0:f269e3021894 24 * INCIDENTAL, OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
elessair 0:f269e3021894 25 * @endinternal
elessair 0:f269e3021894 26 *
elessair 0:f269e3021894 27 * @ingroup main
elessair 0:f269e3021894 28 *
elessair 0:f269e3021894 29 * @details
elessair 0:f269e3021894 30 */
elessair 0:f269e3021894 31
elessair 0:f269e3021894 32 /*************************************************************************************************
elessair 0:f269e3021894 33 * *
elessair 0:f269e3021894 34 * Header files *
elessair 0:f269e3021894 35 * *
elessair 0:f269e3021894 36 *************************************************************************************************/
elessair 0:f269e3021894 37 #include "ncs36510Init.h"
elessair 0:f269e3021894 38
elessair 0:f269e3021894 39 void fPmuInit(void);
elessair 0:f269e3021894 40 /**
elessair 0:f269e3021894 41 * @brief
elessair 0:f269e3021894 42 * Hardware trimming function
elessair 0:f269e3021894 43 * This function copies trim codes from specific flash location
elessair 0:f269e3021894 44 * where they are stored to proper hw registers.
elessair 0:f269e3021894 45 */
elessair 0:f269e3021894 46 boolean fTrim()
elessair 0:f269e3021894 47 {
elessair 0:f269e3021894 48
elessair 0:f269e3021894 49 /**- Check if trim values are present */
elessair 0:f269e3021894 50 /**- If Trim data is present. Only trim if valid trim values are present. */
elessair 0:f269e3021894 51 /**- Copy trims in registers */
elessair 0:f269e3021894 52 if (TRIMREG->REVISION_CODE != 0xFFFFFFFF) {
elessair 0:f269e3021894 53
elessair 0:f269e3021894 54 /**- board specific clock trims may only be done when present, writing all 1's is not good */
elessair 0:f269e3021894 55 if ((TRIMREG->TRIM_32K_EXT & 0xFFFF0000) != 0xFFFF0000) {
elessair 0:f269e3021894 56 CLOCKREG->TRIM_32K_EXT = TRIMREG->TRIM_32K_EXT;
elessair 0:f269e3021894 57 }
elessair 0:f269e3021894 58
elessair 0:f269e3021894 59 if ((TRIMREG->TRIM_32M_EXT & 0xFFFF0000) != 0xFFFF0000) {
elessair 0:f269e3021894 60 CLOCKREG->TRIM_32M_EXT = TRIMREG->TRIM_32M_EXT;
elessair 0:f269e3021894 61 }
elessair 0:f269e3021894 62
elessair 0:f269e3021894 63 MACHWREG->TX_LENGTH.BITS.TX_PRE_CHIPS = TRIMREG->TX_PRE_CHIPS;
elessair 0:f269e3021894 64
elessair 0:f269e3021894 65 RFANATRIMREG->TX_CHAIN_TRIM = TRIMREG->TX_CHAIN_TRIM;
elessair 0:f269e3021894 66 RFANATRIMREG->PLL_VCO_TAP_LOCATION = TRIMREG->PLL_VCO_TAP_LOCATION;
elessair 0:f269e3021894 67 RFANATRIMREG->PLL_TRIM.WORD = TRIMREG->PLL_TRIM;
elessair 0:f269e3021894 68
elessair 0:f269e3021894 69 /**- board specific RSSI trims may only be done when present, writing all 1's is not good */
elessair 0:f269e3021894 70 if ((TRIMREG->RSSI_OFFSET & 0xFFFF0000) != 0xFFFF0000) {
elessair 0:f269e3021894 71 DMDREG->DMD_CONTROL2.BITS.RSSI_OFFSET = TRIMREG->RSSI_OFFSET;
elessair 0:f269e3021894 72 }
elessair 0:f269e3021894 73
elessair 0:f269e3021894 74 RFANATRIMREG->RX_CHAIN_TRIM = TRIMREG->RX_CHAIN_TRIM;
elessair 0:f269e3021894 75 RFANATRIMREG->PMU_TRIM = TRIMREG->PMU_TRIM;
elessair 0:f269e3021894 76 RANDREG->WR_SEED_RD_RAND = TRIMREG->WR_SEED_RD_RAND;
elessair 0:f269e3021894 77
elessair 0:f269e3021894 78 /** REVD boards are trimmed (in flash) with rx vco trims specific for high side injection,
elessair 0:f269e3021894 79 * */
elessair 0:f269e3021894 80 RFANATRIMREG->RX_VCO_TRIM_LUT1 = TRIMREG->RX_VCO_LUT1.WORD;;
elessair 0:f269e3021894 81 RFANATRIMREG->RX_VCO_TRIM_LUT2 = TRIMREG->RX_VCO_LUT2.WORD;;
elessair 0:f269e3021894 82
elessair 0:f269e3021894 83 RFANATRIMREG->TX_VCO_TRIM_LUT1 = TRIMREG->TX_VCO_LUT1.WORD;;
elessair 0:f269e3021894 84 RFANATRIMREG->TX_VCO_TRIM_LUT2 = TRIMREG->TX_VCO_LUT2.WORD;;
elessair 0:f269e3021894 85
elessair 0:f269e3021894 86
elessair 0:f269e3021894 87 return True;
elessair 0:f269e3021894 88 } else {
elessair 0:f269e3021894 89 /**- If no trim values are present, update the global status variable. */
elessair 0:f269e3021894 90 return False;
elessair 0:f269e3021894 91 }
elessair 0:f269e3021894 92 }
elessair 0:f269e3021894 93
elessair 0:f269e3021894 94 /* See clock.h for documentation. */
elessair 0:f269e3021894 95 void fClockInit()
elessair 0:f269e3021894 96 {
elessair 0:f269e3021894 97
elessair 0:f269e3021894 98 /** Enable external 32MHz oscillator */
elessair 0:f269e3021894 99 CLOCKREG->CCR.BITS.OSC_SEL = 1;
elessair 0:f269e3021894 100
elessair 0:f269e3021894 101 /** - Wait external 32MHz oscillator to be ready */
elessair 0:f269e3021894 102 while(CLOCKREG->CSR.BITS.XTAL32M != 1) {} /* If you get stuck here, something is wrong with board or trim values */
elessair 0:f269e3021894 103
elessair 0:f269e3021894 104 /** Internal 32MHz calibration \n *//** - Enable internal 32MHz clock */
elessair 0:f269e3021894 105 PMUREG->CONTROL.BITS.INT32M = 0;
elessair 0:f269e3021894 106
elessair 0:f269e3021894 107 /** - Wait 5 uSec for clock to stabilize */
elessair 0:f269e3021894 108 volatile uint8_t Timer;
elessair 0:f269e3021894 109 for(Timer = 0; Timer < 10; Timer++);
elessair 0:f269e3021894 110
elessair 0:f269e3021894 111 /** - Enable calibration */
elessair 0:f269e3021894 112 CLOCKREG->CCR.BITS.CAL32M = True;
elessair 0:f269e3021894 113
elessair 0:f269e3021894 114 /** - Wait calibration to be completed */
elessair 0:f269e3021894 115 while(CLOCKREG->CSR.BITS.CAL32MDONE == False); /* If you stuck here, issue with internal 32M calibration */
elessair 0:f269e3021894 116
elessair 0:f269e3021894 117 /** - Check calibration status */
elessair 0:f269e3021894 118 while(CLOCKREG->CSR.BITS.CAL32MFAIL == True); /* If you stuck here, issue with internal 32M calibration */
elessair 0:f269e3021894 119
elessair 0:f269e3021894 120 /** - Power down internal 32MHz osc */
elessair 0:f269e3021894 121 PMUREG->CONTROL.BITS.INT32M = 1;
elessair 0:f269e3021894 122
elessair 0:f269e3021894 123 /** Internal 32KHz calibration \n */ /** - Enable internal 32KHz clock */
elessair 0:f269e3021894 124 PMUREG->CONTROL.BITS.INT32K = 0;
elessair 0:f269e3021894 125
elessair 0:f269e3021894 126 /** - Wait 5 uSec for clock to stabilize */
elessair 0:f269e3021894 127 for(Timer = 0; Timer < 10; Timer++);
elessair 0:f269e3021894 128
elessair 0:f269e3021894 129 /** - Enable calibration */
elessair 0:f269e3021894 130 CLOCKREG->CCR.BITS.CAL32K = True;
elessair 0:f269e3021894 131
elessair 0:f269e3021894 132 /** - Wait calibration to be completed */
elessair 0:f269e3021894 133 while(CLOCKREG->CSR.BITS.DONE32K == False); /* If you stuck here, issue with internal 32K calibration */
elessair 0:f269e3021894 134
elessair 0:f269e3021894 135 /** - Check calibration status */
elessair 0:f269e3021894 136 while(CLOCKREG->CSR.BITS.CAL32K == True); /* If you stuck here, issue with internal 32M calibration */
elessair 0:f269e3021894 137
elessair 0:f269e3021894 138 /** - Power down external 32KHz osc */
elessair 0:f269e3021894 139 PMUREG->CONTROL.BITS.EXT32K = 1;
elessair 0:f269e3021894 140
elessair 0:f269e3021894 141 /** Disable all peripheral clocks by default */
elessair 0:f269e3021894 142 CLOCKREG->PDIS.WORD = 0xFFFFFFFF;
elessair 0:f269e3021894 143
elessair 0:f269e3021894 144 /** Set core frequency */
elessair 0:f269e3021894 145 CLOCKREG->FDIV = CPU_CLOCK_DIV - 1;
elessair 0:f269e3021894 146 }
elessair 0:f269e3021894 147
elessair 0:f269e3021894 148 /* Initializes PMU module */
elessair 0:f269e3021894 149 void fPmuInit()
elessair 0:f269e3021894 150 {
elessair 0:f269e3021894 151 /** Enable the clock for PMU peripheral device */
elessair 0:f269e3021894 152 CLOCK_ENABLE(CLOCK_PMU);
elessair 0:f269e3021894 153
elessair 0:f269e3021894 154 /** Unset wakeup on pending (only enabled irq can wakeup) */
elessair 0:f269e3021894 155 SCB->SCR &= ~SCB_SCR_SEVONPEND_Msk;
elessair 0:f269e3021894 156
elessair 0:f269e3021894 157 /** Unset auto sleep when returning from wakeup irq */
elessair 0:f269e3021894 158 SCB->SCR &= ~SCB_SCR_SLEEPONEXIT_Msk;
elessair 0:f269e3021894 159
elessair 0:f269e3021894 160 /** Set regulator timings */
elessair 0:f269e3021894 161 PMUREG->FVDD_TSETTLE = 160;
elessair 0:f269e3021894 162 PMUREG->FVDD_TSTARTUP = 400;
elessair 0:f269e3021894 163
elessair 0:f269e3021894 164 /** Keep SRAMA & SRAMB powered in coma mode */
elessair 0:f269e3021894 165 PMUREG->CONTROL.BITS.SRAMA = False;
elessair 0:f269e3021894 166 PMUREG->CONTROL.BITS.SRAMB = False;
elessair 0:f269e3021894 167
elessair 0:f269e3021894 168 PMUREG->CONTROL.BITS.N1V1 = True; /* Enable ACTIVE mode switching regulator */
elessair 0:f269e3021894 169 PMUREG->CONTROL.BITS.C1V1 = True; /* Enable COMA mode switching regulator */
elessair 0:f269e3021894 170
elessair 0:f269e3021894 171 /** Disable the clock for PMU peripheral device, all settings are done */
elessair 0:f269e3021894 172 CLOCK_DISABLE(CLOCK_PMU);
elessair 0:f269e3021894 173 }
elessair 0:f269e3021894 174
elessair 0:f269e3021894 175 /* See clock.h for documentation. */
elessair 0:f269e3021894 176 uint32_t fClockGetPeriphClockfrequency()
elessair 0:f269e3021894 177 {
elessair 0:f269e3021894 178 return (CPU_CLOCK_ROOT_HZ / CPU_CLOCK_DIV);
elessair 0:f269e3021894 179 }
elessair 0:f269e3021894 180
elessair 0:f269e3021894 181
elessair 0:f269e3021894 182 /**
elessair 0:f269e3021894 183 * @brief
elessair 0:f269e3021894 184 * Hardware initialization function
elessair 0:f269e3021894 185 * This function initializes hardware at application start up prior
elessair 0:f269e3021894 186 * to other initializations or OS operations.
elessair 0:f269e3021894 187 */
elessair 0:f269e3021894 188 static void fHwInit(void)
elessair 0:f269e3021894 189 {
elessair 0:f269e3021894 190
elessair 0:f269e3021894 191 /* Trim register settings */
elessair 0:f269e3021894 192 fTrim();
elessair 0:f269e3021894 193
elessair 0:f269e3021894 194 /* Clock setting */
elessair 0:f269e3021894 195 /** - Initialize clock */
elessair 0:f269e3021894 196 fClockInit();
elessair 0:f269e3021894 197
elessair 0:f269e3021894 198 /** - Initialize pmu */
elessair 0:f269e3021894 199 fPmuInit();
elessair 0:f269e3021894 200
elessair 0:f269e3021894 201 /** Orion has 4 interrupt bits in interrupt priority register
elessair 0:f269e3021894 202 * The lowest 4 bits are not used.
elessair 0:f269e3021894 203 *
elessair 0:f269e3021894 204 @verbatim
elessair 0:f269e3021894 205 +-----+-----+-----+-----+-----+-----+-----+-----+
elessair 0:f269e3021894 206 |bit 7|bit 6|bit 5|bit 4|bit 3|bit 2|bit 1|bit 0|
elessair 0:f269e3021894 207 | | | | | 0 | 0 | 0 | 0 |
elessair 0:f269e3021894 208 +-----+-----+-----+-----+-----+-----+-----+-----+
elessair 0:f269e3021894 209 |
elessair 0:f269e3021894 210 INTERRUPT PRIORITY | NOT IMPLEMENTED,
elessair 0:f269e3021894 211 | read as 0
elessair 0:f269e3021894 212 Valid priorities are 0x00, 0x10, 0x20, 0x30
elessair 0:f269e3021894 213 0x40, 0x50, 0x60, 0x70
elessair 0:f269e3021894 214 0x80, 0x90, 0xA0, 0xB0
elessair 0:f269e3021894 215 0xC0, 0xD0, 0xE0, 0xF0
elessair 0:f269e3021894 216 @endverbatim
elessair 0:f269e3021894 217 * Lowest number is highest priority
elessair 0:f269e3021894 218 *
elessair 0:f269e3021894 219 *
elessair 0:f269e3021894 220 * This range is defined by
elessair 0:f269e3021894 221 * configKERNEL_INTERRUPT_PRIORITY (lowest)
elessair 0:f269e3021894 222 * and configMAX_SYSCALL_INTERRUPT_PRIORITY (highest). All interrupt
elessair 0:f269e3021894 223 * priorities need to fall in that range.
elessair 0:f269e3021894 224 *
elessair 0:f269e3021894 225 * To be future safe, the LSbits of the priority are set to 0xF.
elessair 0:f269e3021894 226 * This wil lmake sure that if more interrupt bits are used, the
elessair 0:f269e3021894 227 * priority is maintained.
elessair 0:f269e3021894 228 */
elessair 0:f269e3021894 229
elessair 0:f269e3021894 230 /** - Set IRQs priorities */
elessair 0:f269e3021894 231 NVIC_SetPriority(Tim0_IRQn, 14);
elessair 0:f269e3021894 232 NVIC_SetPriority(Tim1_IRQn, 14);
elessair 0:f269e3021894 233 NVIC_SetPriority(Tim2_IRQn, 14);
elessair 0:f269e3021894 234 NVIC_SetPriority(Uart1_IRQn,14);
elessair 0:f269e3021894 235 NVIC_SetPriority(Spi_IRQn, 14);
elessair 0:f269e3021894 236 NVIC_SetPriority(I2C_IRQn, 14);
elessair 0:f269e3021894 237 NVIC_SetPriority(Gpio_IRQn, 14);
elessair 0:f269e3021894 238 NVIC_SetPriority(Rtc_IRQn, 14);
elessair 0:f269e3021894 239 NVIC_SetPriority(MacHw_IRQn, 13);
elessair 0:f269e3021894 240 NVIC_SetPriority(Aes_IRQn, 13);
elessair 0:f269e3021894 241 NVIC_SetPriority(Adc_IRQn, 14);
elessair 0:f269e3021894 242 NVIC_SetPriority(ClockCal_IRQn, 14);
elessair 0:f269e3021894 243 NVIC_SetPriority(Uart2_IRQn, 14);
elessair 0:f269e3021894 244 NVIC_SetPriority(Dma_IRQn, 14);
elessair 0:f269e3021894 245 NVIC_SetPriority(Uvi_IRQn, 14);
elessair 0:f269e3021894 246 NVIC_SetPriority(DbgPwrUp_IRQn, 14);
elessair 0:f269e3021894 247 NVIC_SetPriority(Spi2_IRQn, 14);
elessair 0:f269e3021894 248 NVIC_SetPriority(I2C2_IRQn, 14);
elessair 0:f269e3021894 249 }
elessair 0:f269e3021894 250
elessair 0:f269e3021894 251 extern void __Vectors;
elessair 0:f269e3021894 252
elessair 0:f269e3021894 253 void fNcs36510Init(void)
elessair 0:f269e3021894 254 {
elessair 0:f269e3021894 255 /** Setting this register is helping to debug imprecise bus access faults
elessair 0:f269e3021894 256 * making them precise bus access faults. It has an impact on application
elessair 0:f269e3021894 257 * performance. */
elessair 0:f269e3021894 258 // SCnSCB->ACTLR |= SCnSCB_ACTLR_DISDEFWBUF_Msk;
elessair 0:f269e3021894 259
elessair 0:f269e3021894 260 /** This main function implements: */
elessair 0:f269e3021894 261 /**- Disable all interrupts */
elessair 0:f269e3021894 262 NVIC->ICER[0] = 0x1F;
elessair 0:f269e3021894 263
elessair 0:f269e3021894 264 /**- Clear all Pending interrupts */
elessair 0:f269e3021894 265 NVIC->ICPR[0] = 0x1F;
elessair 0:f269e3021894 266
elessair 0:f269e3021894 267 /**- Clear all pending SV and systick */
elessair 0:f269e3021894 268 SCB->ICSR = (uint32_t)0x0A000000;
elessair 0:f269e3021894 269 SCB->VTOR = (uint32_t) (&__Vectors);
elessair 0:f269e3021894 270
elessair 0:f269e3021894 271 /**- Initialize hardware */
elessair 0:f269e3021894 272 fHwInit();
elessair 0:f269e3021894 273 }