takashi kadono / Mbed OS Nucleo_446

Dependencies:   ssd1331

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers mbed_itm_api.c Source File

mbed_itm_api.c

00001 /* mbed Microcontroller Library
00002  * Copyright (c) 2017 ARM Limited
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *     http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 
00017 #if defined(DEVICE_ITM)
00018 
00019 #include "hal/itm_api.h"
00020 #include "cmsis.h"
00021 
00022 #include <stdbool.h>
00023 
00024 #ifndef ITM_STIM_FIFOREADY_Msk
00025 #define ITM_STIM_FIFOREADY_Msk 1
00026 #endif
00027 
00028 #define ITM_ENABLE_WRITE 0xC5ACCE55
00029 
00030 #define SWO_NRZ 0x02
00031 #define SWO_STIMULUS_PORT 0x01
00032 
00033 void mbed_itm_init(void)
00034 {
00035     static bool do_init = true;
00036 
00037     if (do_init) {
00038         do_init = false;
00039 
00040         itm_init();
00041 
00042         /* Enable write access to ITM registers. */
00043         ITM->LAR  = ITM_ENABLE_WRITE;
00044 
00045         /* Trace Port Interface Selected Pin Protocol Register. */
00046         TPI->SPPR = (SWO_NRZ << TPI_SPPR_TXMODE_Pos);
00047 
00048         /* Trace Port Interface Formatter and Flush Control Register */
00049         TPI->FFCR = (1 << TPI_FFCR_TrigIn_Pos);
00050 
00051         /* Data Watchpoint and Trace Control Register */
00052         DWT->CTRL = (1 << DWT_CTRL_CYCTAP_Pos)       |
00053                     (0xF << DWT_CTRL_POSTINIT_Pos)   |
00054                     (0xF << DWT_CTRL_POSTPRESET_Pos) |
00055                     (1 << DWT_CTRL_CYCCNTENA_Pos);
00056 
00057         /* Trace Privilege Register.
00058          * Disable access to trace channel configuration from non-privileged mode.
00059          */
00060         ITM->TPR  = 0x0;
00061 
00062         /* Trace Control Register */
00063         ITM->TCR  = (1 << ITM_TCR_TraceBusID_Pos) |
00064                     (1 << ITM_TCR_DWTENA_Pos)     |
00065                     (1 << ITM_TCR_SYNCENA_Pos)    |
00066                     (1 << ITM_TCR_ITMENA_Pos);
00067 
00068         /* Trace Enable Register */
00069         ITM->TER = SWO_STIMULUS_PORT;
00070     }
00071 }
00072 
00073 static void itm_out8(uint32_t port, uint8_t data)
00074 {
00075     /* Wait until port is available */
00076     while ((ITM->PORT[port].u32 & ITM_STIM_FIFOREADY_Msk) == 0) {
00077         __NOP();
00078     }
00079 
00080     /* write data to port */
00081     ITM->PORT[port].u8 = data;
00082 }
00083 
00084 static void itm_out32(uint32_t port, uint32_t data)
00085 {
00086     /* Wait until port is available */
00087     while ((ITM->PORT[port].u32 & ITM_STIM_FIFOREADY_Msk) == 0) {
00088         __NOP();
00089     }
00090 
00091     /* write data to port */
00092     ITM->PORT[port].u32 = data;
00093 }
00094 
00095 uint32_t mbed_itm_send(uint32_t port, uint32_t data)
00096 {
00097     /* Check if ITM and port is enabled */
00098     if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) &&      /* ITM enabled */
00099             ((ITM->TER & (1UL << port)) != 0UL)) {       /* ITM Port enabled */
00100         itm_out32(port, data);
00101     }
00102 
00103     return data;
00104 }
00105 
00106 void mbed_itm_send_block(uint32_t port, const void *data, size_t len)
00107 {
00108     const char *ptr = data;
00109 
00110     /* Check if ITM and port is enabled */
00111     if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) &&      /* ITM enabled */
00112             ((ITM->TER & (1UL << port)) != 0UL)) {       /* ITM Port enabled */
00113         /* Output single byte at a time until data is aligned */
00114         while ((((uintptr_t) ptr) & 3) && len != 0) {
00115             itm_out8(port, *ptr++);
00116             len--;
00117         }
00118 
00119         /* Output bulk of data one word at a time */
00120         while (len >= 4) {
00121             itm_out32(port, *(const uint32_t *) ptr);
00122             ptr += 4;
00123             len -= 4;
00124         }
00125 
00126         /* Output any trailing bytes */
00127         while (len != 0) {
00128             itm_out8(port, *ptr++);
00129             len--;
00130         }
00131     }
00132 }
00133 #endif // defined(DEVICE_ITM)