Skip to content

Commit

Permalink
microbitv2: Refactory board id and Kl27 timer code into their own files.
Browse files Browse the repository at this point in the history
This should result in no change in behaviour.
  • Loading branch information
microbit-carlos committed Jan 21, 2022
1 parent ebfa1cb commit a2e6e46
Show file tree
Hide file tree
Showing 12 changed files with 314 additions and 156 deletions.
2 changes: 2 additions & 0 deletions records/board/kl27z_microbit_bl.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
common:
macros:
- MICROBIT_LOCK_BOOTLOADER
includes:
- source/board/microbitv2/board_id.h
sources:
board:
- source/board/kl27z_microbit_bl.c
2 changes: 2 additions & 0 deletions records/board/nrf52820_microbit_bl.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
common:
includes:
- source/board/microbitv2/board_id.h
sources:
board:
- source/board/nrf52820_microbit_bl.c
3 changes: 2 additions & 1 deletion source/board/kl27z_microbit_bl.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "target_family.h"
#include "fsl_device_registers.h"
#include "gpio.h"
#include "board_id.h"

// Warning - changing the interface start will break backwards compatibility
COMPILER_ASSERT(DAPLINK_ROM_IF_START == KB(32));
Expand Down Expand Up @@ -59,7 +60,7 @@ const target_family_descriptor_t *g_target_family = NULL;

const board_info_t g_board_info = {
.info_version = kBoardInfoVersion,
.board_id = "9903",
.board_id = BOARD_ID_MB_2_DEFAULT,
.daplink_url_name = "HELP_FAQHTM",
.daplink_drive_name = "MAINTENANCE",
.daplink_target_url = "https://microbit.org/device/?id=@B&v=@V&bl=1",
Expand Down
53 changes: 53 additions & 0 deletions source/board/microbitv2/board_id.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/**
* @file board_id.h
* @brief
*
* DAPLink Interface Firmware
* Copyright 2021 Micro:bit Educational Foundation
* SPDX-License-Identifier: Apache-2.0
*
* 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 BOARD_ID_H_
#define BOARD_ID_H_

#ifdef __cplusplus
extern "C" {
#endif

#define BOARD_ID_MB_2_DEFAULT "9903"
#define BOARD_ID_MB_2_0 "9904"
#define BOARD_ID_MB_2_2_833 "9905"
#define BOARD_ID_MB_2_2_820 "9906"

typedef enum {
BOARD_VERSION_2_DEF = 0x9903,
BOARD_VERSION_2_0 = 0x9904,
BOARD_VERSION_2_2_833 = 0x9905,
BOARD_VERSION_2_2_820 = 0x9906,
} mb_version_t;


/**
* Determines the micro:bit board ID based on on-board components configured
* differently between versions.
*/
mb_version_t board_id_detect(void);


#ifdef __cplusplus
}
#endif

#endif /* BOARD_ID_H_ */
95 changes: 95 additions & 0 deletions source/board/microbitv2/kl27z/board_id.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/**
* @file board_id.c
* @brief
*
* DAPLink Interface Firmware
* Copyright 2020 NXP
* Copyright 2021 Micro:bit Educational Foundation
* SPDX-License-Identifier: Apache-2.0
*
* 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 "IO_Config.h"

#include "board_id.h"
#include "timer_wait.h"

#include "adc.h"
#include "fsl_port.h"
#include "fsl_gpio.h"

#define BRD_ID_1_UPPER_THR_V 935 // Upper threshold in mV for 100nF and 4700R
#define BRD_ID_1_LOWER_THR_V 268 // Lower threshold in mV for 100nF and 4700R

// Board Rev ID detection. Reads BRD_REV_ID voltage
// Depends on gpio_init() to have been executed already
mb_version_t board_id_detect()
{
gpio_pin_config_t pin_config = {
.pinDirection = kGPIO_DigitalOutput,
.outputLogic = 0U
};
uint32_t board_rev_id_adc = 0;
uint32_t board_rev_id_mv = 0;

// Set Board Rev ID pin as output but pin disabled
PORT_SetPinMux(PIN_BOARD_REV_ID_PORT , PIN_BOARD_REV_ID_BIT, kPORT_PinDisabledOrAnalog);
PORT_SetPinDriveStrength(PIN_BOARD_REV_ID_PORT, PIN_BOARD_REV_ID_BIT, kPORT_HighDriveStrength);
GPIO_PinInit(PIN_BOARD_REV_ID_GPIO, PIN_BOARD_REV_ID_BIT, &pin_config);

adc_init();
timer_wait_init();

// 1. Discharge capacitor
/* Set timer period 3ms*/
timer_wait_set_period(3000);
/* Drive BRD_REV_ID pin to low */
GPIO_PortClear(PIN_BOARD_REV_ID_GPIO, PIN_BOARD_REV_ID);
PORT_SetPinMux(PIN_BOARD_REV_ID_PORT , PIN_BOARD_REV_ID_BIT, kPORT_MuxAsGpio);
/* Wait 3ms to allow the 100nF Cap to discharge at least 5*RC with 4700R */
timer_wait();

// 2. Charge capacitor for 100us
/* Set timer period slightly below 100us to account for overheads */
timer_wait_set_period(98);
/* Drive BRD_REV_ID pin to high */
GPIO_PortSet(PIN_BOARD_REV_ID_GPIO, PIN_BOARD_REV_ID);
/* Wait for ~100us */
timer_wait();
/* Change pin to ADC (High-Z). Capacitor will stop charging */
PORT_SetPinMux(PIN_BOARD_REV_ID_PORT , PIN_BOARD_REV_ID_BIT, kPORT_PinDisabledOrAnalog);

// 3. Take ADC measurement
board_rev_id_adc = adc_read_channel(0, PIN_BOARD_REV_ID_ADC_CH, PIN_BOARD_REV_ID_ADC_MUX);
board_rev_id_mv = board_rev_id_adc * 3300 / 0xFFF; // Convert ADC 12-bit value to mV with 3.3V reference

// 4. Discharge capacitor
/* Set timer period 3ms */
timer_wait_set_period(3000);
/* Drive BRD_REV_ID pin to low */
GPIO_PortClear(PIN_BOARD_REV_ID_GPIO, PIN_BOARD_REV_ID);
PORT_SetPinMux(PIN_BOARD_REV_ID_PORT , PIN_BOARD_REV_ID_BIT, kPORT_MuxAsGpio);
/* Wait 3ms to allow the 100nF Cap to discharge at least 5*RC with 4700R */
timer_wait();

// 5. Identify board ID depending on voltage
mb_version_t board_version;
if (board_rev_id_mv > BRD_ID_1_LOWER_THR_V && board_rev_id_mv < BRD_ID_1_UPPER_THR_V) {
board_version = BOARD_VERSION_2_0;
} else {
board_version = BOARD_VERSION_2_DEF;
}

return board_version;
}
24 changes: 11 additions & 13 deletions source/board/microbitv2/kl27z/pwr_mon.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
*/

#include "pwr_mon.h"
#include "timer_wait.h"

#include "adc.h"
#include "fsl_adc16.h"
#include "fsl_pmc.h"
Expand All @@ -39,20 +41,17 @@ static void pwr_mon_bandgap_init(void);
static uint32_t pwr_mon_read_vbg(uint32_t channelGroup);
static uint32_t pwr_mon_adc_to_mv(uint32_t raw_adc);

void TPM0_IRQHandler(void);

extern volatile bool tpmIsrFlag;
extern uint32_t tpm_source_clock;

void pwr_mon_init(void)
{
gpio_pin_config_t pin_config = {
.pinDirection = kGPIO_DigitalOutput,
.outputLogic = 0U
};

adc_init();

timer_wait_init();

// Configure VMON_BAT and RUN_VBAT_SENSE
GPIO_PinInit(PIN_RUN_VBAT_SENSE_GPIO, PIN_RUN_VBAT_SENSE_BIT, &pin_config);
PORT_SetPinMux(PIN_RUN_VBAT_SENSE_PORT, PIN_RUN_VBAT_SENSE_BIT, kPORT_MuxAsGpio);
Expand Down Expand Up @@ -90,23 +89,22 @@ power_source_t pwr_mon_get_power_source(void) {
return power_source;
}

uint32_t pwr_mon_get_vbat_mv(void) {
uint32_t pwr_mon_get_vbat_mv(void)
{
/* Set timer period 3ms*/
TPM_SetTimerPeriod(TPM0, USEC_TO_COUNT(3000U, tpm_source_clock));
timer_wait_set_period(3000);
// Enable voltage divider to take measurement
GPIO_PinWrite(PIN_RUN_VBAT_SENSE_GPIO, PIN_RUN_VBAT_SENSE_BIT, 1);
// Add a ~3ms delay to allow the 100nF capacitors to charge to about 3*RC.
TPM_StartTimer(TPM0, kTPM_SystemClock);
while (false == tpmIsrFlag);
tpmIsrFlag = false;
timer_wait();

uint32_t bat_adc = adc_read_channel(0, PIN_VMON_BAT_ADC_CH, PIN_VMON_BAT_ADC_MUX);
// Disable voltage divider
GPIO_PinWrite(PIN_RUN_VBAT_SENSE_GPIO, PIN_RUN_VBAT_SENSE_BIT, 0);

// Compensate for voltage divider with ratio of 11
bat_adc = bat_adc * 11;

return pwr_mon_adc_to_mv(bat_adc);
}

Expand Down
70 changes: 70 additions & 0 deletions source/board/microbitv2/kl27z/timer_wait.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/**
* @file timer_wait.c
* @brief
*
* DAPLink Interface Firmware
* Copyright 2021 Micro:bit Educational Foundation
* SPDX-License-Identifier: Apache-2.0
*
* 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 "timer_wait.h"

#include "fsl_device_registers.h"
#include "fsl_tpm.h"


static volatile bool tpmIsrFlag = false;
static uint32_t tpm_source_clock;


void TPM0_IRQHandler(void)
{
/* Clear interrupt flag.*/
TPM_ClearStatusFlags(TPM0, kTPM_TimeOverflowFlag);
tpmIsrFlag = true;
TPM_StopTimer(TPM0);
__DSB();
}

void timer_wait_init(void)
{
/* Select the clock source for the TPM counter as kCLOCK_McgIrc48MClk */
CLOCK_SetTpmClock(1U);

tpm_config_t tpmInfo;
TPM_GetDefaultConfig(&tpmInfo);
/* TPM clock divide by TPM_PRESCALER */
tpmInfo.prescale = kTPM_Prescale_Divide_4;
/* Initialize TPM module */
TPM_Init(TPM0, &tpmInfo);

TPM_EnableInterrupts(TPM0, kTPM_TimeOverflowInterruptEnable);
EnableIRQ(TPM0_IRQn);

tpm_source_clock = (CLOCK_GetFreq(kCLOCK_McgIrc48MClk) / 4);
tpmIsrFlag = false;
}

void timer_wait_set_period(uint32_t microsec)
{
TPM_SetTimerPeriod(TPM0, USEC_TO_COUNT(microsec, tpm_source_clock));
}

void timer_wait(void)
{
TPM_StartTimer(TPM0, kTPM_SystemClock);
while (false == tpmIsrFlag);
tpmIsrFlag = false;
}
33 changes: 33 additions & 0 deletions source/board/microbitv2/kl27z/timer_wait.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/**
* @file timer_wait.h
* @brief
*
* DAPLink Interface Firmware
* Copyright 2021 Micro:bit Educational Foundation
* SPDX-License-Identifier: Apache-2.0
*
* 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 TIMER_WAIT_H_
#define TIMER_WAIT_H_

#include <stdint.h>


void timer_wait_init(void);
void timer_wait_set_period(uint32_t microsec);
void timer_wait(void);


#endif /* TIMER_WAIT_H_ */
Loading

0 comments on commit a2e6e46

Please sign in to comment.