Color Oled(SSD1331) connect to STMicroelectronics Nucleo-F466

Dependencies:   ssd1331

Committer:
kadonotakashi
Date:
Wed Oct 10 00:33:53 2018 +0000
Revision:
0:8fdf9a60065b
how to make mbed librry

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kadonotakashi 0:8fdf9a60065b 1 /* mbed Microcontroller Library
kadonotakashi 0:8fdf9a60065b 2 * Copyright (c) 2015-2016 Nuvoton
kadonotakashi 0:8fdf9a60065b 3 *
kadonotakashi 0:8fdf9a60065b 4 * Licensed under the Apache License, Version 2.0 (the "License");
kadonotakashi 0:8fdf9a60065b 5 * you may not use this file except in compliance with the License.
kadonotakashi 0:8fdf9a60065b 6 * You may obtain a copy of the License at
kadonotakashi 0:8fdf9a60065b 7 *
kadonotakashi 0:8fdf9a60065b 8 * http://www.apache.org/licenses/LICENSE-2.0
kadonotakashi 0:8fdf9a60065b 9 *
kadonotakashi 0:8fdf9a60065b 10 * Unless required by applicable law or agreed to in writing, software
kadonotakashi 0:8fdf9a60065b 11 * distributed under the License is distributed on an "AS IS" BASIS,
kadonotakashi 0:8fdf9a60065b 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
kadonotakashi 0:8fdf9a60065b 13 * See the License for the specific language governing permissions and
kadonotakashi 0:8fdf9a60065b 14 * limitations under the License.
kadonotakashi 0:8fdf9a60065b 15 */
kadonotakashi 0:8fdf9a60065b 16
kadonotakashi 0:8fdf9a60065b 17 #include "us_ticker_api.h"
kadonotakashi 0:8fdf9a60065b 18
kadonotakashi 0:8fdf9a60065b 19 #if DEVICE_USTICKER
kadonotakashi 0:8fdf9a60065b 20
kadonotakashi 0:8fdf9a60065b 21 #include "sleep_api.h"
kadonotakashi 0:8fdf9a60065b 22 #include "mbed_assert.h"
kadonotakashi 0:8fdf9a60065b 23 #include "nu_modutil.h"
kadonotakashi 0:8fdf9a60065b 24 #include "nu_miscutil.h"
kadonotakashi 0:8fdf9a60065b 25
kadonotakashi 0:8fdf9a60065b 26 /* Micro seconds per second */
kadonotakashi 0:8fdf9a60065b 27 #define NU_US_PER_SEC 1000000
kadonotakashi 0:8fdf9a60065b 28 /* Timer clock per us_ticker tick */
kadonotakashi 0:8fdf9a60065b 29 #define NU_TMRCLK_PER_TICK 1
kadonotakashi 0:8fdf9a60065b 30 /* Timer clock per second */
kadonotakashi 0:8fdf9a60065b 31 #define NU_TMRCLK_PER_SEC (1000 * 1000)
kadonotakashi 0:8fdf9a60065b 32 /* Timer max counter bit size */
kadonotakashi 0:8fdf9a60065b 33 #define NU_TMR_MAXCNT_BITSIZE 24
kadonotakashi 0:8fdf9a60065b 34 /* Timer max counter */
kadonotakashi 0:8fdf9a60065b 35 #define NU_TMR_MAXCNT ((1 << NU_TMR_MAXCNT_BITSIZE) - 1)
kadonotakashi 0:8fdf9a60065b 36
kadonotakashi 0:8fdf9a60065b 37 static void tmr0_vec(void);
kadonotakashi 0:8fdf9a60065b 38
kadonotakashi 0:8fdf9a60065b 39 static const struct nu_modinit_s timer0_modinit = {TIMER_0, TMR0_MODULE, CLK_CLKSEL1_TMR0SEL_PCLK0, 0, TMR0_RST, TMR0_IRQn, (void *) tmr0_vec};
kadonotakashi 0:8fdf9a60065b 40
kadonotakashi 0:8fdf9a60065b 41 #define TIMER_MODINIT timer0_modinit
kadonotakashi 0:8fdf9a60065b 42
kadonotakashi 0:8fdf9a60065b 43 /* Track ticker status */
kadonotakashi 0:8fdf9a60065b 44 static volatile uint16_t ticker_inited = 0;
kadonotakashi 0:8fdf9a60065b 45
kadonotakashi 0:8fdf9a60065b 46 #define TMR_CMP_MIN 2
kadonotakashi 0:8fdf9a60065b 47 #define TMR_CMP_MAX 0xFFFFFFu
kadonotakashi 0:8fdf9a60065b 48
kadonotakashi 0:8fdf9a60065b 49 void us_ticker_init(void)
kadonotakashi 0:8fdf9a60065b 50 {
kadonotakashi 0:8fdf9a60065b 51 if (ticker_inited) {
kadonotakashi 0:8fdf9a60065b 52 /* By HAL spec, ticker_init allows the ticker to keep counting and disables the
kadonotakashi 0:8fdf9a60065b 53 * ticker interrupt. */
kadonotakashi 0:8fdf9a60065b 54 us_ticker_disable_interrupt();
kadonotakashi 0:8fdf9a60065b 55 return;
kadonotakashi 0:8fdf9a60065b 56 }
kadonotakashi 0:8fdf9a60065b 57 ticker_inited = 1;
kadonotakashi 0:8fdf9a60065b 58
kadonotakashi 0:8fdf9a60065b 59 // Reset IP
kadonotakashi 0:8fdf9a60065b 60 SYS_ResetModule(TIMER_MODINIT.rsetidx);
kadonotakashi 0:8fdf9a60065b 61
kadonotakashi 0:8fdf9a60065b 62 // Select IP clock source
kadonotakashi 0:8fdf9a60065b 63 CLK_SetModuleClock(TIMER_MODINIT.clkidx, TIMER_MODINIT.clksrc, TIMER_MODINIT.clkdiv);
kadonotakashi 0:8fdf9a60065b 64
kadonotakashi 0:8fdf9a60065b 65 // Enable IP clock
kadonotakashi 0:8fdf9a60065b 66 CLK_EnableModuleClock(TIMER_MODINIT.clkidx);
kadonotakashi 0:8fdf9a60065b 67
kadonotakashi 0:8fdf9a60065b 68 TIMER_T *timer_base = (TIMER_T *) NU_MODBASE(TIMER_MODINIT.modname);
kadonotakashi 0:8fdf9a60065b 69
kadonotakashi 0:8fdf9a60065b 70 // Timer for normal counter
kadonotakashi 0:8fdf9a60065b 71 uint32_t clk_timer = TIMER_GetModuleClock(timer_base);
kadonotakashi 0:8fdf9a60065b 72 uint32_t prescale_timer = clk_timer / NU_TMRCLK_PER_SEC - 1;
kadonotakashi 0:8fdf9a60065b 73 MBED_ASSERT((prescale_timer != (uint32_t) -1) && prescale_timer <= 127);
kadonotakashi 0:8fdf9a60065b 74 MBED_ASSERT((clk_timer % NU_TMRCLK_PER_SEC) == 0);
kadonotakashi 0:8fdf9a60065b 75 uint32_t cmp_timer = TMR_CMP_MAX;
kadonotakashi 0:8fdf9a60065b 76 MBED_ASSERT(cmp_timer >= TMR_CMP_MIN && cmp_timer <= TMR_CMP_MAX);
kadonotakashi 0:8fdf9a60065b 77 // NOTE: TIMER_CTL_CNTDATEN_Msk exists in NUC472, but not in M451. In M451, TIMER_CNT is updated continuously by default.
kadonotakashi 0:8fdf9a60065b 78 timer_base->CTL = TIMER_CONTINUOUS_MODE | prescale_timer/* | TIMER_CTL_CNTDATEN_Msk*/;
kadonotakashi 0:8fdf9a60065b 79 timer_base->CMP = cmp_timer;
kadonotakashi 0:8fdf9a60065b 80
kadonotakashi 0:8fdf9a60065b 81 NVIC_SetVector(TIMER_MODINIT.irq_n, (uint32_t) TIMER_MODINIT.var);
kadonotakashi 0:8fdf9a60065b 82
kadonotakashi 0:8fdf9a60065b 83 NVIC_DisableIRQ(TIMER_MODINIT.irq_n);
kadonotakashi 0:8fdf9a60065b 84
kadonotakashi 0:8fdf9a60065b 85 TIMER_EnableInt(timer_base);
kadonotakashi 0:8fdf9a60065b 86
kadonotakashi 0:8fdf9a60065b 87 TIMER_Start(timer_base);
kadonotakashi 0:8fdf9a60065b 88 /* Wait for timer to start counting and raise active flag */
kadonotakashi 0:8fdf9a60065b 89 while(! (timer_base->CTL & TIMER_CTL_ACTSTS_Msk));
kadonotakashi 0:8fdf9a60065b 90 }
kadonotakashi 0:8fdf9a60065b 91
kadonotakashi 0:8fdf9a60065b 92 void us_ticker_free(void)
kadonotakashi 0:8fdf9a60065b 93 {
kadonotakashi 0:8fdf9a60065b 94 /* Disable interrupt */
kadonotakashi 0:8fdf9a60065b 95 NVIC_DisableIRQ(TIMER_MODINIT.irq_n);
kadonotakashi 0:8fdf9a60065b 96
kadonotakashi 0:8fdf9a60065b 97 /* Disable IP clock */
kadonotakashi 0:8fdf9a60065b 98 CLK_DisableModuleClock(TIMER_MODINIT.clkidx);
kadonotakashi 0:8fdf9a60065b 99
kadonotakashi 0:8fdf9a60065b 100 ticker_inited = 0;
kadonotakashi 0:8fdf9a60065b 101 }
kadonotakashi 0:8fdf9a60065b 102
kadonotakashi 0:8fdf9a60065b 103 uint32_t us_ticker_read()
kadonotakashi 0:8fdf9a60065b 104 {
kadonotakashi 0:8fdf9a60065b 105 if (! ticker_inited) {
kadonotakashi 0:8fdf9a60065b 106 us_ticker_init();
kadonotakashi 0:8fdf9a60065b 107 }
kadonotakashi 0:8fdf9a60065b 108
kadonotakashi 0:8fdf9a60065b 109 TIMER_T *timer_base = (TIMER_T *) NU_MODBASE(TIMER_MODINIT.modname);
kadonotakashi 0:8fdf9a60065b 110
kadonotakashi 0:8fdf9a60065b 111 return (TIMER_GetCounter(timer_base) / NU_TMRCLK_PER_TICK);
kadonotakashi 0:8fdf9a60065b 112 }
kadonotakashi 0:8fdf9a60065b 113
kadonotakashi 0:8fdf9a60065b 114 void us_ticker_set_interrupt(timestamp_t timestamp)
kadonotakashi 0:8fdf9a60065b 115 {
kadonotakashi 0:8fdf9a60065b 116 /* Clear any previously pending interrupts */
kadonotakashi 0:8fdf9a60065b 117 us_ticker_clear_interrupt();
kadonotakashi 0:8fdf9a60065b 118 NVIC_ClearPendingIRQ(TIMER_MODINIT.irq_n);
kadonotakashi 0:8fdf9a60065b 119
kadonotakashi 0:8fdf9a60065b 120 /* In continuous mode, counter will be reset to zero with the following sequence:
kadonotakashi 0:8fdf9a60065b 121 * 1. Stop counting
kadonotakashi 0:8fdf9a60065b 122 * 2. Configure new CMP value
kadonotakashi 0:8fdf9a60065b 123 * 3. Restart counting
kadonotakashi 0:8fdf9a60065b 124 *
kadonotakashi 0:8fdf9a60065b 125 * This behavior is not what we want. To fix it, we could configure new CMP value
kadonotakashi 0:8fdf9a60065b 126 * without stopping counting first.
kadonotakashi 0:8fdf9a60065b 127 */
kadonotakashi 0:8fdf9a60065b 128 TIMER_T *timer_base = (TIMER_T *) NU_MODBASE(TIMER_MODINIT.modname);
kadonotakashi 0:8fdf9a60065b 129
kadonotakashi 0:8fdf9a60065b 130 /* NOTE: Because H/W timer requests min compare value, our implementation would have alarm delay of
kadonotakashi 0:8fdf9a60065b 131 * (TMR_CMP_MIN - interval_clk) clocks when interval_clk is between [1, TMR_CMP_MIN). */
kadonotakashi 0:8fdf9a60065b 132 uint32_t cmp_timer = timestamp * NU_TMRCLK_PER_TICK;
kadonotakashi 0:8fdf9a60065b 133 cmp_timer = NU_CLAMP(cmp_timer, TMR_CMP_MIN, TMR_CMP_MAX);
kadonotakashi 0:8fdf9a60065b 134 timer_base->CMP = cmp_timer;
kadonotakashi 0:8fdf9a60065b 135
kadonotakashi 0:8fdf9a60065b 136 /* We can call ticker_irq_handler now. */
kadonotakashi 0:8fdf9a60065b 137 NVIC_EnableIRQ(TIMER_MODINIT.irq_n);
kadonotakashi 0:8fdf9a60065b 138 }
kadonotakashi 0:8fdf9a60065b 139
kadonotakashi 0:8fdf9a60065b 140 void us_ticker_disable_interrupt(void)
kadonotakashi 0:8fdf9a60065b 141 {
kadonotakashi 0:8fdf9a60065b 142 /* We cannot call ticker_irq_handler now. */
kadonotakashi 0:8fdf9a60065b 143 NVIC_DisableIRQ(TIMER_MODINIT.irq_n);
kadonotakashi 0:8fdf9a60065b 144 }
kadonotakashi 0:8fdf9a60065b 145
kadonotakashi 0:8fdf9a60065b 146 void us_ticker_clear_interrupt(void)
kadonotakashi 0:8fdf9a60065b 147 {
kadonotakashi 0:8fdf9a60065b 148 TIMER_ClearIntFlag((TIMER_T *) NU_MODBASE(TIMER_MODINIT.modname));
kadonotakashi 0:8fdf9a60065b 149 }
kadonotakashi 0:8fdf9a60065b 150
kadonotakashi 0:8fdf9a60065b 151 void us_ticker_fire_interrupt(void)
kadonotakashi 0:8fdf9a60065b 152 {
kadonotakashi 0:8fdf9a60065b 153 // NOTE: This event was in the past. Set the interrupt as pending, but don't process it here.
kadonotakashi 0:8fdf9a60065b 154 // This prevents a recursive loop under heavy load which can lead to a stack overflow.
kadonotakashi 0:8fdf9a60065b 155 NVIC_SetPendingIRQ(TIMER_MODINIT.irq_n);
kadonotakashi 0:8fdf9a60065b 156
kadonotakashi 0:8fdf9a60065b 157 /* We can call ticker_irq_handler now. */
kadonotakashi 0:8fdf9a60065b 158 NVIC_EnableIRQ(TIMER_MODINIT.irq_n);
kadonotakashi 0:8fdf9a60065b 159 }
kadonotakashi 0:8fdf9a60065b 160
kadonotakashi 0:8fdf9a60065b 161 const ticker_info_t* us_ticker_get_info()
kadonotakashi 0:8fdf9a60065b 162 {
kadonotakashi 0:8fdf9a60065b 163 static const ticker_info_t info = {
kadonotakashi 0:8fdf9a60065b 164 NU_TMRCLK_PER_SEC / NU_TMRCLK_PER_TICK,
kadonotakashi 0:8fdf9a60065b 165 NU_TMR_MAXCNT_BITSIZE
kadonotakashi 0:8fdf9a60065b 166 };
kadonotakashi 0:8fdf9a60065b 167 return &info;
kadonotakashi 0:8fdf9a60065b 168 }
kadonotakashi 0:8fdf9a60065b 169
kadonotakashi 0:8fdf9a60065b 170 static void tmr0_vec(void)
kadonotakashi 0:8fdf9a60065b 171 {
kadonotakashi 0:8fdf9a60065b 172 us_ticker_clear_interrupt();
kadonotakashi 0:8fdf9a60065b 173
kadonotakashi 0:8fdf9a60065b 174 // NOTE: us_ticker_set_interrupt() may get called in us_ticker_irq_handler();
kadonotakashi 0:8fdf9a60065b 175 us_ticker_irq_handler();
kadonotakashi 0:8fdf9a60065b 176 }
kadonotakashi 0:8fdf9a60065b 177
kadonotakashi 0:8fdf9a60065b 178 #endif