barebones 'hello world' project
This commit is contained in:
parent
7e330befff
commit
2d1e2e8c76
@ -7,129 +7,30 @@ void uart_putc(char c);
|
|||||||
void uart_puts(char *s);
|
void uart_puts(char *s);
|
||||||
|
|
||||||
typedef enum ApplicationMode {
|
typedef enum ApplicationMode {
|
||||||
MODE_TIME,
|
MODE_HELLO = 0,
|
||||||
MODE_SENSE,
|
MODE_THERE
|
||||||
MODE_SET_HOUR,
|
|
||||||
MODE_SET_MINUTE,
|
|
||||||
MODE_SET_SECOND
|
|
||||||
} ApplicationMode;
|
} ApplicationMode;
|
||||||
|
|
||||||
|
typedef enum LightColor {
|
||||||
|
COLOR_OFF = 0,
|
||||||
|
COLOR_RED = 1,
|
||||||
|
COLOR_GREEN = 2,
|
||||||
|
COLOR_YELLOW = 3
|
||||||
|
} LightColor;
|
||||||
|
|
||||||
typedef struct ApplicationState {
|
typedef struct ApplicationState {
|
||||||
ApplicationMode mode;
|
ApplicationMode mode;
|
||||||
bool light_pressed;
|
LightColor color;
|
||||||
bool mode_pressed;
|
|
||||||
bool alarm_pressed;
|
|
||||||
bool light_on;
|
|
||||||
uint16_t dig_T1; /**< dig_T1 cal register. */
|
|
||||||
int16_t dig_T2; /**< dig_T2 cal register. */
|
|
||||||
int16_t dig_T3; /**< dig_T3 cal register. */
|
|
||||||
} ApplicationState;
|
} ApplicationState;
|
||||||
|
|
||||||
ApplicationState applicationState;
|
ApplicationState applicationState;
|
||||||
|
|
||||||
void cb_light_pressed() {
|
void cb_light_pressed() {
|
||||||
applicationState.light_pressed = true;
|
applicationState.color = (applicationState.color + 1) % 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cb_mode_pressed() {
|
void cb_mode_pressed() {
|
||||||
applicationState.mode_pressed = true;
|
applicationState.mode = (applicationState.mode + 1) % 2;
|
||||||
}
|
|
||||||
|
|
||||||
void cb_alarm_pressed() {
|
|
||||||
applicationState.alarm_pressed = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void cb_tick() {
|
|
||||||
;
|
|
||||||
}
|
|
||||||
#define BMP280_REGISTER_DIG_T1 0x88
|
|
||||||
#define BMP280_REGISTER_DIG_T2 0x8A
|
|
||||||
#define BMP280_REGISTER_DIG_T3 0x8C
|
|
||||||
#define BMP280_REGISTER_SOFTRESET 0xE0
|
|
||||||
#define BMP280_REGISTER_STATUS 0xF3
|
|
||||||
#define BMP280_REGISTER_CONTROL 0xF4
|
|
||||||
#define BMP280_REGISTER_CONFIG 0xF5
|
|
||||||
#define BMP280_REGISTER_PRESSUREDATA 0xF7
|
|
||||||
#define BMP280_REGISTER_TEMPDATA 0xFA
|
|
||||||
|
|
||||||
uint16_t read8(uint8_t reg) {
|
|
||||||
uint8_t val;
|
|
||||||
watch_i2c_send(0x77, ®, 1);
|
|
||||||
watch_i2c_receive(0x77, &val, 1);
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t read16(uint8_t reg) {
|
|
||||||
uart_puts("\nReading 2 bytes... ");
|
|
||||||
uint8_t buf[2];
|
|
||||||
watch_i2c_send(0x77, ®, 1);
|
|
||||||
watch_i2c_receive(0x77, (uint8_t *)&buf, 2);
|
|
||||||
uart_puts("received!\n");
|
|
||||||
char buf2[32] = {0};
|
|
||||||
sprintf(buf2, "buf has values: %#02x, %#02x", buf[0], buf[1]);
|
|
||||||
uart_puts(buf2);
|
|
||||||
|
|
||||||
return (buf[0] << 8) | buf[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t read24(uint8_t reg) {
|
|
||||||
uart_puts("\nReading 3 bytes... ");
|
|
||||||
uint32_t value;
|
|
||||||
uint8_t buf[3];
|
|
||||||
|
|
||||||
watch_i2c_send(0x77, ®, 1);
|
|
||||||
watch_i2c_receive(0x77, (uint8_t *)&buf, 3);
|
|
||||||
uart_puts("received!\n");
|
|
||||||
char buf2[33] = {0};
|
|
||||||
sprintf(buf2, "buf has values: %#02x, %#02x, %#02x", buf[0], buf[1], buf[2]);
|
|
||||||
uart_puts(buf2);
|
|
||||||
|
|
||||||
value = buf[0];
|
|
||||||
value <<= 8;
|
|
||||||
value |= buf[1];
|
|
||||||
value <<= 8;
|
|
||||||
value |= buf[2];
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t read16_LE(uint8_t reg) {
|
|
||||||
uint16_t temp = read16(reg);
|
|
||||||
return (temp >> 8) | (temp << 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
int16_t readS16(uint8_t reg) {
|
|
||||||
return (int16_t)read16(reg);
|
|
||||||
}
|
|
||||||
|
|
||||||
int16_t readS16_LE(uint8_t reg) {
|
|
||||||
return (int16_t)read16_LE(reg);
|
|
||||||
}
|
|
||||||
|
|
||||||
void print_temperature() {
|
|
||||||
int32_t var1, var2;
|
|
||||||
int32_t t_fine;
|
|
||||||
|
|
||||||
int32_t adc_T = read24(BMP280_REGISTER_TEMPDATA);
|
|
||||||
adc_T >>= 4;
|
|
||||||
|
|
||||||
var1 = ((((adc_T >> 3) - ((int32_t)applicationState.dig_T1 << 1))) *
|
|
||||||
((int32_t)applicationState.dig_T2)) >>
|
|
||||||
11;
|
|
||||||
|
|
||||||
var2 = (((((adc_T >> 4) - ((int32_t)applicationState.dig_T1)) *
|
|
||||||
((adc_T >> 4) - ((int32_t)applicationState.dig_T1))) >>
|
|
||||||
12) *
|
|
||||||
((int32_t)applicationState.dig_T3)) >>
|
|
||||||
14;
|
|
||||||
|
|
||||||
t_fine = var1 + var2;
|
|
||||||
|
|
||||||
float T = ((t_fine * 5 + 128) >> 8) / 100.0;
|
|
||||||
|
|
||||||
char buf[32] = {0};
|
|
||||||
sprintf(buf, "\n\nTemp is %3.2f degrees C", T);
|
|
||||||
uart_puts(buf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -143,26 +44,14 @@ void print_temperature() {
|
|||||||
*/
|
*/
|
||||||
void app_init() {
|
void app_init() {
|
||||||
memset(&applicationState, 0, sizeof(applicationState));
|
memset(&applicationState, 0, sizeof(applicationState));
|
||||||
|
|
||||||
|
watch_enable_led(false);
|
||||||
|
|
||||||
watch_enable_buttons();
|
watch_enable_buttons();
|
||||||
watch_register_button_callback(BTN_LIGHT, cb_light_pressed);
|
watch_register_button_callback(BTN_LIGHT, cb_light_pressed);
|
||||||
|
watch_register_button_callback(BTN_MODE, cb_mode_pressed);
|
||||||
watch_enable_date_time();
|
|
||||||
watch_enable_tick_callback(cb_tick);
|
|
||||||
|
|
||||||
watch_enable_display();
|
watch_enable_display();
|
||||||
watch_enable_led();
|
|
||||||
watch_enable_i2c();
|
|
||||||
|
|
||||||
uart_puts("\n\nI2C Driver Test\n");
|
|
||||||
uint8_t reset_cmd[] = {0xE0, 0xB6};
|
|
||||||
watch_i2c_send(0x77, reset_cmd, 2);
|
|
||||||
uart_puts("Reset BMP280\n");
|
|
||||||
applicationState.dig_T1 = read16_LE(BMP280_REGISTER_DIG_T1);
|
|
||||||
applicationState.dig_T2 = readS16_LE(BMP280_REGISTER_DIG_T2);
|
|
||||||
applicationState.dig_T3 = readS16_LE(BMP280_REGISTER_DIG_T3);
|
|
||||||
|
|
||||||
uint8_t ctrl_cmd[] = {0xF4, 0xA3};
|
|
||||||
watch_i2c_send(0x77, ctrl_cmd, 2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -172,9 +61,6 @@ void app_init() {
|
|||||||
* a press on one of the buttons).
|
* a press on one of the buttons).
|
||||||
*/
|
*/
|
||||||
void app_prepare_for_sleep() {
|
void app_prepare_for_sleep() {
|
||||||
applicationState.light_pressed = false;
|
|
||||||
applicationState.mode_pressed = false;
|
|
||||||
applicationState.alarm_pressed = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -182,12 +68,33 @@ void app_prepare_for_sleep() {
|
|||||||
* STANDBY sleep mode.
|
* STANDBY sleep mode.
|
||||||
*/
|
*/
|
||||||
void app_wake_from_sleep() {
|
void app_wake_from_sleep() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief the app_loop function is called once on app startup and then again each time
|
||||||
|
* the watch STANDBY sleep mode.
|
||||||
|
*/
|
||||||
void app_loop() {
|
void app_loop() {
|
||||||
if (applicationState.light_pressed) {
|
switch (applicationState.color) {
|
||||||
print_temperature();
|
case COLOR_RED:
|
||||||
|
watch_set_led_red();
|
||||||
|
break;
|
||||||
|
case COLOR_GREEN:
|
||||||
|
watch_set_led_green();
|
||||||
|
break;
|
||||||
|
case COLOR_YELLOW:
|
||||||
|
watch_set_led_yellow();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
applicationState.color = COLOR_OFF;
|
||||||
|
watch_set_led_off();
|
||||||
|
}
|
||||||
|
switch (applicationState.mode) {
|
||||||
|
case MODE_HELLO:
|
||||||
|
watch_display_string("Hello", 5);
|
||||||
|
break;
|
||||||
|
case MODE_THERE:
|
||||||
|
watch_display_string("there", 5);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
uart_putc('.');
|
|
||||||
}
|
}
|
||||||
|
@ -25,14 +25,12 @@ struct pwm_descriptor PWM_0;
|
|||||||
|
|
||||||
struct pwm_descriptor PWM_1;
|
struct pwm_descriptor PWM_1;
|
||||||
|
|
||||||
void ADC_0_CLOCK_init(void)
|
void ADC_0_CLOCK_init(void) {
|
||||||
{
|
|
||||||
hri_mclk_set_APBCMASK_ADC_bit(MCLK);
|
hri_mclk_set_APBCMASK_ADC_bit(MCLK);
|
||||||
hri_gclk_write_PCHCTRL_reg(GCLK, ADC_GCLK_ID, CONF_GCLK_ADC_SRC | (1 << GCLK_PCHCTRL_CHEN_Pos));
|
hri_gclk_write_PCHCTRL_reg(GCLK, ADC_GCLK_ID, CONF_GCLK_ADC_SRC | (1 << GCLK_PCHCTRL_CHEN_Pos));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ADC_0_init(void)
|
void ADC_0_init(void) {
|
||||||
{
|
|
||||||
ADC_0_CLOCK_init();
|
ADC_0_CLOCK_init();
|
||||||
adc_sync_init(&ADC_0, ADC, (void *)NULL);
|
adc_sync_init(&ADC_0, ADC, (void *)NULL);
|
||||||
}
|
}
|
||||||
|
@ -101,6 +101,7 @@ int main(void) {
|
|||||||
app_loop();
|
app_loop();
|
||||||
app_prepare_for_sleep();
|
app_prepare_for_sleep();
|
||||||
sleep(4);
|
sleep(4);
|
||||||
|
app_wake_from_sleep();
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -56,6 +56,7 @@ INCLUDES += \
|
|||||||
-I../hri/ \
|
-I../hri/ \
|
||||||
-I../config/ \
|
-I../config/ \
|
||||||
-I../hw/ \
|
-I../hw/ \
|
||||||
|
-I../watch/ \
|
||||||
-I../app/ \
|
-I../app/ \
|
||||||
-I..
|
-I..
|
||||||
|
|
||||||
@ -63,7 +64,7 @@ SRCS += \
|
|||||||
../main.c \
|
../main.c \
|
||||||
../startup_saml22.c \
|
../startup_saml22.c \
|
||||||
../hw/driver_init.c \
|
../hw/driver_init.c \
|
||||||
../hw/watch.c \
|
../watch/watch.c \
|
||||||
../app/app.c \
|
../app/app.c \
|
||||||
../hal/src/hal_adc_sync.c \
|
../hal/src/hal_adc_sync.c \
|
||||||
../hal/src/hal_atomic.c \
|
../hal/src/hal_atomic.c \
|
||||||
|
@ -12,6 +12,11 @@ void watch_init() {
|
|||||||
// use switching regulator
|
// use switching regulator
|
||||||
SUPC->VREG.bit.SEL = 1;
|
SUPC->VREG.bit.SEL = 1;
|
||||||
while(!SUPC->STATUS.bit.VREGRDY);
|
while(!SUPC->STATUS.bit.VREGRDY);
|
||||||
|
|
||||||
|
// External wake depends on RTC; calendar is a required module.
|
||||||
|
CALENDAR_0_init();
|
||||||
|
calendar_enable(&CALENDAR_0);
|
||||||
|
|
||||||
// TODO: use performance level 0?
|
// TODO: use performance level 0?
|
||||||
// _set_performance_level(0);
|
// _set_performance_level(0);
|
||||||
// hri_pm_write_PLCFG_PLDIS_bit(PM, true);
|
// hri_pm_write_PLCFG_PLDIS_bit(PM, true);
|
||||||
@ -181,45 +186,76 @@ void watch_register_button_callback(const uint32_t pin, ext_irq_cb_t callback) {
|
|||||||
ext_irq_register(pin, callback);
|
ext_irq_register(pin, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool PWM_0_enabled = false;
|
bool PWM_0_enabled = false;
|
||||||
|
|
||||||
void watch_enable_led() {
|
void watch_enable_led(bool pwm) {
|
||||||
if (!PWM_0_enabled) PWM_0_init();
|
if (pwm) {
|
||||||
PWM_0_enabled = true;
|
if (PWM_0_enabled) return;
|
||||||
|
|
||||||
|
PWM_0_init();
|
||||||
pwm_set_parameters(&PWM_0, 10000, 0);
|
pwm_set_parameters(&PWM_0, 10000, 0);
|
||||||
pwm_enable(&PWM_0);
|
pwm_enable(&PWM_0);
|
||||||
|
|
||||||
|
PWM_0_enabled = true;
|
||||||
|
} else {
|
||||||
|
watch_enable_digital_output(RED);
|
||||||
|
watch_enable_digital_output(GREEN);
|
||||||
|
}
|
||||||
watch_set_led_off();
|
watch_set_led_off();
|
||||||
}
|
}
|
||||||
|
|
||||||
void watch_disable_led() {
|
void watch_disable_led(bool pwm) {
|
||||||
gpio_set_pin_function(RED, GPIO_PIN_FUNCTION_OFF);
|
if (pwm) {
|
||||||
gpio_set_pin_function(GREEN, GPIO_PIN_FUNCTION_OFF);
|
if (!PWM_0_enabled) return;
|
||||||
|
|
||||||
pwm_disable(&PWM_0);
|
pwm_disable(&PWM_0);
|
||||||
PWM_0_enabled = false;
|
PWM_0_enabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
watch_disable_digital_output(RED);
|
||||||
|
watch_disable_digital_output(GREEN);
|
||||||
|
}
|
||||||
|
|
||||||
void watch_set_led_color(uint16_t red, uint16_t green) {
|
void watch_set_led_color(uint16_t red, uint16_t green) {
|
||||||
|
if (PWM_0_enabled) {
|
||||||
TC3->COUNT16.CC[0].reg = red;
|
TC3->COUNT16.CC[0].reg = red;
|
||||||
TC3->COUNT16.CC[1].reg = green;
|
TC3->COUNT16.CC[1].reg = green;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void watch_set_led_red() {
|
void watch_set_led_red() {
|
||||||
|
if (PWM_0_enabled) {
|
||||||
watch_set_led_color(65535, 0);
|
watch_set_led_color(65535, 0);
|
||||||
|
} else {
|
||||||
|
watch_set_pin_level(RED, true);
|
||||||
|
watch_set_pin_level(GREEN, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void watch_set_led_green() {
|
void watch_set_led_green() {
|
||||||
watch_set_led_color(0, 65535);
|
if (PWM_0_enabled) {
|
||||||
|
watch_set_led_color(65535, 0);
|
||||||
|
} else {
|
||||||
|
watch_set_pin_level(RED, false);
|
||||||
|
watch_set_pin_level(GREEN, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void watch_set_led_yellow() {
|
||||||
|
if (PWM_0_enabled) {
|
||||||
|
watch_set_led_color(65535, 65535);
|
||||||
|
} else {
|
||||||
|
watch_set_pin_level(RED, true);
|
||||||
|
watch_set_pin_level(GREEN, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void watch_set_led_off() {
|
void watch_set_led_off() {
|
||||||
|
if (PWM_0_enabled) {
|
||||||
watch_set_led_color(0, 0);
|
watch_set_led_color(0, 0);
|
||||||
|
} else {
|
||||||
|
watch_set_pin_level(RED, false);
|
||||||
|
watch_set_pin_level(GREEN, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void watch_enable_date_time() {
|
|
||||||
CALENDAR_0_init();
|
|
||||||
calendar_enable(&CALENDAR_0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void watch_set_date_time(struct calendar_date_time date_time) {
|
void watch_set_date_time(struct calendar_date_time date_time) {
|
||||||
@ -287,6 +323,10 @@ void watch_enable_digital_output(const uint8_t pin) {
|
|||||||
gpio_set_pin_function(pin, GPIO_PIN_FUNCTION_OFF);
|
gpio_set_pin_function(pin, GPIO_PIN_FUNCTION_OFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void watch_disable_digital_output(const uint8_t pin) {
|
||||||
|
gpio_set_pin_direction(pin, GPIO_DIRECTION_OFF);
|
||||||
|
}
|
||||||
|
|
||||||
void watch_set_pin_level(const uint8_t pin, const bool level) {
|
void watch_set_pin_level(const uint8_t pin, const bool level) {
|
||||||
gpio_set_pin_level(pin, level);
|
gpio_set_pin_level(pin, level);
|
||||||
}
|
}
|
@ -19,14 +19,13 @@ void watch_enable_display();
|
|||||||
void watch_display_pixel(uint8_t com, uint8_t seg);
|
void watch_display_pixel(uint8_t com, uint8_t seg);
|
||||||
void watch_display_string(char *string, uint8_t position);
|
void watch_display_string(char *string, uint8_t position);
|
||||||
|
|
||||||
void watch_enable_led();
|
void watch_enable_led(bool pwm);
|
||||||
void watch_disable_led();
|
void watch_disable_led(bool pwm);
|
||||||
void watch_set_led_color(uint16_t red, uint16_t green);
|
void watch_set_led_color(uint16_t red, uint16_t green);
|
||||||
void watch_set_led_red();
|
void watch_set_led_red();
|
||||||
void watch_set_led_green();
|
void watch_set_led_green();
|
||||||
void watch_set_led_off();
|
void watch_set_led_off();
|
||||||
|
|
||||||
void watch_enable_date_time();
|
|
||||||
void watch_set_date_time(struct calendar_date_time date_time);
|
void watch_set_date_time(struct calendar_date_time date_time);
|
||||||
void watch_get_date_time(struct calendar_date_time *date_time);
|
void watch_get_date_time(struct calendar_date_time *date_time);
|
||||||
|
|
||||||
@ -43,6 +42,7 @@ void watch_enable_pull_down(const uint8_t pin);
|
|||||||
bool watch_get_pin_level(const uint8_t pin, const bool level);
|
bool watch_get_pin_level(const uint8_t pin, const bool level);
|
||||||
|
|
||||||
void watch_enable_digital_output(const uint8_t pin);
|
void watch_enable_digital_output(const uint8_t pin);
|
||||||
|
void watch_disable_digital_output(const uint8_t pin);
|
||||||
void watch_set_pin_level(const uint8_t pin, const bool level);
|
void watch_set_pin_level(const uint8_t pin, const bool level);
|
||||||
|
|
||||||
struct io_descriptor *I2C_0_io;
|
struct io_descriptor *I2C_0_io;
|
Loading…
x
Reference in New Issue
Block a user