mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
70113b5fd3
This initial I2C support allows to use the I2C bus in controller mode to interact with multiple peripherals in blocking mode. The CPU will perform a busy wait when transferring data over I2C.
164 lines
6.8 KiB
Plaintext
164 lines
6.8 KiB
Plaintext
/* NXP QN908x specific information for the `periph` drivers */
|
|
/**
|
|
|
|
@defgroup cpu_qn908x NXP QN908x
|
|
@ingroup cpu
|
|
@brief NXP QN908x BLE-enabled Cortex-M4F MCU specific implementation
|
|
|
|
The NXP QN908x family of chips such as the QN9080 feature a Cortex-M4F,
|
|
Bluetooth Low Energy, USB 2.0 and in some SKUs like the QN9080SIP NFC as well.
|
|
The CPU is designed to be ultra-low-power and high-performance, allowing
|
|
applications with small battery capacity. It includes an optional DC-DC and LDO,
|
|
low power sleep timers, I2C, SPI, ADC, SPIFI and several other peripherals.
|
|
|
|
|
|
@defgroup cpu_qn908x_cpuid NXP QN908x CPUID
|
|
@ingroup cpu_qn908x
|
|
@brief NXP QN908x CPUID driver
|
|
|
|
No configuration is necessary. The CPUID value is based on the factory assigned
|
|
default Bluetooth address in the read-only flash section which may not be the
|
|
Bluetooth address used by the Bluetooth module if a different one was programmed
|
|
there.
|
|
|
|
|
|
@defgroup cpu_qn908x_gpio NXP QN908x GPIO
|
|
@ingroup cpu_qn908x
|
|
@brief NXP QN908x GPIO driver
|
|
|
|
The GPIO driver uses the @ref GPIO_PIN(port, pin) macro to declare pins.
|
|
|
|
No configuration is necessary.
|
|
|
|
|
|
@defgroup cpu_qn908x_i2c NXP QN908x I2C
|
|
@ingroup cpu_qn908x
|
|
@brief NXP QN908x I2C driver
|
|
|
|
There are several FLEXCOMM interfaces in this chip, but only two of these
|
|
support I2C (FLEXCOMM1 and FLEXCOMM2) which are mapped as I2C0 and I2C1,
|
|
respectively. A single FLEXCOMM interface can only be used for one of the I2C,
|
|
UART or SPI interfaces, so for example USART1 and I2C0 can't be used at the
|
|
same time since they are both the same FLEXCOMM1 interface.
|
|
|
|
### I2C configuration example (for periph_conf.h) ###
|
|
|
|
static const i2c_conf_t i2c_config[] = {
|
|
{
|
|
.dev = I2C0,
|
|
.pin_scl = GPIO_PIN(PORT_A, 6), // or A8, A12, A20
|
|
.pin_sda = GPIO_PIN(PORT_A, 7), // or A9, A13, A21
|
|
.speed = I2C_SPEED_FAST,
|
|
},
|
|
{
|
|
.dev = I2C1,
|
|
.pin_scl = GPIO_PIN(PORT_A, 2), // or A5, A23, A27
|
|
.pin_sda = GPIO_PIN(PORT_A, 3), // or A4, A22, A26
|
|
.speed = I2C_SPEED_FAST,
|
|
},
|
|
};
|
|
#define I2C_NUMOF ARRAY_SIZE(i2c_config)
|
|
|
|
|
|
@defgroup cpu_qn908x_timer NXP QN908x Standard counter/timers (CTIMER)
|
|
@ingroup cpu_qn908x
|
|
@brief NXP QN908x timer driver
|
|
|
|
The QN908x have 4 standard counter/timers (CTIMER). These timers allow to count
|
|
clock cycles from the APB clock with a 32-bit prescaler, effectively dividing
|
|
the APB clock frequency by a configurable number up to 2^32, allowing a great
|
|
range of timer frequencies selected at runtime. Each timer has 4 independent
|
|
channels to match against which can generate an interrupt.
|
|
|
|
TODO: These CTIMERs and the SCT timers can both be used as PWM as well, with
|
|
different set of capabilities. Boards should be able to split these CTIMER and
|
|
SCT blocks between pwm and timer functions.
|
|
|
|
### Timer configuration example (for periph_conf.h) ###
|
|
|
|
#define TIMER_NUMOF 4
|
|
|
|
|
|
@defgroup cpu_qn908x_rtc NXP QN908x Real-Time-Clock (RTC)
|
|
@ingroup cpu_qn908x
|
|
@brief NXP QN908x RTC driver
|
|
|
|
The RTC block in the QN908x can be driven by the external 32.768 kHz crystal or
|
|
by the internal 32 kHz RCO oscillator clock, whichever is selected as the
|
|
`CLK_32K` clock source. The RTC has an internal "second counter" calibrated
|
|
depending on the frequency of the clock source selected at the time the RTC
|
|
clock is initialized by calling @ref rtc_init.
|
|
|
|
The RTC function in this cpu doesn't have a match against a target value to
|
|
generate an interrupt like the timer peripheral, instead, the alarm function in
|
|
the rtc.h interface is implemented by an interrupt generated every second which
|
|
checks the target value in software. Keep in mind that while the RTC can operate
|
|
while the cpu is the power-down 0 mode, using the alarm functionality during
|
|
that time means that the cpu will wake up every second for a brief moment,
|
|
potentially impacting the power consumption.
|
|
|
|
No RTC-specific configuration is necessary.
|
|
|
|
|
|
@defgroup cpu_qn908x_uart NXP QN908x UART
|
|
@ingroup cpu_qn908x
|
|
@brief NXP QN908x UART driver
|
|
|
|
There are several FLEXCOMM interfaces in this chip, but only two of these
|
|
support UART (FLEXCOMM0 and FLEXCOMM1). The default UART mode is 8n1 and can
|
|
be changed with the uart_mode() function. If only RX or only TX is desired, the
|
|
other pin can be set to GPIO_UNDEF.
|
|
|
|
### UART configuration example (for periph_conf.h) ###
|
|
|
|
static const uart_conf_t uart_config[] = {
|
|
{
|
|
.dev = USART0,
|
|
.rx_pin = GPIO_PIN(PORT_A, 17), // or A5
|
|
.tx_pin = GPIO_PIN(PORT_A, 16), // or A4
|
|
},
|
|
{
|
|
.dev = USART1,
|
|
.rx_pin = GPIO_PIN(PORT_A, 9), // or A13
|
|
.tx_pin = GPIO_PIN(PORT_A, 8), // or A12
|
|
},
|
|
};
|
|
#define UART_NUMOF ARRAY_SIZE(uart_config)
|
|
|
|
|
|
@defgroup cpu_qn908x_wdt NXP QN908x Watchdog timer (WDT)
|
|
@ingroup cpu_qn908x
|
|
@brief NXP QN908x Watchdog timer (WDT)
|
|
|
|
The Watchdog timer in the NXP QN908x starts disabled on reset: the clock bit
|
|
`CLK_WDT_EN` is enabled in the `CLK_EN` register on reset so the timer is
|
|
running but the interrupt and reset functions are disabled. However, after the
|
|
read-only bootloader ROM in the QN908x transfer the control flow to the user
|
|
application (the RIOT kernel) the Watchdog is enabled with a timeout of 10
|
|
seconds.
|
|
|
|
If your board does not include the `periph_wdt` module, the Watchdog will be
|
|
disabled at `cpu_init()` time and there's no configuration necessary. However,
|
|
if your board or application does include it, the Watchdog will be left
|
|
configured with the 10 second timeout set by the Bootloader and you need to
|
|
call `wdt_setup_reboot()` or `wdt_setup_reboot_with_callback()` within the first
|
|
10 seconds.
|
|
|
|
The WDT block supports different clock sources which would be configured by the
|
|
board since they depend on whether the optional crystals are populated in your
|
|
board. Nevertheless, the millisecond values passed to `wdt_setup_reboot*` are
|
|
internally converted to clock ticks using the clock configured at the time the
|
|
function was called. `wdt_setup_reboot*()` can be called multiple times to
|
|
change the WDT parameters or after changing the WDT clock source, but in any
|
|
case `wdt_start()` must be called after it to start the WDT operation.
|
|
|
|
Once the WDT triggers, it is not possible to avoid the device reboot and calling
|
|
wdt_kick() from the WDT callback (if any) or after the callback was called will
|
|
not have any effect. Note that, however, if the WDT callback returns before the
|
|
configured CONFIG_WDT_WARNING_PERIOD the CPU will continue executing the code
|
|
before the WDT interrupt occurred. If this is not desired, an infinite loop at
|
|
the end of the WDT callback, after the safety operations have been performed is
|
|
advisable.
|
|
|
|
*/
|