Color Oled(SSD1331) connect to STMicroelectronics Nucleo-F466

Dependencies:   ssd1331

Committer:
kadonotakashi
Date:
Thu Oct 11 02:27:46 2018 +0000
Revision:
3:f3764f852aa8
Parent:
0:8fdf9a60065b
Nucreo 446 + SSD1331 test version;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kadonotakashi 0:8fdf9a60065b 1 /* mbed Microcontroller Library
kadonotakashi 0:8fdf9a60065b 2 * Copyright (c) 2006-2013 ARM Limited
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 #include "serial_api.h"
kadonotakashi 0:8fdf9a60065b 17
kadonotakashi 0:8fdf9a60065b 18 #if DEVICE_SERIAL
kadonotakashi 0:8fdf9a60065b 19
kadonotakashi 0:8fdf9a60065b 20 // math.h required for floating point operations for baud rate calculation
kadonotakashi 0:8fdf9a60065b 21 #include <math.h>
kadonotakashi 0:8fdf9a60065b 22 #include "mbed_assert.h"
kadonotakashi 0:8fdf9a60065b 23
kadonotakashi 0:8fdf9a60065b 24 #include <string.h>
kadonotakashi 0:8fdf9a60065b 25
kadonotakashi 0:8fdf9a60065b 26 #include "cmsis.h"
kadonotakashi 0:8fdf9a60065b 27 #include "pinmap.h"
kadonotakashi 0:8fdf9a60065b 28 #include "fsl_lpuart.h"
kadonotakashi 0:8fdf9a60065b 29 #include "peripheral_clock_defines.h"
kadonotakashi 0:8fdf9a60065b 30 #include "PeripheralPins.h"
kadonotakashi 0:8fdf9a60065b 31 #include "fsl_clock_config.h"
kadonotakashi 0:8fdf9a60065b 32
kadonotakashi 0:8fdf9a60065b 33 static uint32_t serial_irq_ids[FSL_FEATURE_SOC_LPUART_COUNT] = {0};
kadonotakashi 0:8fdf9a60065b 34 static uart_irq_handler irq_handler;
kadonotakashi 0:8fdf9a60065b 35 /* Array of UART peripheral base address. */
kadonotakashi 0:8fdf9a60065b 36 static LPUART_Type *const uart_addrs[] = LPUART_BASE_PTRS;
kadonotakashi 0:8fdf9a60065b 37 /* Array of LPUART bus clock frequencies */
kadonotakashi 0:8fdf9a60065b 38 static clock_name_t const uart_clocks[] = LPUART_CLOCK_FREQS;
kadonotakashi 0:8fdf9a60065b 39
kadonotakashi 0:8fdf9a60065b 40 int stdio_uart_inited = 0;
kadonotakashi 0:8fdf9a60065b 41 serial_t stdio_uart;
kadonotakashi 0:8fdf9a60065b 42
kadonotakashi 0:8fdf9a60065b 43 void serial_init(serial_t *obj, PinName tx, PinName rx)
kadonotakashi 0:8fdf9a60065b 44 {
kadonotakashi 0:8fdf9a60065b 45 uint32_t uart_tx = pinmap_peripheral(tx, PinMap_UART_TX);
kadonotakashi 0:8fdf9a60065b 46 uint32_t uart_rx = pinmap_peripheral(rx, PinMap_UART_RX);
kadonotakashi 0:8fdf9a60065b 47 obj->index = pinmap_merge(uart_tx, uart_rx);
kadonotakashi 0:8fdf9a60065b 48 MBED_ASSERT((int)obj->index != NC);
kadonotakashi 0:8fdf9a60065b 49
kadonotakashi 0:8fdf9a60065b 50 /* Set the LPUART clock source */
kadonotakashi 0:8fdf9a60065b 51 if (obj->index == LPUART_0) {
kadonotakashi 0:8fdf9a60065b 52 CLOCK_SetLpuart0Clock(1U);
kadonotakashi 0:8fdf9a60065b 53 } else {
kadonotakashi 0:8fdf9a60065b 54 CLOCK_SetLpuart1Clock(1U);
kadonotakashi 0:8fdf9a60065b 55 }
kadonotakashi 0:8fdf9a60065b 56
kadonotakashi 0:8fdf9a60065b 57 lpuart_config_t config;
kadonotakashi 0:8fdf9a60065b 58 LPUART_GetDefaultConfig(&config);
kadonotakashi 0:8fdf9a60065b 59 config.baudRate_Bps = 9600;
kadonotakashi 0:8fdf9a60065b 60 config.enableTx = false;
kadonotakashi 0:8fdf9a60065b 61 config.enableRx = false;
kadonotakashi 0:8fdf9a60065b 62
kadonotakashi 0:8fdf9a60065b 63 LPUART_Init(uart_addrs[obj->index], &config, CLOCK_GetFreq(uart_clocks[obj->index]));
kadonotakashi 0:8fdf9a60065b 64
kadonotakashi 0:8fdf9a60065b 65 pinmap_pinout(tx, PinMap_UART_TX);
kadonotakashi 0:8fdf9a60065b 66 pinmap_pinout(rx, PinMap_UART_RX);
kadonotakashi 0:8fdf9a60065b 67
kadonotakashi 0:8fdf9a60065b 68 if (tx != NC) {
kadonotakashi 0:8fdf9a60065b 69 LPUART_EnableTx(uart_addrs[obj->index], true);
kadonotakashi 0:8fdf9a60065b 70 pin_mode(tx, PullUp);
kadonotakashi 0:8fdf9a60065b 71 }
kadonotakashi 0:8fdf9a60065b 72 if (rx != NC) {
kadonotakashi 0:8fdf9a60065b 73 LPUART_EnableRx(uart_addrs[obj->index], true);
kadonotakashi 0:8fdf9a60065b 74 pin_mode(rx, PullUp);
kadonotakashi 0:8fdf9a60065b 75 }
kadonotakashi 0:8fdf9a60065b 76
kadonotakashi 0:8fdf9a60065b 77 if (obj->index == STDIO_UART) {
kadonotakashi 0:8fdf9a60065b 78 stdio_uart_inited = 1;
kadonotakashi 0:8fdf9a60065b 79 memcpy(&stdio_uart, obj, sizeof(serial_t));
kadonotakashi 0:8fdf9a60065b 80 }
kadonotakashi 0:8fdf9a60065b 81 }
kadonotakashi 0:8fdf9a60065b 82
kadonotakashi 0:8fdf9a60065b 83 void serial_free(serial_t *obj)
kadonotakashi 0:8fdf9a60065b 84 {
kadonotakashi 0:8fdf9a60065b 85 LPUART_Deinit(uart_addrs[obj->index]);
kadonotakashi 0:8fdf9a60065b 86 serial_irq_ids[obj->index] = 0;
kadonotakashi 0:8fdf9a60065b 87 }
kadonotakashi 0:8fdf9a60065b 88
kadonotakashi 0:8fdf9a60065b 89 void serial_baud(serial_t *obj, int baudrate)
kadonotakashi 0:8fdf9a60065b 90 {
kadonotakashi 0:8fdf9a60065b 91 LPUART_SetBaudRate(uart_addrs[obj->index], (uint32_t)baudrate, CLOCK_GetFreq(uart_clocks[obj->index]));
kadonotakashi 0:8fdf9a60065b 92 }
kadonotakashi 0:8fdf9a60065b 93
kadonotakashi 0:8fdf9a60065b 94 void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits)
kadonotakashi 0:8fdf9a60065b 95 {
kadonotakashi 0:8fdf9a60065b 96 LPUART_Type *base = uart_addrs[obj->index];
kadonotakashi 0:8fdf9a60065b 97 uint8_t temp;
kadonotakashi 0:8fdf9a60065b 98 /* Set bit count and parity mode. */
kadonotakashi 0:8fdf9a60065b 99 temp = base->CTRL & ~(LPUART_CTRL_PE_MASK | LPUART_CTRL_PT_MASK | LPUART_CTRL_M_MASK);
kadonotakashi 0:8fdf9a60065b 100 if (parity != ParityNone)
kadonotakashi 0:8fdf9a60065b 101 {
kadonotakashi 0:8fdf9a60065b 102 /* Enable Parity */
kadonotakashi 0:8fdf9a60065b 103 temp |= (LPUART_CTRL_PE_MASK | LPUART_CTRL_M_MASK);
kadonotakashi 0:8fdf9a60065b 104 if (parity == ParityOdd) {
kadonotakashi 0:8fdf9a60065b 105 temp |= LPUART_CTRL_PT_MASK;
kadonotakashi 0:8fdf9a60065b 106 } else if (parity == ParityEven) {
kadonotakashi 0:8fdf9a60065b 107 // PT=0 so nothing more to do
kadonotakashi 0:8fdf9a60065b 108 } else {
kadonotakashi 0:8fdf9a60065b 109 // Hardware does not support forced parity
kadonotakashi 0:8fdf9a60065b 110 MBED_ASSERT(0);
kadonotakashi 0:8fdf9a60065b 111 }
kadonotakashi 0:8fdf9a60065b 112 }
kadonotakashi 0:8fdf9a60065b 113 base->CTRL = temp;
kadonotakashi 0:8fdf9a60065b 114
kadonotakashi 0:8fdf9a60065b 115 #if defined(FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT) && FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT
kadonotakashi 0:8fdf9a60065b 116 /* set stop bit per char */
kadonotakashi 0:8fdf9a60065b 117 temp = base->BAUD & ~LPUART_BAUD_SBNS_MASK;
kadonotakashi 0:8fdf9a60065b 118 base->BAUD = temp | LPUART_BAUD_SBNS((uint8_t)--stop_bits);
kadonotakashi 0:8fdf9a60065b 119 #endif
kadonotakashi 0:8fdf9a60065b 120 }
kadonotakashi 0:8fdf9a60065b 121
kadonotakashi 0:8fdf9a60065b 122 /******************************************************************************
kadonotakashi 0:8fdf9a60065b 123 * INTERRUPTS HANDLING
kadonotakashi 0:8fdf9a60065b 124 ******************************************************************************/
kadonotakashi 0:8fdf9a60065b 125 static inline void uart_irq(uint32_t transmit_empty, uint32_t receive_full, uint32_t index)
kadonotakashi 0:8fdf9a60065b 126 {
kadonotakashi 0:8fdf9a60065b 127 LPUART_Type *base = uart_addrs[index];
kadonotakashi 0:8fdf9a60065b 128
kadonotakashi 0:8fdf9a60065b 129 /* If RX overrun. */
kadonotakashi 0:8fdf9a60065b 130 if (LPUART_STAT_OR_MASK & base->STAT)
kadonotakashi 0:8fdf9a60065b 131 {
kadonotakashi 0:8fdf9a60065b 132 /* Read base->D, otherwise the RX does not work. */
kadonotakashi 0:8fdf9a60065b 133 (void)base->DATA;
kadonotakashi 0:8fdf9a60065b 134 LPUART_ClearStatusFlags(base, kLPUART_RxOverrunFlag);
kadonotakashi 0:8fdf9a60065b 135 }
kadonotakashi 0:8fdf9a60065b 136
kadonotakashi 0:8fdf9a60065b 137 if (serial_irq_ids[index] != 0) {
kadonotakashi 0:8fdf9a60065b 138 if (transmit_empty)
kadonotakashi 0:8fdf9a60065b 139 irq_handler(serial_irq_ids[index], TxIrq);
kadonotakashi 0:8fdf9a60065b 140
kadonotakashi 0:8fdf9a60065b 141 if (receive_full)
kadonotakashi 0:8fdf9a60065b 142 irq_handler(serial_irq_ids[index], RxIrq);
kadonotakashi 0:8fdf9a60065b 143 }
kadonotakashi 0:8fdf9a60065b 144 }
kadonotakashi 0:8fdf9a60065b 145
kadonotakashi 0:8fdf9a60065b 146 void uart0_irq()
kadonotakashi 0:8fdf9a60065b 147 {
kadonotakashi 0:8fdf9a60065b 148 uint32_t status_flags = LPUART0->STAT;
kadonotakashi 0:8fdf9a60065b 149 uart_irq((status_flags & kLPUART_TxDataRegEmptyFlag), (status_flags & kLPUART_RxDataRegFullFlag), 0);
kadonotakashi 0:8fdf9a60065b 150 }
kadonotakashi 0:8fdf9a60065b 151
kadonotakashi 0:8fdf9a60065b 152 void uart1_irq()
kadonotakashi 0:8fdf9a60065b 153 {
kadonotakashi 0:8fdf9a60065b 154 uint32_t status_flags = LPUART1->STAT;
kadonotakashi 0:8fdf9a60065b 155 uart_irq((status_flags & kLPUART_TxDataRegEmptyFlag), (status_flags & kLPUART_RxDataRegFullFlag), 1);
kadonotakashi 0:8fdf9a60065b 156 }
kadonotakashi 0:8fdf9a60065b 157
kadonotakashi 0:8fdf9a60065b 158 void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id)
kadonotakashi 0:8fdf9a60065b 159 {
kadonotakashi 0:8fdf9a60065b 160 irq_handler = handler;
kadonotakashi 0:8fdf9a60065b 161 serial_irq_ids[obj->index] = id;
kadonotakashi 0:8fdf9a60065b 162 }
kadonotakashi 0:8fdf9a60065b 163
kadonotakashi 0:8fdf9a60065b 164 void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable)
kadonotakashi 0:8fdf9a60065b 165 {
kadonotakashi 0:8fdf9a60065b 166 IRQn_Type uart_irqs[] = LPUART_RX_TX_IRQS;
kadonotakashi 0:8fdf9a60065b 167 uint32_t vector = 0;
kadonotakashi 0:8fdf9a60065b 168
kadonotakashi 0:8fdf9a60065b 169 switch (obj->index) {
kadonotakashi 0:8fdf9a60065b 170 case 0:
kadonotakashi 0:8fdf9a60065b 171 vector = (uint32_t)&uart0_irq;
kadonotakashi 0:8fdf9a60065b 172 break;
kadonotakashi 0:8fdf9a60065b 173 case 1:
kadonotakashi 0:8fdf9a60065b 174 vector = (uint32_t)&uart1_irq;
kadonotakashi 0:8fdf9a60065b 175 break;
kadonotakashi 0:8fdf9a60065b 176 default:
kadonotakashi 0:8fdf9a60065b 177 break;
kadonotakashi 0:8fdf9a60065b 178 }
kadonotakashi 0:8fdf9a60065b 179
kadonotakashi 0:8fdf9a60065b 180 if (enable) {
kadonotakashi 0:8fdf9a60065b 181 switch (irq) {
kadonotakashi 0:8fdf9a60065b 182 case RxIrq:
kadonotakashi 0:8fdf9a60065b 183 LPUART_EnableInterrupts(uart_addrs[obj->index], kLPUART_RxDataRegFullInterruptEnable);
kadonotakashi 0:8fdf9a60065b 184 break;
kadonotakashi 0:8fdf9a60065b 185 case TxIrq:
kadonotakashi 0:8fdf9a60065b 186 LPUART_EnableInterrupts(uart_addrs[obj->index], kLPUART_TxDataRegEmptyInterruptEnable);
kadonotakashi 0:8fdf9a60065b 187 break;
kadonotakashi 0:8fdf9a60065b 188 default:
kadonotakashi 0:8fdf9a60065b 189 break;
kadonotakashi 0:8fdf9a60065b 190 }
kadonotakashi 0:8fdf9a60065b 191 NVIC_SetVector(uart_irqs[obj->index], vector);
kadonotakashi 0:8fdf9a60065b 192 NVIC_EnableIRQ(uart_irqs[obj->index]);
kadonotakashi 0:8fdf9a60065b 193
kadonotakashi 0:8fdf9a60065b 194 } else { // disable
kadonotakashi 0:8fdf9a60065b 195 int all_disabled = 0;
kadonotakashi 0:8fdf9a60065b 196 SerialIrq other_irq = (irq == RxIrq) ? (TxIrq) : (RxIrq);
kadonotakashi 0:8fdf9a60065b 197 switch (irq) {
kadonotakashi 0:8fdf9a60065b 198 case RxIrq:
kadonotakashi 0:8fdf9a60065b 199 LPUART_DisableInterrupts(uart_addrs[obj->index], kLPUART_RxDataRegFullInterruptEnable);
kadonotakashi 0:8fdf9a60065b 200 break;
kadonotakashi 0:8fdf9a60065b 201 case TxIrq:
kadonotakashi 0:8fdf9a60065b 202 LPUART_DisableInterrupts(uart_addrs[obj->index], kLPUART_TxDataRegEmptyInterruptEnable);
kadonotakashi 0:8fdf9a60065b 203 break;
kadonotakashi 0:8fdf9a60065b 204 default:
kadonotakashi 0:8fdf9a60065b 205 break;
kadonotakashi 0:8fdf9a60065b 206 }
kadonotakashi 0:8fdf9a60065b 207 switch (other_irq) {
kadonotakashi 0:8fdf9a60065b 208 case RxIrq:
kadonotakashi 0:8fdf9a60065b 209 all_disabled = ((LPUART_GetEnabledInterrupts(uart_addrs[obj->index]) & kLPUART_RxDataRegFullInterruptEnable) == 0);
kadonotakashi 0:8fdf9a60065b 210 break;
kadonotakashi 0:8fdf9a60065b 211 case TxIrq:
kadonotakashi 0:8fdf9a60065b 212 all_disabled = ((LPUART_GetEnabledInterrupts(uart_addrs[obj->index]) & kLPUART_TxDataRegEmptyInterruptEnable) == 0);
kadonotakashi 0:8fdf9a60065b 213 break;
kadonotakashi 0:8fdf9a60065b 214 default:
kadonotakashi 0:8fdf9a60065b 215 break;
kadonotakashi 0:8fdf9a60065b 216 }
kadonotakashi 0:8fdf9a60065b 217 if (all_disabled)
kadonotakashi 0:8fdf9a60065b 218 NVIC_DisableIRQ(uart_irqs[obj->index]);
kadonotakashi 0:8fdf9a60065b 219 }
kadonotakashi 0:8fdf9a60065b 220 }
kadonotakashi 0:8fdf9a60065b 221
kadonotakashi 0:8fdf9a60065b 222 int serial_getc(serial_t *obj)
kadonotakashi 0:8fdf9a60065b 223 {
kadonotakashi 0:8fdf9a60065b 224 uint8_t data;
kadonotakashi 0:8fdf9a60065b 225
kadonotakashi 0:8fdf9a60065b 226 LPUART_ReadBlocking(uart_addrs[obj->index], &data, 1);
kadonotakashi 0:8fdf9a60065b 227 return data;
kadonotakashi 0:8fdf9a60065b 228 }
kadonotakashi 0:8fdf9a60065b 229
kadonotakashi 0:8fdf9a60065b 230 void serial_putc(serial_t *obj, int c)
kadonotakashi 0:8fdf9a60065b 231 {
kadonotakashi 0:8fdf9a60065b 232 while (!serial_writable(obj));
kadonotakashi 0:8fdf9a60065b 233 LPUART_WriteByte(uart_addrs[obj->index], (uint8_t)c);
kadonotakashi 0:8fdf9a60065b 234 }
kadonotakashi 0:8fdf9a60065b 235
kadonotakashi 0:8fdf9a60065b 236 int serial_readable(serial_t *obj)
kadonotakashi 0:8fdf9a60065b 237 {
kadonotakashi 0:8fdf9a60065b 238 uint32_t status_flags = LPUART_GetStatusFlags(uart_addrs[obj->index]);
kadonotakashi 0:8fdf9a60065b 239 if (status_flags & kLPUART_RxOverrunFlag)
kadonotakashi 0:8fdf9a60065b 240 LPUART_ClearStatusFlags(uart_addrs[obj->index], kLPUART_RxOverrunFlag);
kadonotakashi 0:8fdf9a60065b 241 return (status_flags & kLPUART_RxDataRegFullFlag);
kadonotakashi 0:8fdf9a60065b 242 }
kadonotakashi 0:8fdf9a60065b 243
kadonotakashi 0:8fdf9a60065b 244 int serial_writable(serial_t *obj)
kadonotakashi 0:8fdf9a60065b 245 {
kadonotakashi 0:8fdf9a60065b 246 uint32_t status_flags = LPUART_GetStatusFlags(uart_addrs[obj->index]);
kadonotakashi 0:8fdf9a60065b 247 if (status_flags & kLPUART_RxOverrunFlag)
kadonotakashi 0:8fdf9a60065b 248 LPUART_ClearStatusFlags(uart_addrs[obj->index], kLPUART_RxOverrunFlag);
kadonotakashi 0:8fdf9a60065b 249 return (status_flags & kLPUART_TxDataRegEmptyFlag);
kadonotakashi 0:8fdf9a60065b 250 }
kadonotakashi 0:8fdf9a60065b 251
kadonotakashi 0:8fdf9a60065b 252 void serial_clear(serial_t *obj)
kadonotakashi 0:8fdf9a60065b 253 {
kadonotakashi 0:8fdf9a60065b 254 }
kadonotakashi 0:8fdf9a60065b 255
kadonotakashi 0:8fdf9a60065b 256 void serial_pinout_tx(PinName tx)
kadonotakashi 0:8fdf9a60065b 257 {
kadonotakashi 0:8fdf9a60065b 258 pinmap_pinout(tx, PinMap_UART_TX);
kadonotakashi 0:8fdf9a60065b 259 }
kadonotakashi 0:8fdf9a60065b 260
kadonotakashi 0:8fdf9a60065b 261 void serial_break_set(serial_t *obj)
kadonotakashi 0:8fdf9a60065b 262 {
kadonotakashi 0:8fdf9a60065b 263 uart_addrs[obj->index]->CTRL |= LPUART_CTRL_SBK_MASK;
kadonotakashi 0:8fdf9a60065b 264 }
kadonotakashi 0:8fdf9a60065b 265
kadonotakashi 0:8fdf9a60065b 266 void serial_break_clear(serial_t *obj)
kadonotakashi 0:8fdf9a60065b 267 {
kadonotakashi 0:8fdf9a60065b 268 uart_addrs[obj->index]->CTRL &= ~LPUART_CTRL_SBK_MASK;
kadonotakashi 0:8fdf9a60065b 269 }
kadonotakashi 0:8fdf9a60065b 270
kadonotakashi 0:8fdf9a60065b 271 #endif