Skip to content

Commit

Permalink
Add support for Sensor Watch Pro (#412)
Browse files Browse the repository at this point in the history
* Sensor Watch Pro board definition

* Disable hot-plugging on SWCLK

* Add rainbow test

* Move interrupt mapping to board config

* New color definition for Pro boards in makefile
  • Loading branch information
joeycastillo authored Jul 6, 2024
1 parent 89a2af9 commit d98d14d
Show file tree
Hide file tree
Showing 15 changed files with 282 additions and 38 deletions.
64 changes: 64 additions & 0 deletions apps/pro-rainbow-test/app.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#include <stdio.h>
#include <string.h>
#include "watch.h"

void app_init(void) {
}

void app_wake_from_backup(void) {
}

void app_setup(void) {
watch_enable_leds();
}

void app_prepare_for_standby(void) {
}

void app_wake_from_standby(void) {
}

bool app_loop(void) {
static uint8_t red = 0;
static uint8_t green = 0;
static uint8_t blue = 255;
static uint8_t phase = 0;

switch (phase) {
case 0:
red++;
if (red == 255) phase = 1;
break;
case 1:
green++;
if (green == 255) phase = 2;
break;
case 2:
red--;
if (red == 0) phase = 3;
break;
case 3:
blue++;
if (blue == 255) phase = 4;
break;
case 4:
green--;
if (green == 0) phase = 5;
break;
case 5:
red++;
if (red == 255) phase = 6;
break;
case 6:
blue--;
if (blue == 0) {
phase = 1;
}
break;
}

watch_set_led_color_rgb(red, green, blue);
delay_ms(2);

return false;
}
10 changes: 10 additions & 0 deletions apps/pro-rainbow-test/make/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
TOP = ../../..
include $(TOP)/make.mk

INCLUDES += \
-I../

SRCS += \
../app.c

include $(TOP)/rules.mk
4 changes: 4 additions & 0 deletions boards/OSO-FEAL-A1-00/pins.h
Original file line number Diff line number Diff line change
Expand Up @@ -120,4 +120,8 @@
#define D0 GPIO(GPIO_PORTB, 3)
#define D1 GPIO(GPIO_PORTB, 0)

// interrupt mapping
#define EXT_IRQ_AMOUNT 6
#define CONFIG_EIC_EXTINT_MAP {0, PIN_PB00}, {1, PIN_PB01}, {2, PIN_PA02}, {3, PIN_PB03}, {5, PIN_PB05}, {7, PIN_PA07},

#endif // PINS_H_INCLUDED
4 changes: 4 additions & 0 deletions boards/OSO-SWAT-A1-02/pins.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,4 +81,8 @@
#define D0 GPIO(GPIO_PORTB, 3)
#define D1 GPIO(GPIO_PORTB, 0)

// interrupt mapping
#define EXT_IRQ_AMOUNT 6
#define CONFIG_EIC_EXTINT_MAP {0, PIN_PB00}, {1, PIN_PB01}, {2, PIN_PA02}, {3, PIN_PB03}, {6, PIN_PA22}, {7, PIN_PA23},

#endif // PINS_H_INCLUDED
4 changes: 4 additions & 0 deletions boards/OSO-SWAT-A1-04/pins.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,4 +81,8 @@
#define D0 GPIO(GPIO_PORTB, 3)
#define D1 GPIO(GPIO_PORTB, 0)

// interrupt mapping
#define EXT_IRQ_AMOUNT 6
#define CONFIG_EIC_EXTINT_MAP {0, PIN_PB00}, {1, PIN_PB01}, {2, PIN_PA02}, {3, PIN_PB03}, {6, PIN_PA22}, {7, PIN_PA23},

#endif // PINS_H_INCLUDED
4 changes: 4 additions & 0 deletions boards/OSO-SWAT-A1-05/pins.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,4 +81,8 @@
#define D0 GPIO(GPIO_PORTB, 3)
#define D1 GPIO(GPIO_PORTB, 0)

// interrupt mapping
#define EXT_IRQ_AMOUNT 6
#define CONFIG_EIC_EXTINT_MAP {0, PIN_PB00}, {1, PIN_PB01}, {2, PIN_PA02}, {3, PIN_PB03}, {6, PIN_PA22}, {7, PIN_PA23},

#endif // PINS_H_INCLUDED
122 changes: 122 additions & 0 deletions boards/OSO-SWAT-C1-00/pins.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
#ifndef PINS_H_INCLUDED
#define PINS_H_INCLUDED

// Detects if we are on USB power.
#define VBUS_DET GPIO(GPIO_PORTB, 5)

// Buttons
#define BTN_ALARM GPIO(GPIO_PORTA, 2)
#define WATCH_BTN_ALARM_EIC_CHANNEL 2
#define BTN_LIGHT GPIO(GPIO_PORTA, 30)
#define WATCH_BTN_LIGHT_EIC_CHANNEL 10
#define BTN_MODE GPIO(GPIO_PORTA, 31)
#define WATCH_BTN_MODE_EIC_CHANNEL 11

// Buzzer
#define BUZZER GPIO(GPIO_PORTA, 27)
#define WATCH_BUZZER_TCC_PINMUX PINMUX_PA27F_TCC0_WO5
#define WATCH_BUZZER_TCC_CHANNEL 1

// LEDs
#define WATCH_INVERT_LED_POLARITY

#define RED GPIO(GPIO_PORTA, 12)
#define WATCH_RED_TCC_CHANNEL 2
#define WATCH_RED_TCC_PINMUX PINMUX_PA12F_TCC0_WO6

#define BLUE GPIO(GPIO_PORTA, 13)
#define WATCH_BLUE_TCC_CHANNEL 3
#define WATCH_BLUE_TCC_PINMUX PINMUX_PA13F_TCC0_WO7

#define GREEN GPIO(GPIO_PORTA, 22)
#define WATCH_GREEN_TCC_CHANNEL 0
#define WATCH_GREEN_TCC_PINMUX PINMUX_PA22F_TCC0_WO4

// Segment LCD
#define SLCD0 GPIO(GPIO_PORTB, 6)
#define SLCD1 GPIO(GPIO_PORTB, 7)
#define SLCD2 GPIO(GPIO_PORTB, 8)
#define SLCD3 GPIO(GPIO_PORTB, 9)
#define SLCD4 GPIO(GPIO_PORTA, 5)
#define SLCD5 GPIO(GPIO_PORTA, 6)
#define SLCD6 GPIO(GPIO_PORTA, 7)
#define SLCD7 GPIO(GPIO_PORTA, 8)
#define SLCD8 GPIO(GPIO_PORTA, 9)
#define SLCD9 GPIO(GPIO_PORTA, 10)
#define SLCD10 GPIO(GPIO_PORTA, 11)
#define SLCD11 GPIO(GPIO_PORTB, 11)
#define SLCD12 GPIO(GPIO_PORTB, 12)
#define SLCD13 GPIO(GPIO_PORTB, 13)
#define SLCD14 GPIO(GPIO_PORTB, 14)
#define SLCD15 GPIO(GPIO_PORTB, 15)
#define SLCD16 GPIO(GPIO_PORTA, 14)
#define SLCD17 GPIO(GPIO_PORTA, 15)
#define SLCD18 GPIO(GPIO_PORTA, 16)
#define SLCD19 GPIO(GPIO_PORTA, 17)
#define SLCD20 GPIO(GPIO_PORTA, 18)
#define SLCD21 GPIO(GPIO_PORTA, 19)
#define SLCD22 GPIO(GPIO_PORTB, 16)
#define SLCD23 GPIO(GPIO_PORTB, 17)
#define SLCD24 GPIO(GPIO_PORTA, 20)
#define SLCD25 GPIO(GPIO_PORTA, 21)
#define SLCD26 GPIO(GPIO_PORTA, 23)
// This board uses a slightly different pin mapping from the standard watch, and it's not enough to
// just declare the pins. We also have to set the LCD Pin Enable register with the SLCD pins we're
// using. These numbers are not port/pin numbers, but the "SLCD/LP[x]" numbers in the pinmux table.
// If not defined in pins.h, the LCD driver will fall back to the pin mapping in hpl_slcd_config.h.
// LPENL is for pins SLCD/LP[0..31].
#define CONF_SLCD_LPENL (\
(uint32_t)1 << 0 | \
(uint32_t)1 << 1 | \
(uint32_t)1 << 2 | \
(uint32_t)1 << 3 | \
(uint32_t)1 << 5 | \
(uint32_t)1 << 6 | \
(uint32_t)1 << 7 | \
(uint32_t)1 << 11 | \
(uint32_t)1 << 12 | \
(uint32_t)1 << 13 | \
(uint32_t)1 << 14 | \
(uint32_t)1 << 21 | \
(uint32_t)1 << 22 | \
(uint32_t)1 << 23 | \
(uint32_t)1 << 24 | \
(uint32_t)1 << 25 | \
(uint32_t)1 << 30 | \
(uint32_t)1 << 31 | 0)
// LPENH is for pins SLCD/LP[32..51], where bit 0 represents pin 32.
#define CONF_SLCD_LPENH (\
(uint32_t)1 << (32 - 32) | \
(uint32_t)1 << (33 - 32) | \
(uint32_t)1 << (34 - 32) | \
(uint32_t)1 << (35 - 32) | \
(uint32_t)1 << (42 - 32) | \
(uint32_t)1 << (43 - 32) | \
(uint32_t)1 << (48 - 32) | \
(uint32_t)1 << (49 - 32) | \
(uint32_t)1 << (51 - 32) | 0)


// 9-pin connector
#define A0 GPIO(GPIO_PORTB, 4)
#define WATCH_A0_EIC_CHANNEL 4
#define A1 GPIO(GPIO_PORTB, 1)
#define WATCH_A1_EIC_CHANNEL 1
#define A2 GPIO(GPIO_PORTB, 2)
#define WATCH_A2_EIC_CHANNEL 2
#define A3 GPIO(GPIO_PORTB, 3)
#define WATCH_A3_EIC_CHANNEL 3
#define A4 GPIO(GPIO_PORTB, 0)
#define WATCH_A4_EIC_CHANNEL 0
#define SDA GPIO(GPIO_PORTB, 30)
#define SCL GPIO(GPIO_PORTB, 31)

// aliases for as A3/A4; these were mentioned as D0/D1 in early documentation.
#define D0 GPIO(GPIO_PORTB, 3)
#define D1 GPIO(GPIO_PORTB, 0)

// interrupt mapping
#define EXT_IRQ_AMOUNT 6
#define CONFIG_EIC_EXTINT_MAP {0, PIN_PB00}, {1, PIN_PB01}, {2, PIN_PA02}, {3, PIN_PB03}, {10, PIN_PA30}, {11, PIN_PA31},

#endif // PINS_H_INCLUDED
28 changes: 13 additions & 15 deletions make.mk
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,19 @@ BUILD = ./build-sim
endif
BIN = watch

ifndef BOARD
ifndef COLOR
$(error Set the COLOR variable to RED, BLUE, GREEN or PRO depending on what board you have.)
endif

COLOR_VALID := $(filter $(COLOR),RED BLUE GREEN PRO)

ifeq ($(COLOR_VALID),)
$(error COLOR must be RED, BLUE, GREEN or PRO)
endif

ifeq ($(COLOR), PRO)
override BOARD = OSO-SWAT-C1-00
else
override BOARD = OSO-SWAT-A1-05
endif

Expand Down Expand Up @@ -205,20 +217,6 @@ SRCS += \

endif

ifeq ($(LED), BLUE)
CFLAGS += -DWATCH_IS_BLUE_BOARD
endif

ifndef COLOR
$(error Set the COLOR variable to RED, BLUE, or GREEN depending on what board you have.)
endif

COLOR_VALID := $(filter $(COLOR),RED BLUE GREEN)

ifeq ($(COLOR_VALID),)
$(error COLOR must be RED, BLUE, or GREEN)
endif

ifeq ($(COLOR), BLUE)
CFLAGS += -DWATCH_IS_BLUE_BOARD
endif
Expand Down
11 changes: 1 addition & 10 deletions watch-library/hardware/hpl/eic/hpl_eic.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
#include <string.h>
#include <utils.h>
#include <utils_assert.h>
#include "pins.h"

#ifdef __MINGW32__
#define ffs __builtin_ffs
Expand All @@ -62,16 +63,6 @@ static int ffs(int v)
#define INVALID_EXTINT_NUMBER 0xFF
#define INVALID_PIN_NUMBER 0xFFFFFFFF

#ifndef CONFIG_EIC_EXTINT_MAP
/** Dummy mapping to pass compiling. */
#define CONFIG_EIC_EXTINT_MAP \
{ \
INVALID_EXTINT_NUMBER, INVALID_PIN_NUMBER \
}
#endif

#define EXT_IRQ_AMOUNT 6

/**
* \brief EXTINTx and pin number map
*/
Expand Down
14 changes: 14 additions & 0 deletions watch-library/hardware/watch/watch_led.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,24 @@ void watch_disable_leds(void) {
}

void watch_set_led_color(uint8_t red, uint8_t green) {
#ifdef WATCH_BLUE_TCC_CHANNEL
watch_set_led_color_rgb(red, green, 0);
#else
watch_set_led_color_rgb(red, green, green);
#endif
}

void watch_set_led_color_rgb(uint8_t red, uint8_t green, uint8_t blue) {
#ifndef WATCH_BLUE_TCC_CHANNEL
(void) blue; // silence warning
#endif
if (hri_tcc_get_CTRLA_reg(TCC0, TCC_CTRLA_ENABLE)) {
uint32_t period = hri_tcc_get_PER_reg(TCC0, TCC_PER_MASK);
hri_tcc_write_CCBUF_reg(TCC0, WATCH_RED_TCC_CHANNEL, ((period * red * 1000ull) / 255000ull));
hri_tcc_write_CCBUF_reg(TCC0, WATCH_GREEN_TCC_CHANNEL, ((period * green * 1000ull) / 255000ull));
#ifdef WATCH_BLUE_TCC_CHANNEL
hri_tcc_write_CCBUF_reg(TCC0, WATCH_BLUE_TCC_CHANNEL, ((period * blue * 1000ull) / 255000ull));
#endif
}
}

Expand Down
25 changes: 22 additions & 3 deletions watch-library/hardware/watch/watch_private.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ void _watch_init(void) {
// disable the LED pin (it may have been enabled by the bootloader)
watch_disable_digital_output(GPIO(GPIO_PORTA, 20));

// disable debugger hot-plugging
gpio_set_pin_function(SWCLK, GPIO_PIN_FUNCTION_OFF);
gpio_set_pin_direction(SWCLK, GPIO_DIRECTION_OFF);
gpio_set_pin_pull_mode(SWCLK, GPIO_PULL_OFF);

// RAM should be back-biased in STANDBY
PM->STDBYCFG.bit.BBIASHS = 1;

Expand Down Expand Up @@ -152,18 +157,24 @@ void _watch_enable_tcc(void) {
// period (i.e. a square wave with a 50% duty cycle).
// * LEDs on CC[2] and CC[3] can be set to any value from 0 (off) to PER (fully on).
hri_tcc_write_WAVE_reg(TCC0, TCC_WAVE_WAVEGEN_NPWM);
#ifdef WATCH_INVERT_LED_POLARITY
// This is here for the dev board, which uses a common anode LED (instead of common cathode like the actual watch).
#ifdef WATCH_INVERT_LED_POLARITY
// This is here for the dev board and Pro, which use a common anode LED (instead of common cathode like the actual watch).
hri_tcc_set_WAVE_reg(TCC0, (1 << (TCC_WAVE_POL0_Pos + WATCH_RED_TCC_CHANNEL)) |
#ifdef WATCH_BLUE_TCC_CHANNEL
(1 << (TCC_WAVE_POL0_Pos + WATCH_BLUE_TCC_CHANNEL)) |
#endif // WATCH_BLUE_TCC_CHANNEL
(1 << (TCC_WAVE_POL0_Pos + WATCH_GREEN_TCC_CHANNEL)));
#endif
#endif // WATCH_INVERT_LED_POLARITY
// The buzzer will set the period depending on the tone it wants to play, but we have to set some period here to
// get the LED working. Almost any period will do, tho it should be below 20000 (i.e. 50 Hz) to avoid flickering.
hri_tcc_write_PER_reg(TCC0, 1024);
// Set the duty cycle of all pins to 0: LED's off, buzzer not buzzing.
hri_tcc_write_CC_reg(TCC0, WATCH_BUZZER_TCC_CHANNEL, 0);
hri_tcc_write_CC_reg(TCC0, WATCH_RED_TCC_CHANNEL, 0);
hri_tcc_write_CC_reg(TCC0, WATCH_GREEN_TCC_CHANNEL, 0);
#ifdef WATCH_BLUE_TCC_CHANNEL
hri_tcc_write_CC_reg(TCC0, WATCH_BLUE_TCC_CHANNEL, 0);
#endif
// Enable the TCC
hri_tcc_set_CTRLA_ENABLE_bit(TCC0);
hri_tcc_wait_for_sync(TCC0, TCC_SYNCBUSY_ENABLE);
Expand All @@ -173,6 +184,10 @@ void _watch_enable_tcc(void) {
gpio_set_pin_function(RED, WATCH_RED_TCC_PINMUX);
gpio_set_pin_direction(GREEN, GPIO_DIRECTION_OUT);
gpio_set_pin_function(GREEN, WATCH_GREEN_TCC_PINMUX);
#ifdef WATCH_BLUE_TCC_CHANNEL
gpio_set_pin_direction(BLUE, GPIO_DIRECTION_OUT);
gpio_set_pin_function(BLUE, WATCH_BLUE_TCC_PINMUX);
#endif
}

void _watch_disable_tcc(void) {
Expand All @@ -183,6 +198,10 @@ void _watch_disable_tcc(void) {
gpio_set_pin_function(RED, GPIO_PIN_FUNCTION_OFF);
gpio_set_pin_direction(GREEN, GPIO_DIRECTION_OFF);
gpio_set_pin_function(GREEN, GPIO_PIN_FUNCTION_OFF);
#ifdef WATCH_BLUE_TCC_CHANNEL
gpio_set_pin_direction(BLUE, GPIO_DIRECTION_OFF);
gpio_set_pin_function(BLUE, GPIO_PIN_FUNCTION_OFF);
#endif

// disable the TCC
hri_tcc_clear_CTRLA_ENABLE_bit(TCC0);
Expand Down
Loading

0 comments on commit d98d14d

Please sign in to comment.