ported-fixed for nRF52840 port + serial + analog + pin description + gpio + cmsis vector opp + gcc startup/scater file

pull/4134/head
Andrzej Puzdrowski 2016-12-23 15:33:39 +01:00 committed by Anna Bridge
parent b313873683
commit 4a38ec8b83
15 changed files with 255 additions and 643 deletions

View File

@ -1,399 +0,0 @@
/*
* Copyright (c) 2013 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:
*
* 1. Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic Semiconductor ASA
* integrated circuit in a product or a software update for such product, 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.
*
* 3. 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.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary or object form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* 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.
*
*/
#include "mbed_assert.h"
#include "mbed_error.h"
#include "pwmout_api.h"
#include "cmsis.h"
#include "pinmap.h"
#if DEVICE_PWMOUT
#include "app_util_platform.h"
#include "nrf_drv_pwm.h"
#define MAX_PWM_COUNTERTOP (0x7FFF) // 0x7FFF is the max of COUNTERTOP value for the PWM peripherial of the nRF52.
#define MAX_PWM_PERIOD_US (MAX_PWM_COUNTERTOP * 8) // PWM hw is driven by 16 MHz clock, hence the tick is 1_us/16,
// and 128 is the max prescaler value.
#define MAX_PWM_PERIOD_MS ((MAX_PWM_PERIOD_US / 1000) + 1) // approximations advance
#define MAX_PWM_PERIOD_S ((MAX_PWM_PERIOD_US / 1000000) + 1) // approximations advance
#define PWM_INSTANCE_COUNT (PWM_COUNT) // import from the nrf_drv_config.h file
///> instances of nRF52 PWM driver
static const nrf_drv_pwm_t m_pwm_driver[PWM_INSTANCE_COUNT] =
{
#if PWM0_ENABLED
NRF_DRV_PWM_INSTANCE(0),
#endif
#if PWM1_ENABLED
NRF_DRV_PWM_INSTANCE(1),
#endif
#if PWM2_ENABLED
NRF_DRV_PWM_INSTANCE(2)
#endif
};
typedef struct
{
uint32_t period_us;
uint32_t duty_us;
float duty;
} pwm_signal_t; /// PWM signal description type
typedef struct
{
nrf_drv_pwm_t * p_pwm_driver;
pwm_signal_t signal;
volatile nrf_pwm_values_common_t seq_values[1];
} pwm_t; /// internal PWM instance support type
static pwm_t m_pwm[PWM_INSTANCE_COUNT] =
{
#if PWM0_ENABLED
{.p_pwm_driver = NULL},
#endif
#if PWM1_ENABLED
{.p_pwm_driver = NULL},
#endif
#if PWM2_ENABLED
{.p_pwm_driver = NULL}
#endif
}; /// Array of internal PWM instances.
typedef struct
{
uint16_t period_hwu; // unit related to pwm_clk
uint16_t duty_hwu; // unit related to pwm_clk
nrf_pwm_clk_t pwm_clk;
} pulsewidth_set_t; /// helper type for timing calculations
static void internal_pwmout_exe(pwmout_t *obj, bool new_period, bool initialization);
// extern PWM nIRQ handler implementations
void PWM0_IRQHandler(void);
void PWM1_IRQHandler(void);
void PWM2_IRQHandler(void);
static const peripheral_handler_desc_t pwm_handlers[PWM_INSTANCE_COUNT] =
{
{
PWM0_IRQn,
(uint32_t)PWM0_IRQHandler
},
{
PWM1_IRQn,
(uint32_t)PWM1_IRQHandler
},
{
PWM2_IRQn,
(uint32_t)PWM2_IRQHandler
}
};
void pwmout_init(pwmout_t *obj, PinName pin)
{
uint32_t i;
for (i = 0; PWM_INSTANCE_COUNT; i++)
{
if (m_pwm[i].p_pwm_driver == NULL) // a driver instance not assigned to the obj?
{
NVIC_SetVector(pwm_handlers[i].IRQn, pwm_handlers[i].vector);
obj->pin = pin;
obj->pwm_channel = i;
m_pwm[i].p_pwm_driver = (nrf_drv_pwm_t *) &m_pwm_driver[i];
m_pwm[i].signal.period_us = 200000; // 0.02 s
m_pwm[i].signal.duty_us = 100000;
m_pwm[i].signal.duty = 0.5f;
obj->pwm_struct = &m_pwm[i];
internal_pwmout_exe(obj, true, true);
break;
}
}
MBED_ASSERT(i != PWM_INSTANCE_COUNT); // assert if free instance was not found.
}
void pwmout_free(pwmout_t *obj)
{
nrf_drv_pwm_uninit( (nrf_drv_pwm_t*) obj->pwm_struct );
m_pwm[obj->pwm_channel].p_pwm_driver = NULL;
}
void pwmout_write(pwmout_t *obj, float percent)
{
if (percent < 0)
{
percent = 0;
}
else if (percent > 1)
{
percent = 1;
}
pwm_signal_t * p_pwm_signal = &(((pwm_t*)obj->pwm_struct)->signal);
p_pwm_signal->duty = percent;
int us = (((int)p_pwm_signal->period_us) * percent);
pwmout_pulsewidth_us(obj, us);
}
float pwmout_read(pwmout_t *obj)
{
pwm_signal_t * p_pwm_signal = &(((pwm_t*)obj->pwm_struct)->signal);
return (float)p_pwm_signal->duty_us / (float)p_pwm_signal->period_us;
}
void pwmout_period(pwmout_t *obj, float seconds)
{
// raught saturation < 0, quasi-max>
if (seconds > MAX_PWM_PERIOD_S)
{
seconds = MAX_PWM_PERIOD_S;
}
else if (seconds < 0)
{
seconds = 0; // f. pwmout_period_us will set period to min. value
}
int us = seconds * 1000000;
pwmout_period_us(obj, us);
}
void pwmout_period_ms(pwmout_t *obj, int ms)
{
// reught saturation < 0, quasi-max>
if (ms > MAX_PWM_PERIOD_MS)
{
ms = MAX_PWM_PERIOD_MS;
}
else if (ms < 0)
{
ms = 0; // f. pwmout_period_us will set period to min. value
}
int us = ms * 1000;
pwmout_period_us(obj, us);
}
void pwmout_period_us(pwmout_t *obj, int us)
{
pwm_signal_t * p_pwm_signal = &(((pwm_t*)obj->pwm_struct)->signal);
// saturation <1, real-max>
if (us > MAX_PWM_PERIOD_US)
{
us = MAX_PWM_PERIOD_US;
}
else if (us < 1)
{
us = 1;
}
p_pwm_signal->duty_us = (int)((float)us * p_pwm_signal->duty);
p_pwm_signal->period_us = us;
internal_pwmout_exe(obj, true, false);
}
void pwmout_pulsewidth(pwmout_t *obj, float seconds)
{
// raught saturation < 0, quasi-max>
if (seconds > MAX_PWM_PERIOD_S)
{
seconds = MAX_PWM_PERIOD_S;
}
else if (seconds < 0)
{
seconds = 0;
}
int us = seconds * 1000000;
pwmout_pulsewidth_us(obj,us);
}
void pwmout_pulsewidth_ms(pwmout_t *obj, int ms)
{
// raught saturation < 0, quasi-max>
if (ms > MAX_PWM_PERIOD_MS)
{
ms = MAX_PWM_PERIOD_MS;
}
else if (ms < 0)
{
ms = 0;
}
int us = ms * 1000;
pwmout_pulsewidth_us(obj, us);
}
void pwmout_pulsewidth_us(pwmout_t *obj, int us)
{
// saturation <0, real-max>
if (us > MAX_PWM_PERIOD_US)
{
us = MAX_PWM_PERIOD_US;
}
else if (us < 0)
{
us = 0;
}
pwm_signal_t * p_pwm_signal = &(((pwm_t*)obj->pwm_struct)->signal);
p_pwm_signal->duty_us = us;
p_pwm_signal->duty = us / p_pwm_signal->period_us;
internal_pwmout_exe(obj, false, false);
}
static ret_code_t pulsewidth_us_set_get(int period_hwu, int duty_hwu, pulsewidth_set_t * p_settings)
{
uint16_t div;
nrf_pwm_clk_t pwm_clk = NRF_PWM_CLK_16MHz;
for(div = 1; div <= 128 ; div <<= 1) // 128 is the maximum of clock prescaler for PWM peripherial
{
if (MAX_PWM_COUNTERTOP >= period_hwu)
{
p_settings->period_hwu = period_hwu; // unit [us/16 * div]
p_settings->duty_hwu = duty_hwu; // unit [us/16 * div]
p_settings->pwm_clk = pwm_clk;
return NRF_SUCCESS;
}
period_hwu >>= 1;
duty_hwu >>= 1;
pwm_clk++;
}
return NRF_ERROR_INVALID_PARAM;
}
static void internal_pwmout_exe(pwmout_t *obj, bool new_period, bool initialization)
{
pulsewidth_set_t pulsewidth_set;
pwm_signal_t * p_pwm_signal;
nrf_drv_pwm_t * p_pwm_driver;
ret_code_t ret_code;
p_pwm_signal = &(((pwm_t*)obj->pwm_struct)->signal);
if (NRF_SUCCESS == pulsewidth_us_set_get(p_pwm_signal->period_us * 16, // base clk for PWM is 16 MHz
p_pwm_signal->duty_us * 16, // base clk for PWM is 16 MHz
&pulsewidth_set))
{
p_pwm_driver = (((pwm_t*)obj->pwm_struct)->p_pwm_driver);
const nrf_pwm_sequence_t seq =
{
.values.p_common = (nrf_pwm_values_common_t*) (((pwm_t*)obj->pwm_struct)->seq_values),
.length = 1,
.repeats = 0,
.end_delay = 0
};
(((pwm_t*)obj->pwm_struct)->seq_values)[0] = pulsewidth_set.duty_hwu | 0x8000;
if (new_period)
{
nrf_drv_pwm_config_t config0 =
{
.output_pins =
{
obj->pin | NRF_DRV_PWM_PIN_INVERTED, // channel 0
NRF_DRV_PWM_PIN_NOT_USED, // channel 1
NRF_DRV_PWM_PIN_NOT_USED, // channel 2
NRF_DRV_PWM_PIN_NOT_USED, // channel 3
},
.irq_priority = PWM0_CONFIG_IRQ_PRIORITY,
.base_clock = pulsewidth_set.pwm_clk,
.count_mode = NRF_PWM_MODE_UP,
.top_value = pulsewidth_set.period_hwu,
.load_mode = NRF_PWM_LOAD_COMMON,
.step_mode = NRF_PWM_STEP_AUTO
};
if (!initialization)
{
nrf_drv_pwm_uninit(p_pwm_driver);
}
ret_code = nrf_drv_pwm_init( p_pwm_driver, &config0, NULL);
MBED_ASSERT(ret_code == NRF_SUCCESS); // assert if free instance was not found.
}
nrf_drv_pwm_simple_playback(p_pwm_driver, &seq, 0, NRF_DRV_PWM_FLAG_LOOP);
}
else
{
MBED_ASSERT(0); // force assertion
}
}
#endif // DEVICE_PWMOUT

View File

@ -44,7 +44,8 @@ extern "C" {
#endif
typedef enum {
Port0 = 0 //GPIO pins 0-31
Port0 = 0, //GPIO pins 0-31 -> 0.0-0.31
Port1 = 1 //GPIO pins 32-47 -> 1.0-1.15
} PortName;
#ifdef __cplusplus

View File

@ -40,6 +40,7 @@
#define MBED_PINNAMES_H
#include "cmsis.h"
#include "nrf_gpio.h"
#ifdef __cplusplus
extern "C" {
@ -52,85 +53,122 @@ typedef enum {
#define PORT_SHIFT 3
typedef enum {
p0 = 0,
p1 = 1,
p2 = 2,
p3 = 3,
p4 = 4,
p5 = 5,
p6 = 6,
p7 = 7,
p8 = 8,
p9 = 9,
p10 = 10,
p11 = 11,
p12 = 12,
p13 = 13,
p14 = 14,
p15 = 15,
p16 = 16,
p17 = 17,
p18 = 18,
p19 = 19,
p20 = 20,
p21 = 21,
p22 = 22,
p23 = 23,
p24 = 24,
p25 = 25,
p26 = 26,
p27 = 27,
p28 = 28,
p29 = 29,
p30 = 30,
p31 = 31,
///> define macro producing for example Px_y = NRF_GPIO_PIN_MAP(x, y)
#define PinDef(port_num, pin_num) P##port_num##_##pin_num = NRF_GPIO_PIN_MAP(port_num, pin_num)
P0_0 = p0,
P0_1 = p1,
P0_2 = p2,
P0_3 = p3,
P0_4 = p4,
P0_5 = p5,
P0_6 = p6,
P0_7 = p7,
P0_8 = p8,
P0_9 = p9,
P0_10 = p10,
P0_11 = p11,
P0_12 = p12,
P0_13 = p13,
P0_14 = p14,
P0_15 = p15,
typedef enum {
PinDef(0 , 0), // P0_0 = 0...
PinDef(0 , 1),
PinDef(0 , 2),
PinDef(0 , 3),
PinDef(0 , 4),
PinDef(0 , 5),
PinDef(0 , 6),
PinDef(0 , 7),
PinDef(0 , 8),
PinDef(0 , 9),
PinDef(0 , 10),
PinDef(0 , 11),
PinDef(0 , 12),
PinDef(0 , 13),
PinDef(0 , 14),
PinDef(0 , 15),
PinDef(0 , 16),
PinDef(0 , 17),
PinDef(0 , 18),
PinDef(0 , 19),
PinDef(0 , 20),
PinDef(0 , 21),
PinDef(0 , 22),
PinDef(0 , 23),
PinDef(0 , 24),
PinDef(0 , 25),
PinDef(0 , 26),
PinDef(0 , 27),
PinDef(0 , 28),
PinDef(0 , 29),
PinDef(0 , 30),
PinDef(0 , 31),
PinDef(1 , 0), //P1_1 = 32...
PinDef(1 , 1),
PinDef(1 , 2),
PinDef(1 , 3),
PinDef(1 , 4),
PinDef(1 , 5),
PinDef(1 , 6),
PinDef(1 , 7),
PinDef(1 , 8),
PinDef(1 , 9),
PinDef(1 , 10),
PinDef(1 , 11),
PinDef(1 , 12),
PinDef(1 , 13),
PinDef(1 , 14),
PinDef(1 , 15),
// Port0
p0 = P0_0,
p1 = P0_1,
p2 = P0_2,
p3 = P0_3,
p4 = P0_4,
p5 = P0_5,
p6 = P0_6,
p7 = P0_7,
p8 = P0_8,
p9 = P0_9,
p10 = P0_10,
p11 = P0_11,
p12 = P0_12,
p13 = P0_13,
p14 = P0_14,
p15 = P0_15,
p16 = P0_16,
p17 = P0_17,
p18 = P0_18,
p19 = P0_19,
p20 = P0_20,
p21 = P0_21,
p22 = P0_22,
p23 = P0_23,
p24 = P0_24,
p25 = P0_25,
p26 = P0_26,
p27 = P0_27,
p28 = P0_28,
p29 = P0_29,
p30 = P0_30,
p31 = P0_31,
// Port1
p32 = P1_0,
p33 = P1_1,
p34 = P1_2,
p35 = P1_3,
p36 = P1_4,
p37 = P1_5,
p38 = P1_6,
p39 = P1_7,
p40 = P1_8,
p41 = P1_9,
p42 = P1_10,
p43 = P1_11,
p44 = P1_12,
p45 = P1_13,
p46 = P1_14,
p47 = P1_15,
LED1 = p13,
LED2 = p14,
LED3 = p15,
LED4 = p16,
P0_16 = p16,
P0_17 = p17,
P0_18 = p18,
P0_19 = p19,
P0_20 = p20,
P0_21 = p21,
P0_22 = p22,
P0_23 = p23,
P0_24 = p24,
P0_25 = p25,
P0_26 = p26,
P0_27 = p27,
P0_28 = p28,
P0_29 = p29,
P0_30 = p30,
P0_31 = p31,
LED1 = p17,
LED2 = p18,
LED3 = p19,
LED4 = p20,
BUTTON1 = p13,
BUTTON2 = p14,
BUTTON3 = p15,
BUTTON4 = p16,
BUTTON1 = p11,
BUTTON2 = p12,
BUTTON3 = p24,
BUTTON4 = p25,
RX_PIN_NUMBER = p8,
TX_PIN_NUMBER = p6,
@ -141,39 +179,39 @@ typedef enum {
USBTX = TX_PIN_NUMBER,
USBRX = RX_PIN_NUMBER,
SPI_PSELMOSI0 = p23,
SPI_PSELMISO0 = p24,
SPI_PSELSS0 = p22,
SPI_PSELSCK0 = p25,
SPI_PSELMOSI0 = P1_13,
SPI_PSELMISO0 = P1_14,
SPI_PSELSS0 = P1_12,
SPI_PSELSCK0 = P1_15,
SPI_PSELMOSI1 = p12,
SPI_PSELMISO1 = p13,
SPI_PSELSS1 = p11,
SPI_PSELSCK1 = p14,
SPI_PSELMOSI1 = P1_2,
SPI_PSELMISO1 = P1_3,
SPI_PSELSS1 = P1_1,
SPI_PSELSCK1 = P1_4,
SPIS_PSELMOSI = p12,
SPIS_PSELMISO = p13,
SPIS_PSELSS = p11,
SPIS_PSELSCK = p14,
SPIS_PSELMOSI = P1_2,
SPIS_PSELMISO = P1_3,
SPIS_PSELSS = P1_1,
SPIS_PSELSCK = P1_4,
I2C_SDA0 = p26,
I2C_SCL0 = p27,
D0 = p11,
D1 = p12,
D2 = p13,
D3 = p14,
D4 = p15,
D5 = p16,
D6 = p17,
D7 = p18,
D0 = P1_1,
D1 = P1_2,
D2 = P1_3,
D3 = P1_4,
D4 = P1_5,
D5 = P1_6,
D6 = P1_7,
D7 = P1_8,
D8 = p19,
D9 = p20,
D10 = p22,
D11 = p23,
D12 = p24,
D13 = p25,
D8 = P1_10,
D9 = P1_11,
D10 = P1_12,
D11 = P1_13,
D12 = P1_14,
D13 = P1_15,
D14 = p26,
D15 = p27,

View File

@ -1,91 +0,0 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
*
* 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 "mbed_assert.h"
#include "analogin_api.h"
#include "cmsis.h"
#include "pinmap.h"
#include "app_util_platform.h"
#include "nrf_drv_saadc.h"
#ifdef DEVICE_ANALOGIN
#define ADC_12BIT_RANGE 0xFFF
#define ADC_RANGE ADC_12BIT_RANGE
static void analog_in_event_handler(nrf_drv_saadc_evt_t const *p_event)// type of nrf_drv_saadc_event_handler_t
{
(void) p_event;
}
static const nrf_drv_saadc_config_t saadc_config =
{
.resolution = NRF_SAADC_RESOLUTION_12BIT,
.oversample = NRF_SAADC_OVERSAMPLE_DISABLED,
.interrupt_priority = SAADC_CONFIG_IRQ_PRIORITY
};
void SAADC_IRQHandler(void);
void analogin_init(analogin_t *obj, PinName pin)
{
ret_code_t ret_code;
NVIC_SetVector(SAADC_IRQn, (uint32_t)SAADC_IRQHandler);
ret_code = nrf_drv_saadc_init(&saadc_config, analog_in_event_handler);
MBED_ASSERT(((ret_code == NRF_SUCCESS) || (ret_code == NRF_ERROR_INVALID_STATE))); //NRF_ERROR_INVALID_STATE expected for multiple channels used.
uint8_t saadcIn = nrf_drv_saadc_gpio_to_ain(pin);
MBED_ASSERT(saadcIn != NRF_SAADC_INPUT_DISABLED);
obj->adc = ADC0_0; // only one instance of ADC in nRF52 SoC
obj->adc_pin = saadcIn - 1;
nrf_saadc_channel_config_t channel_config =
NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(saadcIn); //Single ended, negative input to ADC shorted to GND.
ret_code = nrf_drv_saadc_channel_init(obj->adc_pin, &channel_config);
MBED_ASSERT(ret_code == NRF_SUCCESS);
}
uint16_t analogin_read_u16(analogin_t *obj)
{
int16_t adc_value;
ret_code_t ret_code;
ret_code = nrf_drv_saadc_sample_convert(obj->adc_pin, &adc_value);
MBED_ASSERT(ret_code == NRF_SUCCESS);
if (adc_value < 0)
{
// Even in the single ended mode measured value can be {-0}. Saturation for avoid casting to a big integer.
return 0;
}
else
{
return (uint16_t) adc_value;
}
}
float analogin_read(analogin_t *obj)
{
uint16_t value = analogin_read_u16(obj);
return (float)value * (1.0f / (float)ADC_RANGE);
}
#endif // DEVICE_ANALOGIN

View File

@ -1,27 +1,13 @@
;WITHOUT SOFTDEVICE:
;LR_IROM1 0x00000000 0x00040000 {
; ER_IROM1 0x00000000 0x00040000 {
; *.o (RESET, +First)
; *(InRoot$$Sections)
; .ANY (+RO)
; }
; RW_IRAM1 0x20000000 0x00004000 {
; .ANY (+RW +ZI)
; }
;}
;
;WITH SOFTDEVICE:
LR_IROM1 0x1C000 0x0064000 {
ER_IROM1 0x1C000 0x0064000 {
LR_IROM1 0x21000 0x00DF000 {
ER_IROM1 0x21000 0x00DF000 {
*.o (RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
}
RW_IRAM0 0x20002EF8 UNINIT 0x000000D8 { ;no init section
RW_IRAM0 0x20002EF8 UNINIT 0x000000F4 { ;no init section
*(noinit)
}
RW_IRAM1 0x20002FD0 0x0000D030 {
RW_IRAM1 0x20002FEC 0x0003D014 {
.ANY (+RW +ZI)
}
}

View File

@ -94,6 +94,13 @@ __Vectors DCD __initial_sp ; Top of Stack
DCD RTC2_IRQHandler_v
DCD I2S_IRQHandler_v
DCD FPU_IRQHandler_v
DCD USBD_IRQHandler_v
DCD UARTE1_IRQHandler_v
DCD QSPI_IRQHandler_v
DCD CRYPTOCELL_IRQHandler_v
DCD SPIM3_IRQHandler_v
DCD 0 ; Reserved
DCD PWM3_IRQHandler_v
__Vectors_End
@ -202,6 +209,16 @@ Default_Handler PROC
EXPORT RTC2_IRQHandler_v [WEAK]
EXPORT I2S_IRQHandler_v [WEAK]
EXPORT FPU_IRQHandler_v [WEAK]
EXPORT USBD_IRQHandler_v [WEAK]
EXPORT UARTE1_IRQHandler_v [WEAK]
EXPORT QSPI_IRQHandler_v [WEAK]
EXPORT CRYPTOCELL_IRQHandler_v [WEAK]
EXPORT SPIM3_IRQHandler_v [WEAK]
EXPORT PWM3_IRQHandler_v [WEAK]
POWER_CLOCK_IRQHandler
RADIO_IRQHandler
UARTE0_UART0_IRQHandler_v
@ -239,6 +256,13 @@ SPIM2_SPIS2_SPI2_IRQHandler_v
RTC2_IRQHandler_v
I2S_IRQHandler_v
FPU_IRQHandler_v
USBD_IRQHandler_v
UARTE1_IRQHandler_v
QSPI_IRQHandler_v
CRYPTOCELL_IRQHandler_v
SPIM3_IRQHandler_v
PWM3_IRQHandler_v
B .
ENDP
ALIGN

View File

@ -106,6 +106,13 @@ __Vectors:
.long RTC2_IRQHandler_v
.long I2S_IRQHandler_v
.long FPU_IRQHandler_v
.long USBD_IRQHandler_v
.long UARTE1_IRQHandler_v
.long QSPI_IRQHandler_v
.long CRYPTOCELL_IRQHandler_v
.long SPIM3_IRQHandler_v
.long 0 /*Reserved */
.long PWM3_IRQHandler_v
.size __Vectors, . - __Vectors
@ -266,5 +273,11 @@ Default_Handler:
IRQ RTC2_IRQHandler_v
IRQ I2S_IRQHandler_v
IRQ FPU_IRQHandler_v
IRQ USBD_IRQHandler_v
IRQ UARTE1_IRQHandler_v
IRQ QSPI_IRQHandler_v
IRQ CRYPTOCELL_IRQHandler_v
IRQ SPIM3_IRQHandler_v
IRQ PWM3_IRQHandler_v
.end

View File

@ -32,7 +32,7 @@
#ifndef MBED_CMSIS_NVIC_H
#define MBED_CMSIS_NVIC_H
#define NVIC_NUM_VECTORS (16 + 38) // CORE + MCU Peripherals
#define NVIC_NUM_VECTORS (16 + 46) // CORE + MCU Peripherals
#define NVIC_USER_IRQ_OFFSET 16
#include "nrf.h"

View File

@ -2312,7 +2312,7 @@
// <e> TWI_ENABLED - nrf_drv_twi - TWI/TWIM peripheral driver
//==========================================================
#ifndef TWI_ENABLED
#define TWI_ENABLED 1
#define TWI_ENABLED 0
#endif
#if TWI_ENABLED
// <o> TWI_DEFAULT_CONFIG_FREQUENCY - Frequency
@ -2456,7 +2456,7 @@
// <1=> Enabled
#ifndef UART_DEFAULT_CONFIG_HWFC
#define UART_DEFAULT_CONFIG_HWFC 0
#define UART_DEFAULT_CONFIG_HWFC 1
#endif
// <o> UART_DEFAULT_CONFIG_PARITY - Parity
@ -2488,7 +2488,7 @@
// <268435456=> 57600 baud
#ifndef UART_DEFAULT_CONFIG_BAUDRATE
#define UART_DEFAULT_CONFIG_BAUDRATE 30801920
#define UART_DEFAULT_CONFIG_BAUDRATE 2576384
#endif
// <o> UART_DEFAULT_CONFIG_IRQ_PRIORITY - Interrupt priority

View File

@ -26,6 +26,9 @@
#define ADC_12BIT_RANGE 0xFFF
#define ADC_RANGE ADC_12BIT_RANGE
__STATIC_INLINE nrf_saadc_input_t nrf_drv_saadc_gpio_to_ain(uint32_t pin);
static void analog_in_event_handler(nrf_drv_saadc_evt_t const *p_event)// type of nrf_drv_saadc_event_handler_t
{
(void) p_event;
@ -88,4 +91,33 @@ float analogin_read(analogin_t *obj)
return (float)value * (1.0f / (float)ADC_RANGE);
}
/**
* @brief Function for converting a GPIO pin number to an analog input pin number used in the channel
* configuration.
*
* @param[in] pin GPIO pin.
*
* @return Value representing an analog input pin. The function returns @ref NRF_SAADC_INPUT_DISABLED
* if the specified pin is not an analog input.
*/
__STATIC_INLINE nrf_saadc_input_t nrf_drv_saadc_gpio_to_ain(uint32_t pin)
{
// AIN0 - AIN3
if (pin >= 2 && pin <= 5)
{
//0 means "not connected", hence this "+ 1"
return (nrf_saadc_input_t)(pin - 2 + 1);
}
// AIN4 - AIN7
else if (pin >= 28 && pin <= 31)
{
return (nrf_saadc_input_t)(pin - 24 + 1);
}
else
{
return NRF_SAADC_INPUT_DISABLED;
}
}
#endif // DEVICE_ANALOGIN

View File

@ -19,8 +19,9 @@
#include "pinmap.h"
#include "nrf_drv_gpiote.h"
#if defined(TARGET_MCU_NRF51822)
#define GPIO_PIN_COUNT 48
#elif defined(TARGET_MCU_NRF51822)
#define GPIO_PIN_COUNT 31
#else
#define GPIO_PIN_COUNT 32
@ -36,7 +37,13 @@ typedef struct {
bool irq_rise : 1;
} gpio_cfg_t;
uint32_t m_gpio_initialized;
#if GPIO_PIN_COUNT > 32
typedef uint32_t gpio_mask_t;
#else
typedef uint32_t gpio_mask_t;
#endif
gpio_mask_t m_gpio_initialized;
gpio_cfg_t m_gpio_cfg[GPIO_PIN_COUNT];
@ -46,7 +53,7 @@ gpio_cfg_t m_gpio_cfg[GPIO_PIN_COUNT];
static gpio_irq_handler m_irq_handler;
static uint32_t m_channel_ids[GPIO_PIN_COUNT] = {0};
uint32_t m_gpio_irq_enabled;
gpio_mask_t m_gpio_irq_enabled;
static void gpiote_irq_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
@ -54,7 +61,7 @@ static void gpiote_irq_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t a
nrf_gpio_pin_sense_t sense = nrf_gpio_pin_sense_get(pin);
gpio_irq_event event = (sense == NRF_GPIO_PIN_SENSE_LOW) ? IRQ_RISE : IRQ_FALL;
if (m_gpio_irq_enabled & (1UL << pin)) {
if (m_gpio_irq_enabled & ((gpio_mask_t)1 << pin)) {
if (((event == IRQ_RISE) && m_gpio_cfg[pin].irq_rise)
|| ((event == IRQ_FALL) && m_gpio_cfg[pin].irq_fall)) {
m_irq_handler(m_channel_ids[pin], event);
@ -84,7 +91,7 @@ int gpio_read(gpio_t *obj)
{
MBED_ASSERT(obj->pin != (PinName)NC);
if (m_gpio_cfg[obj->pin].direction == PIN_OUTPUT) {
return ((NRF_GPIO->OUTSET & (1UL << obj->pin)) ? 1 : 0);
return (nrf_gpio_pin_out_read(obj->pin) ? 1 : 0);
} else {
return nrf_gpio_pin_read(obj->pin);
}
@ -92,7 +99,7 @@ int gpio_read(gpio_t *obj)
static void gpiote_pin_uninit(uint8_t pin)
{
if (m_gpio_initialized & (1UL << pin)) {
if (m_gpio_initialized & ((gpio_mask_t)1 << pin)) {
if ((m_gpio_cfg[pin].direction == PIN_OUTPUT) && (!m_gpio_cfg[pin].used_as_irq)) {
nrf_drv_gpiote_out_uninit(pin);
}
@ -116,7 +123,7 @@ static void gpio_apply_config(uint8_t pin)
if (m_gpio_cfg[pin].used_as_irq) {
cfg.pull = NRF_GPIO_PIN_PULLUP;
nrf_drv_gpiote_in_init(pin, &cfg, gpiote_irq_handler);
if ((m_gpio_irq_enabled & (1 << pin))
if ((m_gpio_irq_enabled & ((gpio_mask_t)1 << pin))
&& (m_gpio_cfg[pin].irq_rise || m_gpio_cfg[pin].irq_fall))
{
nrf_drv_gpiote_in_event_enable(pin, true);
@ -142,10 +149,10 @@ static void gpio_apply_config(uint8_t pin)
nrf_drv_gpiote_out_config_t cfg = GPIOTE_CONFIG_OUT_SIMPLE(m_gpio_cfg[pin].init_high);
nrf_drv_gpiote_out_init(pin, &cfg);
}
m_gpio_initialized |= (1UL << pin);
m_gpio_initialized |= ((gpio_mask_t)1 << pin);
}
else {
m_gpio_initialized &= ~(1UL << pin);
m_gpio_initialized &= ~((gpio_mask_t)1 << pin);
}
}
@ -211,7 +218,7 @@ void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable)
{
gpio_cfg_t* cfg = &m_gpio_cfg[obj->ch];
bool irq_enabled_before =
(m_gpio_irq_enabled & (1 << obj->ch)) &&
(m_gpio_irq_enabled & ((gpio_mask_t)1 << obj->ch)) &&
(cfg->irq_rise || cfg->irq_fall);
if (event == IRQ_RISE) {
@ -235,7 +242,7 @@ void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable)
void gpio_irq_enable(gpio_irq_t *obj)
{
m_gpio_irq_enabled |= (1 << obj->ch);
m_gpio_irq_enabled |= ((gpio_mask_t)1 << obj->ch);
if (m_gpio_cfg[obj->ch].irq_rise || m_gpio_cfg[obj->ch].irq_fall) {
nrf_drv_gpiote_in_event_enable(obj->ch, true);
}
@ -244,6 +251,6 @@ void gpio_irq_enable(gpio_irq_t *obj)
void gpio_irq_disable(gpio_irq_t *obj)
{
m_gpio_irq_enabled &= ~(1 << obj->ch);
m_gpio_irq_enabled &= ~((gpio_mask_t)1 << obj->ch);
nrf_drv_gpiote_in_event_disable(obj->ch);
}

View File

@ -8,7 +8,7 @@
* 1. Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic Semiconductor ASA
* 2. Redistributions in// binary form, except as embedded into a Nordic Semiconductor ASA
* integrated circuit in a product or a software update for such product, 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.
@ -57,9 +57,6 @@ struct spi_s {
};
struct port_s {
__IO uint32_t *reg_cnf;
__IO uint32_t *reg_out;
__I uint32_t *reg_in;
PortName port;
uint32_t mask;
};

View File

@ -29,7 +29,9 @@ void pin_mode(PinName pin, PinMode mode)
MBED_ASSERT(pin != (PinName)NC);
uint32_t pin_number = (uint32_t)pin;
NRF_GPIO_Type * reg = nrf_gpio_pin_port_decode(&pin_number);
NRF_GPIO->PIN_CNF[pin_number] &= ~GPIO_PIN_CNF_PULL_Msk;
NRF_GPIO->PIN_CNF[pin_number] |= (mode << GPIO_PIN_CNF_PULL_Pos);
reg->PIN_CNF[pin_number] &= ~GPIO_PIN_CNF_PULL_Msk;
reg->PIN_CNF[pin_number] |= (mode << GPIO_PIN_CNF_PULL_Pos);
}

View File

@ -40,10 +40,12 @@
#include "pinmap.h"
#include "gpio_api.h"
static NRF_GPIO_Type * const m_ports[] = GPIO_REG_LIST;
PinName port_pin(PortName port, int pin_n)
{
(void) port;
return (PinName)(pin_n);
return NRF_GPIO_PIN_MAP(port, pin_n);
}
void port_init(port_t *obj, PortName port, int mask, PinDirection dir)
@ -51,10 +53,6 @@ void port_init(port_t *obj, PortName port, int mask, PinDirection dir)
obj->port = port;
obj->mask = mask;
obj->reg_out = &NRF_GPIO->OUT;
obj->reg_in = &NRF_GPIO->IN;
obj->reg_cnf = NRF_GPIO->PIN_CNF;
port_dir(obj, dir);
}
@ -72,11 +70,14 @@ void port_mode(port_t *obj, PinMode mode)
void port_dir(port_t *obj, PinDirection dir)
{
int i;
volatile uint32_t *reg_cnf = (volatile uint32_t*) m_ports[obj->port]->PIN_CNF;
switch (dir) {
case PIN_INPUT:
for (i = 0; i<31; i++) {
if (obj->mask & (1 << i)) {
obj->reg_cnf[i] = (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos)
reg_cnf[i] = (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos)
| (GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos)
| (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos)
| (GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos);
@ -86,7 +87,7 @@ void port_dir(port_t *obj, PinDirection dir)
case PIN_OUTPUT:
for (i = 0; i<31; i++) {
if (obj->mask & (1 << i)) {
obj->reg_cnf[i] = (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos)
reg_cnf[i] = (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos)
| (GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos)
| (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos)
| (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos)
@ -99,10 +100,11 @@ void port_dir(port_t *obj, PinDirection dir)
void port_write(port_t *obj, int value)
{
*obj->reg_out = value;
m_ports[obj->port]->OUTSET = value & obj->mask;
m_ports[obj->port]->OUTCLR = (~value) & obj->mask;
}
int port_read(port_t *obj)
{
return (*obj->reg_in);
return ((m_ports[obj->port]->IN) & obj->mask);
}