Repository: incubator-mynewt-larva Updated Branches: refs/heads/master d4e843a65 -> a54dc9f15
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/826d3a57/hw/mcu/nordic/nrf51xxx/include/mcu/nrf51_deprecated.h ---------------------------------------------------------------------- diff --git a/hw/mcu/nordic/nrf51xxx/include/mcu/nrf51_deprecated.h b/hw/mcu/nordic/nrf51xxx/include/mcu/nrf51_deprecated.h new file mode 100755 index 0000000..70ac836 --- /dev/null +++ b/hw/mcu/nordic/nrf51xxx/include/mcu/nrf51_deprecated.h @@ -0,0 +1,454 @@ +/** + * Copyright (c) 2016 Runtime Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* Copyright (c) 2015, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef NRF51_DEPRECATED_H +#define NRF51_DEPRECATED_H + +/*lint ++flb "Enter library region */ + +/* This file is given to prevent your SW from not compiling with the updates made to nrf51.h and + * nrf51_bitfields.h. The macros defined in this file were available previously. Do not use these + * macros on purpose. Use the ones defined in nrf51.h and nrf51_bitfields.h instead. + */ + +/* NVMC */ +/* The register ERASEPROTECTEDPAGE is called ERASEPCR0 in the documentation. */ +#define ERASEPROTECTEDPAGE ERASEPCR0 + + +/* LPCOMP */ +/* The interrupt ISR was renamed. Adding old name to the macros. */ +#define LPCOMP_COMP_IRQHandler LPCOMP_IRQHandler +#define LPCOMP_COMP_IRQn LPCOMP_IRQn + + +/* MPU */ +/* The field MPU.PERR0.LPCOMP_COMP was renamed. Added into deprecated in case somebody was using the macros defined for it. */ +#define MPU_PERR0_LPCOMP_COMP_Pos MPU_PERR0_LPCOMP_Pos +#define MPU_PERR0_LPCOMP_COMP_Msk MPU_PERR0_LPCOMP_Msk +#define MPU_PERR0_LPCOMP_COMP_InRegion1 MPU_PERR0_LPCOMP_InRegion1 +#define MPU_PERR0_LPCOMP_COMP_InRegion0 MPU_PERR0_LPCOMP_InRegion0 + + +/* POWER */ +/* The field POWER.RAMON.OFFRAM3 was eliminated. Added into deprecated in case somebody was using the macros defined for it. */ +#define POWER_RAMON_OFFRAM3_Pos (19UL) +#define POWER_RAMON_OFFRAM3_Msk (0x1UL << POWER_RAMON_OFFRAM3_Pos) +#define POWER_RAMON_OFFRAM3_RAM3Off (0UL) +#define POWER_RAMON_OFFRAM3_RAM3On (1UL) +/* The field POWER.RAMON.OFFRAM2 was eliminated. Added into deprecated in case somebody was using the macros defined for it. */ +#define POWER_RAMON_OFFRAM2_Pos (18UL) +#define POWER_RAMON_OFFRAM2_Msk (0x1UL << POWER_RAMON_OFFRAM2_Pos) +#define POWER_RAMON_OFFRAM2_RAM2Off (0UL) +#define POWER_RAMON_OFFRAM2_RAM2On (1UL) +/* The field POWER.RAMON.ONRAM3 was eliminated. Added into deprecated in case somebody was using the macros defined for it. */ +#define POWER_RAMON_ONRAM3_Pos (3UL) +#define POWER_RAMON_ONRAM3_Msk (0x1UL << POWER_RAMON_ONRAM3_Pos) +#define POWER_RAMON_ONRAM3_RAM3Off (0UL) +#define POWER_RAMON_ONRAM3_RAM3On (1UL) +/* The field POWER.RAMON.ONRAM2 was eliminated. Added into deprecated in case somebody was using the macros defined for it. */ +#define POWER_RAMON_ONRAM2_Pos (2UL) +#define POWER_RAMON_ONRAM2_Msk (0x1UL << POWER_RAMON_ONRAM2_Pos) +#define POWER_RAMON_ONRAM2_RAM2Off (0UL) +#define POWER_RAMON_ONRAM2_RAM2On (1UL) + + +/* RADIO */ +/* The enumerated value RADIO.TXPOWER.TXPOWER.Neg40dBm was renamed. Added into deprecated with the new macro name. */ +#define RADIO_TXPOWER_TXPOWER_Neg40dBm RADIO_TXPOWER_TXPOWER_Neg30dBm +/* The name of the field SKIPADDR was corrected. Old macros added for compatibility. */ +#define RADIO_CRCCNF_SKIP_ADDR_Pos RADIO_CRCCNF_SKIPADDR_Pos +#define RADIO_CRCCNF_SKIP_ADDR_Msk RADIO_CRCCNF_SKIPADDR_Msk +#define RADIO_CRCCNF_SKIP_ADDR_Include RADIO_CRCCNF_SKIPADDR_Include +#define RADIO_CRCCNF_SKIP_ADDR_Skip RADIO_CRCCNF_SKIPADDR_Skip +/* The name of the field PLLLOCK was corrected. Old macros added for compatibility. */ +#define RADIO_TEST_PLL_LOCK_Pos RADIO_TEST_PLLLOCK_Pos +#define RADIO_TEST_PLL_LOCK_Msk RADIO_TEST_PLLLOCK_Msk +#define RADIO_TEST_PLL_LOCK_Disabled RADIO_TEST_PLLLOCK_Disabled +#define RADIO_TEST_PLL_LOCK_Enabled RADIO_TEST_PLLLOCK_Enabled +/* The name of the field CONSTCARRIER was corrected. Old macros added for compatibility. */ +#define RADIO_TEST_CONST_CARRIER_Pos RADIO_TEST_CONSTCARRIER_Pos +#define RADIO_TEST_CONST_CARRIER_Msk RADIO_TEST_CONSTCARRIER_Msk +#define RADIO_TEST_CONST_CARRIER_Disabled RADIO_TEST_CONSTCARRIER_Disabled +#define RADIO_TEST_CONST_CARRIER_Enabled RADIO_TEST_CONSTCARRIER_Enabled + + +/* FICR */ +/* The registers FICR.SIZERAMBLOCK0, FICR.SIZERAMBLOCK1, FICR.SIZERAMBLOCK2 and FICR.SIZERAMBLOCK3 were renamed into an array. */ +#define SIZERAMBLOCK0 SIZERAMBLOCKS +#define SIZERAMBLOCK1 SIZERAMBLOCKS +#define SIZERAMBLOCK2 SIZERAMBLOCK[2] /*!< Note that this macro will disapear when SIZERAMBLOCK array is eliminated. SIZERAMBLOCK is a deprecated array. */ +#define SIZERAMBLOCK3 SIZERAMBLOCK[3] /*!< Note that this macro will disapear when SIZERAMBLOCK array is eliminated. SIZERAMBLOCK is a deprecated array. */ +/* The registers FICR.DEVICEID0 and FICR.DEVICEID1 were renamed into an array. */ +#define DEVICEID0 DEVICEID[0] +#define DEVICEID1 DEVICEID[1] +/* The registers FICR.ER0, FICR.ER1, FICR.ER2 and FICR.ER3 were renamed into an array. */ +#define ER0 ER[0] +#define ER1 ER[1] +#define ER2 ER[2] +#define ER3 ER[3] +/* The registers FICR.IR0, FICR.IR1, FICR.IR2 and FICR.IR3 were renamed into an array. */ +#define IR0 IR[0] +#define IR1 IR[1] +#define IR2 IR[2] +#define IR3 IR[3] +/* The registers FICR.DEVICEADDR0 and FICR.DEVICEADDR1 were renamed into an array. */ +#define DEVICEADDR0 DEVICEADDR[0] +#define DEVICEADDR1 DEVICEADDR[1] + + +/* PPI */ +/* The tasks PPI.TASKS_CHGxEN and PPI.TASKS_CHGxDIS were renamed into an array of structs. */ +#define TASKS_CHG0EN TASKS_CHG[0].EN +#define TASKS_CHG0DIS TASKS_CHG[0].DIS +#define TASKS_CHG1EN TASKS_CHG[1].EN +#define TASKS_CHG1DIS TASKS_CHG[1].DIS +#define TASKS_CHG2EN TASKS_CHG[2].EN +#define TASKS_CHG2DIS TASKS_CHG[2].DIS +#define TASKS_CHG3EN TASKS_CHG[3].EN +#define TASKS_CHG3DIS TASKS_CHG[3].DIS +/* The registers PPI.CHx_EEP and PPI.CHx_TEP were renamed into an array of structs. */ +#define CH0_EEP CH[0].EEP +#define CH0_TEP CH[0].TEP +#define CH1_EEP CH[1].EEP +#define CH1_TEP CH[1].TEP +#define CH2_EEP CH[2].EEP +#define CH2_TEP CH[2].TEP +#define CH3_EEP CH[3].EEP +#define CH3_TEP CH[3].TEP +#define CH4_EEP CH[4].EEP +#define CH4_TEP CH[4].TEP +#define CH5_EEP CH[5].EEP +#define CH5_TEP CH[5].TEP +#define CH6_EEP CH[6].EEP +#define CH6_TEP CH[6].TEP +#define CH7_EEP CH[7].EEP +#define CH7_TEP CH[7].TEP +#define CH8_EEP CH[8].EEP +#define CH8_TEP CH[8].TEP +#define CH9_EEP CH[9].EEP +#define CH9_TEP CH[9].TEP +#define CH10_EEP CH[10].EEP +#define CH10_TEP CH[10].TEP +#define CH11_EEP CH[11].EEP +#define CH11_TEP CH[11].TEP +#define CH12_EEP CH[12].EEP +#define CH12_TEP CH[12].TEP +#define CH13_EEP CH[13].EEP +#define CH13_TEP CH[13].TEP +#define CH14_EEP CH[14].EEP +#define CH14_TEP CH[14].TEP +#define CH15_EEP CH[15].EEP +#define CH15_TEP CH[15].TEP +/* The registers PPI.CHG0, PPI.CHG1, PPI.CHG2 and PPI.CHG3 were renamed into an array. */ +#define CHG0 CHG[0] +#define CHG1 CHG[1] +#define CHG2 CHG[2] +#define CHG3 CHG[3] +/* All bitfield macros for the CHGx registers therefore changed name. */ +#define PPI_CHG0_CH15_Pos PPI_CHG_CH15_Pos +#define PPI_CHG0_CH15_Msk PPI_CHG_CH15_Msk +#define PPI_CHG0_CH15_Excluded PPI_CHG_CH15_Excluded +#define PPI_CHG0_CH15_Included PPI_CHG_CH15_Included +#define PPI_CHG0_CH14_Pos PPI_CHG_CH14_Pos +#define PPI_CHG0_CH14_Msk PPI_CHG_CH14_Msk +#define PPI_CHG0_CH14_Excluded PPI_CHG_CH14_Excluded +#define PPI_CHG0_CH14_Included PPI_CHG_CH14_Included +#define PPI_CHG0_CH13_Pos PPI_CHG_CH13_Pos +#define PPI_CHG0_CH13_Msk PPI_CHG_CH13_Msk +#define PPI_CHG0_CH13_Excluded PPI_CHG_CH13_Excluded +#define PPI_CHG0_CH13_Included PPI_CHG_CH13_Included +#define PPI_CHG0_CH12_Pos PPI_CHG_CH12_Pos +#define PPI_CHG0_CH12_Msk PPI_CHG_CH12_Msk +#define PPI_CHG0_CH12_Excluded PPI_CHG_CH12_Excluded +#define PPI_CHG0_CH12_Included PPI_CHG_CH12_Included +#define PPI_CHG0_CH11_Pos PPI_CHG_CH11_Pos +#define PPI_CHG0_CH11_Msk PPI_CHG_CH11_Msk +#define PPI_CHG0_CH11_Excluded PPI_CHG_CH11_Excluded +#define PPI_CHG0_CH11_Included PPI_CHG_CH11_Included +#define PPI_CHG0_CH10_Pos PPI_CHG_CH10_Pos +#define PPI_CHG0_CH10_Msk PPI_CHG_CH10_Msk +#define PPI_CHG0_CH10_Excluded PPI_CHG_CH10_Excluded +#define PPI_CHG0_CH10_Included PPI_CHG_CH10_Included +#define PPI_CHG0_CH9_Pos PPI_CHG_CH9_Pos +#define PPI_CHG0_CH9_Msk PPI_CHG_CH9_Msk +#define PPI_CHG0_CH9_Excluded PPI_CHG_CH9_Excluded +#define PPI_CHG0_CH9_Included PPI_CHG_CH9_Included +#define PPI_CHG0_CH8_Pos PPI_CHG_CH8_Pos +#define PPI_CHG0_CH8_Msk PPI_CHG_CH8_Msk +#define PPI_CHG0_CH8_Excluded PPI_CHG_CH8_Excluded +#define PPI_CHG0_CH8_Included PPI_CHG_CH8_Included +#define PPI_CHG0_CH7_Pos PPI_CHG_CH7_Pos +#define PPI_CHG0_CH7_Msk PPI_CHG_CH7_Msk +#define PPI_CHG0_CH7_Excluded PPI_CHG_CH7_Excluded +#define PPI_CHG0_CH7_Included PPI_CHG_CH7_Included +#define PPI_CHG0_CH6_Pos PPI_CHG_CH6_Pos +#define PPI_CHG0_CH6_Msk PPI_CHG_CH6_Msk +#define PPI_CHG0_CH6_Excluded PPI_CHG_CH6_Excluded +#define PPI_CHG0_CH6_Included PPI_CHG_CH6_Included +#define PPI_CHG0_CH5_Pos PPI_CHG_CH5_Pos +#define PPI_CHG0_CH5_Msk PPI_CHG_CH5_Msk +#define PPI_CHG0_CH5_Excluded PPI_CHG_CH5_Excluded +#define PPI_CHG0_CH5_Included PPI_CHG_CH5_Included +#define PPI_CHG0_CH4_Pos PPI_CHG_CH4_Pos +#define PPI_CHG0_CH4_Msk PPI_CHG_CH4_Msk +#define PPI_CHG0_CH4_Excluded PPI_CHG_CH4_Excluded +#define PPI_CHG0_CH4_Included PPI_CHG_CH4_Included +#define PPI_CHG0_CH3_Pos PPI_CHG_CH3_Pos +#define PPI_CHG0_CH3_Msk PPI_CHG_CH3_Msk +#define PPI_CHG0_CH3_Excluded PPI_CHG_CH3_Excluded +#define PPI_CHG0_CH3_Included PPI_CHG_CH3_Included +#define PPI_CHG0_CH2_Pos PPI_CHG_CH2_Pos +#define PPI_CHG0_CH2_Msk PPI_CHG_CH2_Msk +#define PPI_CHG0_CH2_Excluded PPI_CHG_CH2_Excluded +#define PPI_CHG0_CH2_Included PPI_CHG_CH2_Included +#define PPI_CHG0_CH1_Pos PPI_CHG_CH1_Pos +#define PPI_CHG0_CH1_Msk PPI_CHG_CH1_Msk +#define PPI_CHG0_CH1_Excluded PPI_CHG_CH1_Excluded +#define PPI_CHG0_CH1_Included PPI_CHG_CH1_Included +#define PPI_CHG0_CH0_Pos PPI_CHG_CH0_Pos +#define PPI_CHG0_CH0_Msk PPI_CHG_CH0_Msk +#define PPI_CHG0_CH0_Excluded PPI_CHG_CH0_Excluded +#define PPI_CHG0_CH0_Included PPI_CHG_CH0_Included +#define PPI_CHG1_CH15_Pos PPI_CHG_CH15_Pos +#define PPI_CHG1_CH15_Msk PPI_CHG_CH15_Msk +#define PPI_CHG1_CH15_Excluded PPI_CHG_CH15_Excluded +#define PPI_CHG1_CH15_Included PPI_CHG_CH15_Included +#define PPI_CHG1_CH14_Pos PPI_CHG_CH14_Pos +#define PPI_CHG1_CH14_Msk PPI_CHG_CH14_Msk +#define PPI_CHG1_CH14_Excluded PPI_CHG_CH14_Excluded +#define PPI_CHG1_CH14_Included PPI_CHG_CH14_Included +#define PPI_CHG1_CH13_Pos PPI_CHG_CH13_Pos +#define PPI_CHG1_CH13_Msk PPI_CHG_CH13_Msk +#define PPI_CHG1_CH13_Excluded PPI_CHG_CH13_Excluded +#define PPI_CHG1_CH13_Included PPI_CHG_CH13_Included +#define PPI_CHG1_CH12_Pos PPI_CHG_CH12_Pos +#define PPI_CHG1_CH12_Msk PPI_CHG_CH12_Msk +#define PPI_CHG1_CH12_Excluded PPI_CHG_CH12_Excluded +#define PPI_CHG1_CH12_Included PPI_CHG_CH12_Included +#define PPI_CHG1_CH11_Pos PPI_CHG_CH11_Pos +#define PPI_CHG1_CH11_Msk PPI_CHG_CH11_Msk +#define PPI_CHG1_CH11_Excluded PPI_CHG_CH11_Excluded +#define PPI_CHG1_CH11_Included PPI_CHG_CH11_Included +#define PPI_CHG1_CH10_Pos PPI_CHG_CH10_Pos +#define PPI_CHG1_CH10_Msk PPI_CHG_CH10_Msk +#define PPI_CHG1_CH10_Excluded PPI_CHG_CH10_Excluded +#define PPI_CHG1_CH10_Included PPI_CHG_CH10_Included +#define PPI_CHG1_CH9_Pos PPI_CHG_CH9_Pos +#define PPI_CHG1_CH9_Msk PPI_CHG_CH9_Msk +#define PPI_CHG1_CH9_Excluded PPI_CHG_CH9_Excluded +#define PPI_CHG1_CH9_Included PPI_CHG_CH9_Included +#define PPI_CHG1_CH8_Pos PPI_CHG_CH8_Pos +#define PPI_CHG1_CH8_Msk PPI_CHG_CH8_Msk +#define PPI_CHG1_CH8_Excluded PPI_CHG_CH8_Excluded +#define PPI_CHG1_CH8_Included PPI_CHG_CH8_Included +#define PPI_CHG1_CH7_Pos PPI_CHG_CH7_Pos +#define PPI_CHG1_CH7_Msk PPI_CHG_CH7_Msk +#define PPI_CHG1_CH7_Excluded PPI_CHG_CH7_Excluded +#define PPI_CHG1_CH7_Included PPI_CHG_CH7_Included +#define PPI_CHG1_CH6_Pos PPI_CHG_CH6_Pos +#define PPI_CHG1_CH6_Msk PPI_CHG_CH6_Msk +#define PPI_CHG1_CH6_Excluded PPI_CHG_CH6_Excluded +#define PPI_CHG1_CH6_Included PPI_CHG_CH6_Included +#define PPI_CHG1_CH5_Pos PPI_CHG_CH5_Pos +#define PPI_CHG1_CH5_Msk PPI_CHG_CH5_Msk +#define PPI_CHG1_CH5_Excluded PPI_CHG_CH5_Excluded +#define PPI_CHG1_CH5_Included PPI_CHG_CH5_Included +#define PPI_CHG1_CH4_Pos PPI_CHG_CH4_Pos +#define PPI_CHG1_CH4_Msk PPI_CHG_CH4_Msk +#define PPI_CHG1_CH4_Excluded PPI_CHG_CH4_Excluded +#define PPI_CHG1_CH4_Included PPI_CHG_CH4_Included +#define PPI_CHG1_CH3_Pos PPI_CHG_CH3_Pos +#define PPI_CHG1_CH3_Msk PPI_CHG_CH3_Msk +#define PPI_CHG1_CH3_Excluded PPI_CHG_CH3_Excluded +#define PPI_CHG1_CH3_Included PPI_CHG_CH3_Included +#define PPI_CHG1_CH2_Pos PPI_CHG_CH2_Pos +#define PPI_CHG1_CH2_Msk PPI_CHG_CH2_Msk +#define PPI_CHG1_CH2_Excluded PPI_CHG_CH2_Excluded +#define PPI_CHG1_CH2_Included PPI_CHG_CH2_Included +#define PPI_CHG1_CH1_Pos PPI_CHG_CH1_Pos +#define PPI_CHG1_CH1_Msk PPI_CHG_CH1_Msk +#define PPI_CHG1_CH1_Excluded PPI_CHG_CH1_Excluded +#define PPI_CHG1_CH1_Included PPI_CHG_CH1_Included +#define PPI_CHG1_CH0_Pos PPI_CHG_CH0_Pos +#define PPI_CHG1_CH0_Msk PPI_CHG_CH0_Msk +#define PPI_CHG1_CH0_Excluded PPI_CHG_CH0_Excluded +#define PPI_CHG1_CH0_Included PPI_CHG_CH0_Included +#define PPI_CHG2_CH15_Pos PPI_CHG_CH15_Pos +#define PPI_CHG2_CH15_Msk PPI_CHG_CH15_Msk +#define PPI_CHG2_CH15_Excluded PPI_CHG_CH15_Excluded +#define PPI_CHG2_CH15_Included PPI_CHG_CH15_Included +#define PPI_CHG2_CH14_Pos PPI_CHG_CH14_Pos +#define PPI_CHG2_CH14_Msk PPI_CHG_CH14_Msk +#define PPI_CHG2_CH14_Excluded PPI_CHG_CH14_Excluded +#define PPI_CHG2_CH14_Included PPI_CHG_CH14_Included +#define PPI_CHG2_CH13_Pos PPI_CHG_CH13_Pos +#define PPI_CHG2_CH13_Msk PPI_CHG_CH13_Msk +#define PPI_CHG2_CH13_Excluded PPI_CHG_CH13_Excluded +#define PPI_CHG2_CH13_Included PPI_CHG_CH13_Included +#define PPI_CHG2_CH12_Pos PPI_CHG_CH12_Pos +#define PPI_CHG2_CH12_Msk PPI_CHG_CH12_Msk +#define PPI_CHG2_CH12_Excluded PPI_CHG_CH12_Excluded +#define PPI_CHG2_CH12_Included PPI_CHG_CH12_Included +#define PPI_CHG2_CH11_Pos PPI_CHG_CH11_Pos +#define PPI_CHG2_CH11_Msk PPI_CHG_CH11_Msk +#define PPI_CHG2_CH11_Excluded PPI_CHG_CH11_Excluded +#define PPI_CHG2_CH11_Included PPI_CHG_CH11_Included +#define PPI_CHG2_CH10_Pos PPI_CHG_CH10_Pos +#define PPI_CHG2_CH10_Msk PPI_CHG_CH10_Msk +#define PPI_CHG2_CH10_Excluded PPI_CHG_CH10_Excluded +#define PPI_CHG2_CH10_Included PPI_CHG_CH10_Included +#define PPI_CHG2_CH9_Pos PPI_CHG_CH9_Pos +#define PPI_CHG2_CH9_Msk PPI_CHG_CH9_Msk +#define PPI_CHG2_CH9_Excluded PPI_CHG_CH9_Excluded +#define PPI_CHG2_CH9_Included PPI_CHG_CH9_Included +#define PPI_CHG2_CH8_Pos PPI_CHG_CH8_Pos +#define PPI_CHG2_CH8_Msk PPI_CHG_CH8_Msk +#define PPI_CHG2_CH8_Excluded PPI_CHG_CH8_Excluded +#define PPI_CHG2_CH8_Included PPI_CHG_CH8_Included +#define PPI_CHG2_CH7_Pos PPI_CHG_CH7_Pos +#define PPI_CHG2_CH7_Msk PPI_CHG_CH7_Msk +#define PPI_CHG2_CH7_Excluded PPI_CHG_CH7_Excluded +#define PPI_CHG2_CH7_Included PPI_CHG_CH7_Included +#define PPI_CHG2_CH6_Pos PPI_CHG_CH6_Pos +#define PPI_CHG2_CH6_Msk PPI_CHG_CH6_Msk +#define PPI_CHG2_CH6_Excluded PPI_CHG_CH6_Excluded +#define PPI_CHG2_CH6_Included PPI_CHG_CH6_Included +#define PPI_CHG2_CH5_Pos PPI_CHG_CH5_Pos +#define PPI_CHG2_CH5_Msk PPI_CHG_CH5_Msk +#define PPI_CHG2_CH5_Excluded PPI_CHG_CH5_Excluded +#define PPI_CHG2_CH5_Included PPI_CHG_CH5_Included +#define PPI_CHG2_CH4_Pos PPI_CHG_CH4_Pos +#define PPI_CHG2_CH4_Msk PPI_CHG_CH4_Msk +#define PPI_CHG2_CH4_Excluded PPI_CHG_CH4_Excluded +#define PPI_CHG2_CH4_Included PPI_CHG_CH4_Included +#define PPI_CHG2_CH3_Pos PPI_CHG_CH3_Pos +#define PPI_CHG2_CH3_Msk PPI_CHG_CH3_Msk +#define PPI_CHG2_CH3_Excluded PPI_CHG_CH3_Excluded +#define PPI_CHG2_CH3_Included PPI_CHG_CH3_Included +#define PPI_CHG2_CH2_Pos PPI_CHG_CH2_Pos +#define PPI_CHG2_CH2_Msk PPI_CHG_CH2_Msk +#define PPI_CHG2_CH2_Excluded PPI_CHG_CH2_Excluded +#define PPI_CHG2_CH2_Included PPI_CHG_CH2_Included +#define PPI_CHG2_CH1_Pos PPI_CHG_CH1_Pos +#define PPI_CHG2_CH1_Msk PPI_CHG_CH1_Msk +#define PPI_CHG2_CH1_Excluded PPI_CHG_CH1_Excluded +#define PPI_CHG2_CH1_Included PPI_CHG_CH1_Included +#define PPI_CHG2_CH0_Pos PPI_CHG_CH0_Pos +#define PPI_CHG2_CH0_Msk PPI_CHG_CH0_Msk +#define PPI_CHG2_CH0_Excluded PPI_CHG_CH0_Excluded +#define PPI_CHG2_CH0_Included PPI_CHG_CH0_Included +#define PPI_CHG3_CH15_Pos PPI_CHG_CH15_Pos +#define PPI_CHG3_CH15_Msk PPI_CHG_CH15_Msk +#define PPI_CHG3_CH15_Excluded PPI_CHG_CH15_Excluded +#define PPI_CHG3_CH15_Included PPI_CHG_CH15_Included +#define PPI_CHG3_CH14_Pos PPI_CHG_CH14_Pos +#define PPI_CHG3_CH14_Msk PPI_CHG_CH14_Msk +#define PPI_CHG3_CH14_Excluded PPI_CHG_CH14_Excluded +#define PPI_CHG3_CH14_Included PPI_CHG_CH14_Included +#define PPI_CHG3_CH13_Pos PPI_CHG_CH13_Pos +#define PPI_CHG3_CH13_Msk PPI_CHG_CH13_Msk +#define PPI_CHG3_CH13_Excluded PPI_CHG_CH13_Excluded +#define PPI_CHG3_CH13_Included PPI_CHG_CH13_Included +#define PPI_CHG3_CH12_Pos PPI_CHG_CH12_Pos +#define PPI_CHG3_CH12_Msk PPI_CHG_CH12_Msk +#define PPI_CHG3_CH12_Excluded PPI_CHG_CH12_Excluded +#define PPI_CHG3_CH12_Included PPI_CHG_CH12_Included +#define PPI_CHG3_CH11_Pos PPI_CHG_CH11_Pos +#define PPI_CHG3_CH11_Msk PPI_CHG_CH11_Msk +#define PPI_CHG3_CH11_Excluded PPI_CHG_CH11_Excluded +#define PPI_CHG3_CH11_Included PPI_CHG_CH11_Included +#define PPI_CHG3_CH10_Pos PPI_CHG_CH10_Pos +#define PPI_CHG3_CH10_Msk PPI_CHG_CH10_Msk +#define PPI_CHG3_CH10_Excluded PPI_CHG_CH10_Excluded +#define PPI_CHG3_CH10_Included PPI_CHG_CH10_Included +#define PPI_CHG3_CH9_Pos PPI_CHG_CH9_Pos +#define PPI_CHG3_CH9_Msk PPI_CHG_CH9_Msk +#define PPI_CHG3_CH9_Excluded PPI_CHG_CH9_Excluded +#define PPI_CHG3_CH9_Included PPI_CHG_CH9_Included +#define PPI_CHG3_CH8_Pos PPI_CHG_CH8_Pos +#define PPI_CHG3_CH8_Msk PPI_CHG_CH8_Msk +#define PPI_CHG3_CH8_Excluded PPI_CHG_CH8_Excluded +#define PPI_CHG3_CH8_Included PPI_CHG_CH8_Included +#define PPI_CHG3_CH7_Pos PPI_CHG_CH7_Pos +#define PPI_CHG3_CH7_Msk PPI_CHG_CH7_Msk +#define PPI_CHG3_CH7_Excluded PPI_CHG_CH7_Excluded +#define PPI_CHG3_CH7_Included PPI_CHG_CH7_Included +#define PPI_CHG3_CH6_Pos PPI_CHG_CH6_Pos +#define PPI_CHG3_CH6_Msk PPI_CHG_CH6_Msk +#define PPI_CHG3_CH6_Excluded PPI_CHG_CH6_Excluded +#define PPI_CHG3_CH6_Included PPI_CHG_CH6_Included +#define PPI_CHG3_CH5_Pos PPI_CHG_CH5_Pos +#define PPI_CHG3_CH5_Msk PPI_CHG_CH5_Msk +#define PPI_CHG3_CH5_Excluded PPI_CHG_CH5_Excluded +#define PPI_CHG3_CH5_Included PPI_CHG_CH5_Included +#define PPI_CHG3_CH4_Pos PPI_CHG_CH4_Pos +#define PPI_CHG3_CH4_Msk PPI_CHG_CH4_Msk +#define PPI_CHG3_CH4_Excluded PPI_CHG_CH4_Excluded +#define PPI_CHG3_CH4_Included PPI_CHG_CH4_Included +#define PPI_CHG3_CH3_Pos PPI_CHG_CH3_Pos +#define PPI_CHG3_CH3_Msk PPI_CHG_CH3_Msk +#define PPI_CHG3_CH3_Excluded PPI_CHG_CH3_Excluded +#define PPI_CHG3_CH3_Included PPI_CHG_CH3_Included +#define PPI_CHG3_CH2_Pos PPI_CHG_CH2_Pos +#define PPI_CHG3_CH2_Msk PPI_CHG_CH2_Msk +#define PPI_CHG3_CH2_Excluded PPI_CHG_CH2_Excluded +#define PPI_CHG3_CH2_Included PPI_CHG_CH2_Included +#define PPI_CHG3_CH1_Pos PPI_CHG_CH1_Pos +#define PPI_CHG3_CH1_Msk PPI_CHG_CH1_Msk +#define PPI_CHG3_CH1_Excluded PPI_CHG_CH1_Excluded +#define PPI_CHG3_CH1_Included PPI_CHG_CH1_Included +#define PPI_CHG3_CH0_Pos PPI_CHG_CH0_Pos +#define PPI_CHG3_CH0_Msk PPI_CHG_CH0_Msk +#define PPI_CHG3_CH0_Excluded PPI_CHG_CH0_Excluded +#define PPI_CHG3_CH0_Included PPI_CHG_CH0_Included + + + +/*lint --flb "Leave library region" */ + +#endif /* NRF51_DEPRECATED_H */ + http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/826d3a57/hw/mcu/nordic/nrf51xxx/include/mcu/nrf51_hal.h ---------------------------------------------------------------------- diff --git a/hw/mcu/nordic/nrf51xxx/include/mcu/nrf51_hal.h b/hw/mcu/nordic/nrf51xxx/include/mcu/nrf51_hal.h new file mode 100755 index 0000000..46f4737 --- /dev/null +++ b/hw/mcu/nordic/nrf51xxx/include/mcu/nrf51_hal.h @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2015 Runtime Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef H_NRF51_HAL_ +#define H_NRF51_HAL_ + +#ifdef __cplusplus + extern "C" { +#endif + +/* Helper functions to enable/disable interrupts. */ +#define __HAL_DISABLE_INTERRUPTS(x) \ + do { \ + x = __get_PRIMASK(); \ + __disable_irq(); \ + } while(0); + +#define __HAL_ENABLE_INTERRUPTS(x) \ + do { \ + if (!x) { \ + __enable_irq(); \ + } \ + } while(0); + +struct nrf51_uart_cfg { + int8_t suc_pin_tx; /* pins for IO */ + int8_t suc_pin_rx; + int8_t suc_pin_rts; + int8_t suc_pin_cts; +}; +const struct nrf51_uart_cfg *bsp_uart_config(void); + +#ifdef __cplusplus +} +#endif + +#endif /* H_NRF51_HAL_ */ + http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/826d3a57/hw/mcu/nordic/nrf51xxx/include/mcu/system_nrf51.h ---------------------------------------------------------------------- diff --git a/hw/mcu/nordic/nrf51xxx/include/mcu/system_nrf51.h b/hw/mcu/nordic/nrf51xxx/include/mcu/system_nrf51.h new file mode 100755 index 0000000..16fe556 --- /dev/null +++ b/hw/mcu/nordic/nrf51xxx/include/mcu/system_nrf51.h @@ -0,0 +1,85 @@ +/** + * Copyright (c) 2016 Runtime Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* Copyright (c) 2015, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef SYSTEM_NRF51_H +#define SYSTEM_NRF51_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <stdint.h> + + +extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */ + +/** + * Initialize the system + * + * @param none + * @return none + * + * @brief Setup the microcontroller system. + * Initialize the System and update the SystemCoreClock variable. + */ +extern void SystemInit (void); + +/** + * Update SystemCoreClock variable + * + * @param none + * @return none + * + * @brief Updates the SystemCoreClock with current core Clock + * retrieved from cpu registers. + */ +extern void SystemCoreClockUpdate (void); + +#ifdef __cplusplus +} +#endif + +#endif /* SYSTEM_NRF51_H */ http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/826d3a57/hw/mcu/nordic/nrf51xxx/src/hal_cputime.c ---------------------------------------------------------------------- diff --git a/hw/mcu/nordic/nrf51xxx/src/hal_cputime.c b/hw/mcu/nordic/nrf51xxx/src/hal_cputime.c new file mode 100644 index 0000000..319ef04 --- /dev/null +++ b/hw/mcu/nordic/nrf51xxx/src/hal_cputime.c @@ -0,0 +1,585 @@ +/** + * Copyright (c) 2015 Stack Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include <string.h> +#include <stdint.h> +#include <assert.h> +#include "bsp/cmsis_nvic.h" +#include "hal/hal_cputime.h" +#include "mcu/nrf51.h" +#include "mcu/nrf51_bitfields.h" +#include "mcu/nrf51_hal.h" + +/* Maximum timer frequency */ +#define NRF51_MAX_TIMER_FREQ (16000000) + +/* + * Use these defines to select a timer and the compare channels. The reason + * channel 2 is left open for TIMER0 is that there are pre-programmed PPI + * channels that use timer 0 channel 2 for certain events. For example, the + * radio has RADIO->EVENTS_END tied to capture channel 2. This can be + * used to capture rx/tx end times. + */ + +#define CPUTIMER NRF_TIMER0 +#define CPUTIMER_IRQ (TIMER0_IRQn) +#define CPUTIMER_CC_CNTR (0) +#define CPUTIMER_CC_OVERFLOW (1) +#define CPUTIMER_CC_INT (3) + +/* Interrupt mask for interrupt enable/clear */ +#define CPUTIMER_INT_MASK(x) ((1 << (uint32_t)(x)) << 16) + +/* XXX: + * - Must determine how to set priority of cpu timer interrupt + * - Determine if we should use a mutex as opposed to disabling interrupts + * - Should I use macro for compare channel? + * - Sync to OSTIME. + */ + +/* CPUTIME data */ +struct cputime_data +{ + uint32_t ticks_per_usec; /* number of ticks per usec */ + uint32_t cputime_high; /* high word of 64-bit cpu time */ + uint32_t timer_isrs; /* Number of timer interrupts */ + uint32_t ocmp_ints; /* Number of ocmp interrupts */ + uint32_t uif_ints; /* Number of overflow interrupts */ +}; +struct cputime_data g_cputime; + +/* Queue for timers */ +TAILQ_HEAD(cputime_qhead, cpu_timer) g_cputimer_q; + +__STATIC_INLINE void +cputime_disable_ocmp(void) +{ + CPUTIMER->INTENCLR = CPUTIMER_INT_MASK(CPUTIMER_CC_INT); +} + +/** + * cputime set ocmp + * + * Set the OCMP used by the cputime module to the desired cputime. + * + * NOTE: Must be called with interrupts disabled. + * + * @param timer Pointer to timer. + */ +static void +cputime_set_ocmp(struct cpu_timer *timer) +{ + /* Disable ocmp interrupt and set new value */ + cputime_disable_ocmp(); + + /* Set output compare register to timer expiration */ + CPUTIMER->CC[CPUTIMER_CC_INT] = timer->cputime; + + /* Clear interrupt flag*/ + CPUTIMER->EVENTS_COMPARE[CPUTIMER_CC_INT] = 0; + + /* Enable the output compare interrupt */ + CPUTIMER->INTENSET = CPUTIMER_INT_MASK(CPUTIMER_CC_INT); + + /* Force interrupt to occur as we may have missed it */ + if ((int32_t)(cputime_get32() - timer->cputime) >= 0) { + NVIC_SetPendingIRQ(CPUTIMER_IRQ); + } +} + +/** + * cputime chk expiration + * + * Iterates through the cputimer queue to determine if any timers have expired. + * If the timer has expired the timer is removed from the queue and the timer + * callback function is executed. + * + */ +static void +cputime_chk_expiration(void) +{ + uint32_t ctx; + struct cpu_timer *timer; + + __HAL_DISABLE_INTERRUPTS(ctx); + while ((timer = TAILQ_FIRST(&g_cputimer_q)) != NULL) { + if ((int32_t)(cputime_get32() - timer->cputime) >= 0) { + TAILQ_REMOVE(&g_cputimer_q, timer, link); + timer->link.tqe_prev = NULL; + timer->cb(timer->arg); + } else { + break; + } + } + + /* Any timers left on queue? If so, we need to set OCMP */ + timer = TAILQ_FIRST(&g_cputimer_q); + if (timer) { + cputime_set_ocmp(timer); + } else { + cputime_disable_ocmp(); + } + __HAL_ENABLE_INTERRUPTS(ctx); +} + +/** + * cputime isr + * + * This is the global timer interrupt routine. + * + */ +static void +cputime_isr(void) +{ + uint32_t compare; + uint32_t overflow; + + /* Check interrupt source. If set, clear them */ + compare = CPUTIMER->EVENTS_COMPARE[CPUTIMER_CC_INT]; + if (compare) { + CPUTIMER->EVENTS_COMPARE[CPUTIMER_CC_INT] = 0; + } + overflow = CPUTIMER->EVENTS_COMPARE[CPUTIMER_CC_OVERFLOW]; + if (overflow) { + CPUTIMER->EVENTS_COMPARE[CPUTIMER_CC_OVERFLOW] = 0; + } + + /* Count # of interrupts */ + ++g_cputime.timer_isrs; + + /* If overflow, increment high word of cpu time */ + if (overflow) { + ++g_cputime.uif_ints; + ++g_cputime.cputime_high; + } + + /* + * NOTE: we dont check the 'compare' variable here due to how the timer + * is implemented on this chip. There is no way to force an output + * compare, so if we are late setting the output compare (i.e. the timer + * counter is already passed the output compare value), we use the NVIC + * to set a pending interrupt. This means that there will be no compare + * flag set, so all we do is check to see if the compare interrupt is + * enabled. + */ + if (CPUTIMER->INTENCLR & CPUTIMER_INT_MASK(CPUTIMER_CC_INT)) { + ++g_cputime.ocmp_ints; + cputime_chk_expiration(); + + /* XXX: Recommended by nordic to make sure interrupts are cleared */ + compare = CPUTIMER->EVENTS_COMPARE[CPUTIMER_CC_INT]; + } +} + +/** + * cputime init + * + * Initialize the cputime module. This must be called after os_init is called + * and before any other timer API are used. This should be called only once + * and should be called before the hardware timer is used. + * + * @param clock_freq The desired cputime frequency, in hertz (Hz). + * + * @return int 0 on success; -1 on error. + */ +int +cputime_init(uint32_t clock_freq) +{ + uint32_t ctx; + uint32_t max_freq; + uint32_t pre_scaler; + + /* Clock frequency must be at least 1 MHz */ + if (clock_freq < 1000000U) { + return -1; + } + + /* Check if clock frequency exceeds max. range */ + max_freq = NRF51_MAX_TIMER_FREQ; + if (clock_freq > max_freq) { + return -1; + } + + /* Is this exact frequency obtainable? */ + pre_scaler = max_freq / clock_freq; + if ((pre_scaler * clock_freq) != max_freq) { + return -1; + } + + /* + * Pre-scaler is 4 bits and is a 2^n, so the only possible values that + * work are 1, 2, 4, 8 and 16, which gives a valid pre-scaler of 0, 1, 2, + * 3 or 4. + */ + switch (pre_scaler) { + case 1: + pre_scaler = 0; + break; + case 2: + pre_scaler = 1; + break; + case 4: + pre_scaler = 2; + break; + case 8: + pre_scaler = 3; + break; + case 16: + pre_scaler = 4; + break; + default: + pre_scaler = 0xFFFFFFFF; + break; + } + + if (pre_scaler == 0xFFFFFFFF) { + return -1; + } + + /* Initialize the timer queue */ + TAILQ_INIT(&g_cputimer_q); + + /* disable interrupts */ + __HAL_DISABLE_INTERRUPTS(ctx); + + /* Set the clock frequency */ + g_cputime.ticks_per_usec = clock_freq / 1000000U; + + /* XXX: no way to halt the timer in debug mode that I can see */ + + /* Stop the timer first */ + CPUTIMER->TASKS_STOP = 1; + + /* Put the timer in timer mode using 32 bits. */ + CPUTIMER->MODE = TIMER_MODE_MODE_Timer; + CPUTIMER->BITMODE = TIMER_BITMODE_BITMODE_32Bit; + + /* Set the pre-scaler*/ + CPUTIMER->PRESCALER = pre_scaler; + + /* Start the timer */ + CPUTIMER->TASKS_START = 1; + + /* Use an output compare to generate an overflow */ + CPUTIMER->CC[CPUTIMER_CC_OVERFLOW] = 0; + CPUTIMER->EVENTS_COMPARE[CPUTIMER_CC_OVERFLOW] = 0; + CPUTIMER->INTENSET = CPUTIMER_INT_MASK(CPUTIMER_CC_OVERFLOW); + + /* Set isr in vector table and enable interrupt */ + NVIC_SetVector(CPUTIMER_IRQ, (uint32_t)cputime_isr); + NVIC_EnableIRQ(CPUTIMER_IRQ); + + __HAL_ENABLE_INTERRUPTS(ctx); + + return 0; +} + +/** + * cputime get64 + * + * Returns cputime as a 64-bit number. + * + * @return uint64_t The 64-bit representation of cputime. + */ +uint64_t +cputime_get64(void) +{ + uint32_t ctx; + uint32_t high; + uint32_t low; + uint64_t cpu_time; + + __HAL_DISABLE_INTERRUPTS(ctx); + high = g_cputime.cputime_high; + low = cputime_get32(); + if (CPUTIMER->EVENTS_COMPARE[CPUTIMER_CC_OVERFLOW]) { + ++high; + low = cputime_get32(); + } + __HAL_ENABLE_INTERRUPTS(ctx); + + cpu_time = ((uint64_t)high << 32) | low; + + return cpu_time; +} + +/** + * cputime get32 + * + * Returns the low 32 bits of cputime. + * + * @return uint32_t The lower 32 bits of cputime + */ +uint32_t +cputime_get32(void) +{ + uint32_t cpu_time; + + /* Force a capture of the timer into 'cntr' capture channel; read it */ + CPUTIMER->TASKS_CAPTURE[CPUTIMER_CC_CNTR] = 1; + cpu_time = CPUTIMER->CC[CPUTIMER_CC_CNTR]; + + return cpu_time; +} + +/** + * cputime nsecs to ticks + * + * Converts the given number of nanoseconds into cputime ticks. + * + * @param usecs The number of nanoseconds to convert to ticks + * + * @return uint32_t The number of ticks corresponding to 'nsecs' + */ +uint32_t +cputime_nsecs_to_ticks(uint32_t nsecs) +{ + uint32_t ticks; + + ticks = ((nsecs * g_cputime.ticks_per_usec) + 999) / 1000; + return ticks; +} + +/** + * cputime ticks to nsecs + * + * Convert the given number of ticks into nanoseconds. + * + * @param ticks The number of ticks to convert to nanoseconds. + * + * @return uint32_t The number of nanoseconds corresponding to 'ticks' + */ +uint32_t +cputime_ticks_to_nsecs(uint32_t ticks) +{ + uint32_t nsecs; + + nsecs = ((ticks * 1000) + (g_cputime.ticks_per_usec - 1)) / + g_cputime.ticks_per_usec; + + return nsecs; +} + +/** + * cputime usecs to ticks + * + * Converts the given number of microseconds into cputime ticks. + * + * @param usecs The number of microseconds to convert to ticks + * + * @return uint32_t The number of ticks corresponding to 'usecs' + */ +uint32_t +cputime_usecs_to_ticks(uint32_t usecs) +{ + uint32_t ticks; + + ticks = (usecs * g_cputime.ticks_per_usec); + return ticks; +} + +/** + * cputime ticks to usecs + * + * Convert the given number of ticks into microseconds. + * + * @param ticks The number of ticks to convert to microseconds. + * + * @return uint32_t The number of microseconds corresponding to 'ticks' + */ +uint32_t +cputime_ticks_to_usecs(uint32_t ticks) +{ + uint32_t us; + + us = (ticks + (g_cputime.ticks_per_usec - 1)) / g_cputime.ticks_per_usec; + return us; +} + +/** + * cputime delay ticks + * + * Wait until the number of ticks has elapsed. This is a blocking delay. + * + * @param ticks The number of ticks to wait. + */ +void +cputime_delay_ticks(uint32_t ticks) +{ + uint32_t until; + + until = cputime_get32() + ticks; + while ((int32_t)(cputime_get32() - until) < 0) { + /* Loop here till finished */ + } +} + +/** + * cputime delay nsecs + * + * Wait until 'nsecs' nanoseconds has elapsed. This is a blocking delay. + * + * @param nsecs The number of nanoseconds to wait. + */ +void +cputime_delay_nsecs(uint32_t nsecs) +{ + uint32_t ticks; + + ticks = cputime_nsecs_to_ticks(nsecs); + cputime_delay_ticks(ticks); +} + +/** + * cputime delay usecs + * + * Wait until 'usecs' microseconds has elapsed. This is a blocking delay. + * + * @param usecs The number of usecs to wait. + */ +void +cputime_delay_usecs(uint32_t usecs) +{ + uint32_t ticks; + + ticks = cputime_usecs_to_ticks(usecs); + cputime_delay_ticks(ticks); +} + +/** + * cputime timer init + * + * + * @param timer The timer to initialize. Cannot be NULL. + * @param fp The timer callback function. Cannot be NULL. + * @param arg Pointer to data object to pass to timer. + */ +void +cputime_timer_init(struct cpu_timer *timer, cputimer_func fp, void *arg) +{ + assert(timer != NULL); + assert(fp != NULL); + + timer->cb = fp; + timer->arg = arg; + timer->link.tqe_prev = (void *) NULL; +} + +/** + * cputime timer start + * + * Start a cputimer that will expire at 'cputime'. If cputime has already + * passed, the timer callback will still be called (at interrupt context). + * Cannot be called when the timer has already started. + * + * @param timer Pointer to timer to start. Cannot be NULL. + * @param cputime The cputime at which the timer should expire. + */ +void +cputime_timer_start(struct cpu_timer *timer, uint32_t cputime) +{ + struct cpu_timer *entry; + uint32_t ctx; + + assert(timer != NULL); + assert(timer->link.tqe_prev == NULL); + + /* XXX: should this use a mutex? not sure... */ + __HAL_DISABLE_INTERRUPTS(ctx); + + timer->cputime = cputime; + if (TAILQ_EMPTY(&g_cputimer_q)) { + TAILQ_INSERT_HEAD(&g_cputimer_q, timer, link); + } else { + TAILQ_FOREACH(entry, &g_cputimer_q, link) { + if ((int32_t)(timer->cputime - entry->cputime) < 0) { + TAILQ_INSERT_BEFORE(entry, timer, link); + break; + } + } + if (!entry) { + TAILQ_INSERT_TAIL(&g_cputimer_q, timer, link); + } + } + + /* If this is the head, we need to set new OCMP */ + if (timer == TAILQ_FIRST(&g_cputimer_q)) { + cputime_set_ocmp(timer); + } + + __HAL_ENABLE_INTERRUPTS(ctx); +} + +/** + * cputimer timer relative + * + * Sets a cpu timer that will expire 'usecs' microseconds from the current + * cputime. + * + * @param timer Pointer to timer. Cannot be NULL. + * @param usecs The number of usecs from now at which the timer will expire. + */ +void +cputime_timer_relative(struct cpu_timer *timer, uint32_t usecs) +{ + uint32_t cputime; + + assert(timer != NULL); + + cputime = cputime_get32() + cputime_usecs_to_ticks(usecs); + cputime_timer_start(timer, cputime); +} + +/** + * cputime timer stop + * + * Stops a cputimer from running. The timer is removed from the timer queue + * and interrupts are disabled if no timers are left on the queue. Can be + * called even if timer is not running. + * + * @param timer Pointer to cputimer to stop. Cannot be NULL. + */ +void +cputime_timer_stop(struct cpu_timer *timer) +{ + int reset_ocmp; + uint32_t ctx; + struct cpu_timer *entry; + + assert(timer != NULL); + + __HAL_DISABLE_INTERRUPTS(ctx); + + if (timer->link.tqe_prev != NULL) { + reset_ocmp = 0; + if (timer == TAILQ_FIRST(&g_cputimer_q)) { + /* If first on queue, we will need to reset OCMP */ + entry = TAILQ_NEXT(timer, link); + reset_ocmp = 1; + } + TAILQ_REMOVE(&g_cputimer_q, timer, link); + timer->link.tqe_prev = NULL; + if (reset_ocmp) { + if (entry) { + cputime_set_ocmp(entry); + } else { + cputime_disable_ocmp(); + } + } + } + + __HAL_ENABLE_INTERRUPTS(ctx); +} + http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/826d3a57/hw/mcu/nordic/nrf51xxx/src/hal_gpio.c ---------------------------------------------------------------------- diff --git a/hw/mcu/nordic/nrf51xxx/src/hal_gpio.c b/hw/mcu/nordic/nrf51xxx/src/hal_gpio.c new file mode 100644 index 0000000..fa4cf7a --- /dev/null +++ b/hw/mcu/nordic/nrf51xxx/src/hal_gpio.c @@ -0,0 +1,591 @@ +/** + * Copyright (c) 2015 Runtime Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "hal/hal_gpio.h" +#include "bsp/cmsis_nvic.h" +#include "mcu/nrf51.h" +#include "mcu/nrf51_bitfields.h" +#include <assert.h> + + /* XXX: Notes + * 1) Right now, we are not disabling the NVIC interrupt source; we only + * disable the external interrupt from occurring. Dont think either way + * to do it is an issue... when we release we may want to disable the NVIC + * + * 2) investigate how thread safe these routines are. HAL_GPIO_Init, for + * example. Looks like if it gets interrupted while doing config an error + * may occur. Read/modify write could cause screw-ups. + * + * 3) Currently, this code does not change the interrupt priority of the + * external interrupt vectors in the NVIC. The application developer must + * decide on the priority level for each external interrupt and program that + * by using the CMSIS NVIC API (NVIC_SetPriority and NVIC_SetPriorityGrouping) + * + * 4) The code probably does not handle "re-purposing" gpio very well. + * "Re-purposing" means changing a gpio from input to output, or calling + * gpio_init_in and expecting previously enabled interrupts to be stopped. + * + * 5) Possbily add access to HAL_GPIO_DeInit. + */ + +/* + * GPIO pin mapping + * + */ +#define GPIO_INDEX(pin) (pin) +#define GPIO_MASK(pin) (1 << GPIO_INDEX(pin)) + +/* Storage for GPIO callbacks. */ +struct gpio_irq_obj +{ + void *arg; + gpio_irq_handler_t isr; +}; + +#if 0 +static struct gpio_irq_obj gpio_irq_handlers[16]; +#endif + +struct ext_irqs +{ + volatile uint32_t irq0; + volatile uint32_t irq1; + volatile uint32_t irq2; + volatile uint32_t irq3; + volatile uint32_t irq4; + volatile uint32_t irq9_5; + volatile uint32_t irq15_10; +}; +struct ext_irqs ext_irq_counts; + +#if 0 +/** + * ext irq handler + * + * Handles the gpio interrupt attached to a gpio pin. + * + * @param index + */ +static void +ext_irq_handler(int index) +{ + uint32_t mask; + + mask = 1 << index; + if (__HAL_GPIO_EXTI_GET_IT(mask) != RESET) { + __HAL_GPIO_EXTI_CLEAR_IT(mask); + gpio_irq_handlers[index].isr(gpio_irq_handlers[index].arg); + } +} + +/* External interrupt 0 */ +static void +ext_irq0(void) +{ + ++ext_irq_counts.irq0; + ext_irq_handler(0); +} + +/* External interrupt 1 */ +static void +ext_irq1(void) +{ + ++ext_irq_counts.irq1; + ext_irq_handler(1); +} + +/* External interrupt 2 */ +static void +ext_irq2(void) +{ + ++ext_irq_counts.irq2; + ext_irq_handler(2); +} + +/* External interrupt 3 */ +static void +ext_irq3(void) +{ + ++ext_irq_counts.irq3; + ext_irq_handler(3); +} + +/** + * ext irq4 + * + * External interrupt handler for external interrupt 4. + * + */ +static void +ext_irq4(void) +{ + ++ext_irq_counts.irq4; + ext_irq_handler(4); +} + +/** + * ext irq9_5 + * + * External interrupt handler for irqs 9 through 5. + * + */ +static void +ext_irq9_5(void) +{ + int index; + + ++ext_irq_counts.irq9_5; + for (index = 5; index <= 9; ++index) { + ext_irq_handler(index); + } +} + +/** + * ext irq15_10 + * + * External interrupt handler for irqs 15 through 10. + * + */ +static void +ext_irq15_10(void) +{ + int index; + + ++ext_irq_counts.irq15_10; + for (index = 10; index <= 15; ++index) { + ext_irq_handler(index); + } +} + +/** + * hal gpio clk enable + * + * Enable the port peripheral clock + * + * @param port_idx + */ +static void +hal_gpio_clk_enable(uint32_t port_idx) +{ + switch (port_idx) { + case 0: + __HAL_RCC_GPIOA_CLK_ENABLE(); + break; + case 1: + __HAL_RCC_GPIOB_CLK_ENABLE(); + break; + case 2: + __HAL_RCC_GPIOC_CLK_ENABLE(); + break; + case 3: + __HAL_RCC_GPIOD_CLK_ENABLE(); + break; + case 4: + __HAL_RCC_GPIOE_CLK_ENABLE(); + break; +#if defined GPIOF_BASE + case 5: + __HAL_RCC_GPIOF_CLK_ENABLE(); + break; +#endif +#if defined GPIOG_BASE + case 6: + __HAL_RCC_GPIOG_CLK_ENABLE(); + break; +#endif +#if defined GPIOH_BASE + case 7: + __HAL_RCC_GPIOH_CLK_ENABLE(); + break; +#endif +#if defined GPIOI_BASE + case 8: + __HAL_RCC_GPIOI_CLK_ENABLE(); + break; +#endif +#if defined GPIOJ_BASE + case 9: + __HAL_RCC_GPIOJ_CLK_ENABLE(); + break; +#endif +#if defined GPIOK_BASE + case 10: + __HAL_RCC_GPIOK_CLK_ENABLE(); + break; +#endif + default: + assert(0); + break; + } +} + +/** + * hal gpio pin to irq + * + * Converts the logical pin number to the IRQ number associated with the + * external interrupt for that particular GPIO. + * + * @param pin + * + * @return IRQn_Type + */ +static IRQn_Type +hal_gpio_pin_to_irq(int pin) +{ + int index; + IRQn_Type irqn; + + index = GPIO_INDEX(pin); + if (index <= 4) { + irqn = GPIOTE_IRQn + index; + } else if (index <= 9) { + irqn = EXTI9_5_IRQn; + } else { + irqn = EXTI15_10_IRQn; + } + + return irqn; +} +#endif + +static void +hal_gpio_set_nvic(IRQn_Type irqn) +{ +#if 0 + uint32_t isr; + + switch (irqn) { + case EXTI0_IRQn: + isr = (uint32_t)&ext_irq0; + break; + case EXTI1_IRQn: + isr = (uint32_t)&ext_irq1; + break; + case EXTI2_IRQn: + isr = (uint32_t)&ext_irq2; + break; + case EXTI3_IRQn: + isr = (uint32_t)&ext_irq3; + break; + case EXTI4_IRQn: + isr = (uint32_t)&ext_irq4; + break; + case EXTI9_5_IRQn: + isr = (uint32_t)&ext_irq9_5; + break; + case EXTI15_10_IRQn: + isr = (uint32_t)&ext_irq15_10; + break; + default: + assert(0); + break; + } + + /* Set isr in vector table if not yet set */ + if (NVIC_GetVector(irqn) != isr) { + NVIC_SetVector(irqn, isr); + NVIC_EnableIRQ(irqn); + } +#endif +} + +/** + * gpio init in + * + * Initializes the specified pin as an input + * + * @param pin Pin number to set as input + * @param pull pull type + * + * @return int 0: no error; -1 otherwise. + */ +int +gpio_init_in(int pin, gpio_pull_t pull) +{ + uint32_t conf; + + switch (pull) { + case GPIO_PULL_UP: + conf = GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos; + break; + case GPIO_PULL_DOWN: + conf = GPIO_PIN_CNF_PULL_Pulldown << GPIO_PIN_CNF_PULL_Pos; + break; + case GPIO_PULL_NONE: + default: + conf = 0; + break; + } + + NRF_GPIO->PIN_CNF[pin] = conf; + NRF_GPIO->DIRCLR = GPIO_MASK(pin); + + return 0; +} + +/** + * gpio init out + * + * Initialize the specified pin as an output, setting the pin to the specified + * value. + * + * @param pin Pin number to set as output + * @param val Value to set pin + * + * @return int 0: no error; -1 otherwise. + */ +int gpio_init_out(int pin, int val) +{ + if (val) { + NRF_GPIO->OUTSET = GPIO_MASK(pin); + } else { + NRF_GPIO->OUTCLR = GPIO_MASK(pin); + } + NRF_GPIO->PIN_CNF[pin] = GPIO_PIN_CNF_DIR_Output; + NRF_GPIO->DIRSET = GPIO_MASK(pin); + return 0; +} + +/** + * gpio set + * + * Sets specified pin to 1 (high) + * + * @param pin + */ +void gpio_set(int pin) +{ + NRF_GPIO->OUTSET = GPIO_MASK(pin); +} + +/** + * gpio clear + * + * Sets specified pin to 0 (low). + * + * @param pin + */ +void gpio_clear(int pin) +{ + NRF_GPIO->OUTCLR = GPIO_MASK(pin); +} + +/** + * gpio write + * + * Write a value (either high or low) to the specified pin. + * + * @param pin Pin to set + * @param val Value to set pin (0:low 1:high) + */ +void gpio_write(int pin, int val) +{ + if (val) { + gpio_set(pin); + } else { + gpio_clear(pin); + } +} + +/** + * gpio read + * + * Reads the specified pin. + * + * @param pin Pin number to read + * + * @return int 0: low, 1: high + */ +int gpio_read(int pin) +{ + return (NRF_GPIO->IN & GPIO_MASK(pin)); +} + +/** + * gpio toggle + * + * Toggles the specified pin + * + * @param pin Pin number to toggle + */ +void gpio_toggle(int pin) +{ + if (gpio_read(pin)) { + gpio_clear(pin); + } else { + gpio_set(pin); + } +} + +/** + * gpio irq init + * + * Initialize an external interrupt on a gpio pin + * + * @param pin Pin number to enable gpio. + * @param handler Interrupt handler + * @param arg Argument to pass to interrupt handler + * @param trig Trigger mode of interrupt + * @param pull Push/pull mode of input. + * + * @return int + */ +int +gpio_irq_init(int pin, gpio_irq_handler_t handler, void *arg, + gpio_irq_trig_t trig, gpio_pull_t pull) +{ +#if 0 + int rc; + int irqn; + int index; + uint32_t pin_mask; + uint32_t mode; + GPIO_InitTypeDef init_cfg; + + /* Configure the gpio for an external interrupt */ + rc = 0; + switch (trig) { + case GPIO_TRIG_NONE: + rc = -1; + break; + case GPIO_TRIG_RISING: + mode = GPIO_MODE_IT_RISING; + break; + case GPIO_TRIG_FALLING: + mode = GPIO_MODE_IT_FALLING; + break; + case GPIO_TRIG_BOTH: + mode = GPIO_MODE_IT_RISING_FALLING; + break; + case GPIO_TRIG_LOW: + rc = -1; + break; + case GPIO_TRIG_HIGH: + rc = -1; + break; + default: + rc = -1; + break; + } + + /* Check to make sure no error has occurred */ + if (!rc) { + /* Disable interrupt and clear any pending */ + gpio_irq_disable(pin); + pin_mask = GPIO_MASK(pin); + __HAL_GPIO_EXTI_CLEAR_FLAG(pin_mask); + + /* Set the gpio irq handler */ + index = GPIO_INDEX(pin); + gpio_irq_handlers[index].isr = handler; + gpio_irq_handlers[index].arg = arg; + + /* Configure the GPIO */ + init_cfg.Mode = mode; + init_cfg.Pull = pull; + rc = hal_gpio_init(pin, &init_cfg); + if (!rc) { + /* Enable interrupt vector in NVIC */ + irqn = hal_gpio_pin_to_irq(pin); + hal_gpio_set_nvic(irqn); + } + } + + return rc; +#else + hal_gpio_set_nvic(0); + return 0; +#endif +} + +/** + * gpio irq release + * + * No longer interrupt when something occurs on the pin. NOTE: this function + * does not change the GPIO push/pull setting nor does it change the + * SYSCFG EXTICR registers. It also does not disable the NVIC interrupt enable + * setting for the irq. + * + * @param pin + */ +void +gpio_irq_release(int pin) +{ +#if 0 + int index; + uint32_t pin_mask; + + /* Disable the interrupt */ + gpio_irq_disable(pin); + + /* Clear any pending interrupts */ + pin_mask = GPIO_MASK(pin); + __HAL_GPIO_EXTI_CLEAR_FLAG(pin_mask); + + /* Clear out the irq handler */ + index = GPIO_INDEX(pin); + gpio_irq_handlers[index].arg = NULL; + gpio_irq_handlers[index].isr = NULL; +#else + return; +#endif +} + +/** + * gpio irq enable + * + * Enable the irq on the specified pin + * + * @param pin + */ +void +gpio_irq_enable(int pin) +{ +#if 0 + uint32_t ctx; + uint32_t mask; + + mask = GPIO_MASK(pin); + + __HAL_DISABLE_INTERRUPTS(ctx); + EXTI->IMR |= mask; + __HAL_ENABLE_INTERRUPTS(ctx); +#else + return; +#endif +} + +/** + * gpio irq disable + * + * + * @param pin + */ +void +gpio_irq_disable(int pin) +{ +#if 0 + uint32_t ctx; + uint32_t mask; + + mask = GPIO_MASK(pin); + __HAL_DISABLE_INTERRUPTS(ctx); + EXTI->IMR &= ~mask; + __HAL_ENABLE_INTERRUPTS(ctx); +#else + return; +#endif +} http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/826d3a57/hw/mcu/nordic/nrf51xxx/src/hal_system.c ---------------------------------------------------------------------- diff --git a/hw/mcu/nordic/nrf51xxx/src/hal_system.c b/hw/mcu/nordic/nrf51xxx/src/hal_system.c new file mode 100644 index 0000000..f8c74f9 --- /dev/null +++ b/hw/mcu/nordic/nrf51xxx/src/hal_system.c @@ -0,0 +1,26 @@ +/** + * Copyright (c) 2015 Runtime Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <mcu/cortex_m0.h> +#include "hal/hal_system.h" + +void +system_reset(void) +{ + while (1) { + NVIC_SystemReset(); + } +} http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/826d3a57/hw/mcu/nordic/nrf51xxx/src/hal_uart.c ---------------------------------------------------------------------- diff --git a/hw/mcu/nordic/nrf51xxx/src/hal_uart.c b/hw/mcu/nordic/nrf51xxx/src/hal_uart.c new file mode 100644 index 0000000..66a230c --- /dev/null +++ b/hw/mcu/nordic/nrf51xxx/src/hal_uart.c @@ -0,0 +1,295 @@ +/** + * Copyright (c) 2015 Runtime Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "hal/hal_uart.h" +#include "bsp/cmsis_nvic.h" +#include "bsp/bsp.h" + +#include "mcu/nrf.h" +#include "mcu/nrf51_hal.h" + +#include <assert.h> + +#define UART_INT_TXDRDY UART_INTENSET_TXDRDY_Msk +#define UART_INT_RXDRDY UART_INTENSET_RXDRDY_Msk +#define UART_CONFIG_PARITY UART_CONFIG_PARITY_Msk +#define UART_CONFIG_HWFC UART_CONFIG_HWFC_Msk +#define UART_ENABLE UART_ENABLE_ENABLE_Enabled + +/* Only one UART on NRF 51xxx. */ +struct hal_uart { + uint8_t u_open:1; + uint8_t u_rx_stall:1; + uint8_t u_tx_started:1; + uint8_t u_rx_buf; + uint8_t u_tx_buf; + hal_uart_rx_char u_rx_func; + hal_uart_tx_char u_tx_func; + hal_uart_tx_done u_tx_done; + void *u_func_arg; +}; +static struct hal_uart uart; + +int +hal_uart_init_cbs(int port, hal_uart_tx_char tx_func, hal_uart_tx_done tx_done, + hal_uart_rx_char rx_func, void *arg) +{ + struct hal_uart *u; + + if (port != 0) { + return -1; + } + u = &uart; + if (u->u_open) { + return -1; + } + u->u_rx_func = rx_func; + u->u_tx_func = tx_func; + u->u_tx_done = tx_done; + u->u_func_arg = arg; + return 0; +} + +static int +hal_uart_tx_fill_buf(struct hal_uart *u) +{ + int data; + int i; + + i = 0; + data = u->u_tx_func(u->u_func_arg); + if (data < 0) { + u->u_tx_buf = data; + i = 1; + } + return i; +} + +void +hal_uart_start_tx(int port) +{ + struct hal_uart *u; + int sr; + int rc; + + u = &uart; + __HAL_DISABLE_INTERRUPTS(sr); + if (u->u_tx_started == 0) { + rc = hal_uart_tx_fill_buf(u); + if (rc > 0) { + NRF_UART0->INTENSET = UART_INT_TXDRDY; + NRF_UART0->TXD = u->u_tx_buf; + NRF_UART0->TASKS_STARTTX = 1; + u->u_tx_started = 1; + } + } + __HAL_ENABLE_INTERRUPTS(sr); +} + +void +hal_uart_start_rx(int port) +{ + struct hal_uart *u; + int sr; + int rc; + + u = &uart; + if (u->u_rx_stall) { + __HAL_DISABLE_INTERRUPTS(sr); + rc = u->u_rx_func(u->u_func_arg, u->u_rx_buf); + if (rc == 0) { + u->u_rx_stall = 0; + NRF_UART0->TASKS_STARTRX = 1; + } + + __HAL_ENABLE_INTERRUPTS(sr); + } +} + +void +hal_uart_blocking_tx(int port, uint8_t data) +{ + struct hal_uart *u; + + u = &uart; + if (!u->u_open) { + return; + } + + /* If we have started, wait until the current uart dma buffer is done */ + if (u->u_tx_started) { + while (NRF_UART0->EVENTS_TXDRDY == 0) { + /* Wait here until the dma is finished */ + } + } + + NRF_UART0->EVENTS_TXDRDY = 0; + NRF_UART0->TXD = (uint32_t)data; + NRF_UART0->TASKS_STARTTX = 1; + + while (NRF_UART0->EVENTS_TXDRDY == 0) { + /* Wait till done */ + } + + /* Stop the uart */ + NRF_UART0->TASKS_STOPTX = 1; +} + +static void +uart_irq_handler(void) +{ + struct hal_uart *u; + int rc; + + u = &uart; + if (NRF_UART0->EVENTS_TXDRDY) { + NRF_UART0->EVENTS_TXDRDY = 0; + rc = hal_uart_tx_fill_buf(u); + if (rc > 0) { + NRF_UART0->TXD = u->u_tx_buf; + NRF_UART0->TASKS_STARTTX = 1; + } else { + if (u->u_tx_done) { + u->u_tx_done(u->u_func_arg); + } + NRF_UART0->INTENCLR = UART_INT_TXDRDY; + NRF_UART0->TASKS_STOPTX = 1; + u->u_tx_started = 0; + } + } + if (NRF_UART0->EVENTS_RXDRDY) { + NRF_UART0->EVENTS_RXDRDY = 0; + rc = u->u_rx_func(u->u_func_arg, u->u_rx_buf); + if (rc < 0) { + u->u_rx_stall = 1; + } else { + NRF_UART0->TASKS_STARTRX = 1; + } + } +} + +static uint32_t +hal_uart_baudrate(int baudrate) +{ + switch (baudrate) { + case 9600: + return UART_BAUDRATE_BAUDRATE_Baud9600; + case 19200: + return UART_BAUDRATE_BAUDRATE_Baud19200; + case 38400: + return UART_BAUDRATE_BAUDRATE_Baud38400; + case 57600: + return UART_BAUDRATE_BAUDRATE_Baud57600; + case 115200: + return UART_BAUDRATE_BAUDRATE_Baud115200; + case 230400: + return UART_BAUDRATE_BAUDRATE_Baud230400; + case 460800: + return UART_BAUDRATE_BAUDRATE_Baud460800; + case 921600: + return UART_BAUDRATE_BAUDRATE_Baud921600; + default: + return 0; + } +} + +int +hal_uart_config(int port, int32_t baudrate, uint8_t databits, uint8_t stopbits, + enum hal_uart_parity parity, enum hal_uart_flow_ctl flow_ctl) +{ + struct hal_uart *u; + const struct nrf51_uart_cfg *cfg; + uint32_t cfg_reg = 0; + uint32_t baud_reg; + + if (port != 0) { + return -1; + } + + u = &uart; + if (u->u_open) { + return -1; + } + cfg = bsp_uart_config(); + assert(cfg); + + /* + * pin config + * UART config + * nvic config + * enable uart + */ + if (databits != 8) { + return -1; + } + if (stopbits != 1) { + return -1; + } + + switch (parity) { + case HAL_UART_PARITY_NONE: + break; + case HAL_UART_PARITY_ODD: + return -1; + case HAL_UART_PARITY_EVEN: + cfg_reg |= UART_CONFIG_PARITY; + break; + } + + switch (flow_ctl) { + case HAL_UART_FLOW_CTL_NONE: + break; + case HAL_UART_FLOW_CTL_RTS_CTS: + cfg_reg |= UART_CONFIG_HWFC; + if (cfg->suc_pin_rts < 0 || cfg->suc_pin_cts < 0) { + /* + * Can't turn on HW flow control if pins to do that are not + * defined. + */ + assert(0); + return -1; + } + break; + } + baud_reg = hal_uart_baudrate(baudrate); + if (baud_reg == 0) { + return -1; + } + NRF_UART0->ENABLE = 0; + NRF_UART0->INTENCLR = 0xffffffff; + NRF_UART0->PSELTXD = cfg->suc_pin_tx; + NRF_UART0->PSELRXD = cfg->suc_pin_rx; + if (flow_ctl == HAL_UART_FLOW_CTL_RTS_CTS) { + NRF_UART0->PSELRTS = cfg->suc_pin_rts; + NRF_UART0->PSELCTS = cfg->suc_pin_cts; + } else { + NRF_UART0->PSELRTS = 0xffffffff; + NRF_UART0->PSELCTS = 0xffffffff; + } + NRF_UART0->BAUDRATE = baud_reg; + NRF_UART0->CONFIG = cfg_reg; + + NVIC_SetVector(UART0_IRQn, (uint32_t)uart_irq_handler); + NVIC_EnableIRQ(UART0_IRQn); + + NRF_UART0->ENABLE = UART_ENABLE; + NRF_UART0->INTENSET = UART_INT_RXDRDY; + NRF_UART0->TASKS_STARTRX = 1; + + u->u_open = 1; + + return 0; +}