1 /**
2     *****************************************************************************
3     * @file     cmem7_misc.c
4     *
5     * @brief    CMEM7 miscellaneous file
6     *
7     *
8     * @version  V1.0
9     * @date     3. September 2013
10     *
11     * @note
12     *
13     *****************************************************************************
14     * @attention
15     *
16     * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
17     * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
18     * TIME. AS A RESULT, CAPITAL-MICRO SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
19     * INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
20     * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
21     * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
22     *
23     * <h2><center>&copy; COPYRIGHT 2013 Capital-micro </center></h2>
24     *****************************************************************************
25     */
26 
27 #include "cmem7_misc.h"
28 
29 #define AIRCR_VECTKEY_MASK    ((uint32_t)0x05FA0000)
30 
NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup)31 void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup)
32 {
33   /* Check the parameters */
34   assert_param(IS_NVIC_PRIORITY_GROUP(NVIC_PriorityGroup));
35 
36   /* Set the PRIGROUP[10:8] bits according to NVIC_PriorityGroup value */
37   SCB->AIRCR = AIRCR_VECTKEY_MASK | NVIC_PriorityGroup;
38 }
39 
NVIC_Init(NVIC_InitTypeDef * NVIC_InitStruct)40 void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct)
41 {
42   uint32_t tmppriority = 0x00, tmppre = 0x00, tmpsub = 0x0F;
43 
44   /* Check the parameters */
45   assert_param(IS_NVIC_PREEMPTION_PRIORITY(NVIC_InitStruct->NVIC_IRQChannelPreemptionPriority));
46   assert_param(IS_NVIC_SUB_PRIORITY(NVIC_InitStruct->NVIC_IRQChannelSubPriority));
47 
48   if (NVIC_InitStruct->NVIC_IRQChannelCmd != FALSE)
49   {
50     /* Compute the Corresponding IRQ Priority --------------------------------*/
51     tmppriority = (0x700 - ((SCB->AIRCR) & (uint32_t)0x700))>> 0x08;
52     tmppre = (0x4 - tmppriority);
53     tmpsub = tmpsub >> tmppriority;
54 
55     tmppriority = (uint32_t)NVIC_InitStruct->NVIC_IRQChannelPreemptionPriority << tmppre;
56     tmppriority |=  NVIC_InitStruct->NVIC_IRQChannelSubPriority & tmpsub;
57     tmppriority = tmppriority << 0x04;
58 
59     NVIC->IP[NVIC_InitStruct->NVIC_IRQChannel] = tmppriority;
60 
61     /* Enable the Selected IRQ Channels --------------------------------------*/
62     NVIC->ISER[NVIC_InitStruct->NVIC_IRQChannel >> 0x05] =
63       (uint32_t)0x01 << (NVIC_InitStruct->NVIC_IRQChannel & (uint8_t)0x1F);
64   }
65   else
66   {
67     /* Disable the Selected IRQ Channels -------------------------------------*/
68     NVIC->ICER[NVIC_InitStruct->NVIC_IRQChannel >> 0x05] =
69       (uint32_t)0x01 << (NVIC_InitStruct->NVIC_IRQChannel & (uint8_t)0x1F);
70   }
71 }
72 
NVIC_SetVectorTable(uint32_t NVIC_VectTab,uint32_t Offset)73 void NVIC_SetVectorTable(uint32_t NVIC_VectTab, uint32_t Offset)
74 {
75   /* Check the parameters */
76   assert_param(IS_NVIC_VECTTAB(NVIC_VectTab));
77   assert_param(IS_NVIC_OFFSET(Offset));
78 
79   SCB->VTOR = NVIC_VectTab | (Offset & (uint32_t)0x1FFFFF80);
80 }
81 
NVIC_SystemLPConfig(uint8_t LowPowerMode,BOOL NewState)82 void NVIC_SystemLPConfig(uint8_t LowPowerMode, BOOL NewState)
83 {
84   /* Check the parameters */
85   assert_param(IS_NVIC_LP(LowPowerMode));
86 
87   if (!NewState)
88   {
89     SCB->SCR &= (uint32_t)(~(uint32_t)LowPowerMode);
90   } else {
91         SCB->SCR |= LowPowerMode;
92     }
93 }
94 
95 #define DEF_IBUS_OFFSET     0x1FFE0000
96 #define DEF_EXT_ADDR        0x08020000
isMappingOn()97 static BOOL isMappingOn() {
98   /* If default values aren't changed */
99   if ((GLOBAL_CTRL->IBUSOFF == DEF_IBUS_OFFSET) &&
100     (GLOBAL_CTRL->EXTADDR == DEF_EXT_ADDR)) {
101     return FALSE;
102   }
103 
104   return TRUE;
105 }
106 
GLB_MMAP(uint32_t from,uint32_t to,BOOL isIcacheOn)107 void GLB_MMAP(uint32_t from, uint32_t to, BOOL isIcacheOn) {
108     volatile int n;
109 
110     GLOBAL_CTRL->IBUSOFF = GLOBAL_CTRL->DBUSOFF = (from - to);
111     GLOBAL_CTRL->EXTADDR = to;
112 
113     // Delay several cycles
114     for (n = 0; n < 100; n++);
115     GLOBAL_CTRL->ICACHE_b.EN = isIcacheOn;
116     for (n = 0; n < 100; n++);
117 }
118 
119 /*
120  * ------------------------------------------------------------------
121  * | 0 - 0x20000 | --> 0x20000000 | -> 0x40000000 | -> 0xFFFFFFFF   |
122  * |  code SRAM  | map to region  | data SRAM     | map from region |
123  * ------------------------------------------------------------------
124  */
125 #define MAPPING_FROM_REGION_START   0x40000000
126 #define MAPPING_TO_REGION_END       0x20000000
GLB_ConvertToMappingFromAddr(uint32_t to)127 uint32_t GLB_ConvertToMappingFromAddr(uint32_t to) {
128   if (!isMappingOn()) {
129     return to;
130   }
131 
132   if ((to > MAPPING_TO_REGION_END) || (to < GLOBAL_CTRL->EXTADDR)) {
133     return to;
134   }
135 
136   return (to + GLOBAL_CTRL->IBUSOFF);
137 }
138 
GLB_ConvertToMappingToAddr(uint32_t from)139 uint32_t GLB_ConvertToMappingToAddr(uint32_t from) {
140   if (!isMappingOn()) {
141     return from;
142   }
143 
144   if (from < MAPPING_FROM_REGION_START) {
145     return from;
146   }
147 
148   return (from - GLOBAL_CTRL->IBUSOFF);
149 }
150 
GLB_SetNmiIrqNum(uint32_t irq)151 void GLB_SetNmiIrqNum(uint32_t irq) {
152     GLOBAL_CTRL->NMI_SEL_b.NMI = irq;
153 }
154 
GLB_SelectSysClkSource(uint8_t source)155 void GLB_SelectSysClkSource(uint8_t source) {
156     switch (source) {
157     case SYS_CLK_SEL_DLL :
158         // M7's DLL clock should be fixed at PLL loation 2
159         // In constrast, it's C2R1.
160         // Wait DLL clock stable
161         while (PDLOCK->GCLK_b.C2R1D == 0) ;
162         GLOBAL_CTRL->CLK_SEL_1_b.SYS_CLK = SYS_CLK_SEL_DLL;
163         break;
164     case SYS_CLK_SEL_CRYSTAL :
165         GLOBAL_CTRL->CLK_SEL_1_b.SYS_CLK = SYS_CLK_SEL_CRYSTAL;
166         break;
167     case SYS_CLK_SEL_EXTERNAL :
168         // TODO, Add the condition that makes sure input
169         // external clock is stable
170         // For example :
171         //  PLL location 0
172         //  while (PDLOCK->GCLK_b.C1R1P == 0) ;
173         //  DLL location 0
174         //  while (PDLOCK->GCLK_b.C1R1D == 0) ;
175         GLOBAL_CTRL->CLK_SEL_1_b.SYS_CLK = SYS_CLK_SEL_EXTERNAL;
176         break;
177     case SYS_CLK_SEL_OSC :
178         // Fall through
179     default :
180         GLOBAL_CTRL->CLK_SEL_1_b.SYS_CLK = SYS_CLK_SEL_OSC;
181         break;
182     }
183 }
184