A hacky fix for PWM + TWI

This commit is contained in:
rbaron 2021-03-15 22:40:09 +01:00
parent 02df5f4595
commit b521e3f0f6
6 changed files with 86 additions and 48 deletions

View file

@ -2835,7 +2835,7 @@
// <e> NRFX_PWM_CONFIG_LOG_ENABLED - Enables logging in the module. // <e> NRFX_PWM_CONFIG_LOG_ENABLED - Enables logging in the module.
//========================================================== //==========================================================
#ifndef NRFX_PWM_CONFIG_LOG_ENABLED #ifndef NRFX_PWM_CONFIG_LOG_ENABLED
#define NRFX_PWM_CONFIG_LOG_ENABLED 0 #define NRFX_PWM_CONFIG_LOG_ENABLED 1
#endif #endif
// <o> NRFX_PWM_CONFIG_LOG_LEVEL - Default Severity level // <o> NRFX_PWM_CONFIG_LOG_LEVEL - Default Severity level
@ -2846,7 +2846,7 @@
// <4=> Debug // <4=> Debug
#ifndef NRFX_PWM_CONFIG_LOG_LEVEL #ifndef NRFX_PWM_CONFIG_LOG_LEVEL
#define NRFX_PWM_CONFIG_LOG_LEVEL 3 #define NRFX_PWM_CONFIG_LOG_LEVEL 4
#endif #endif
// <o> NRFX_PWM_CONFIG_INFO_COLOR - ANSI escape code prefix. // <o> NRFX_PWM_CONFIG_INFO_COLOR - ANSI escape code prefix.
@ -4351,7 +4351,7 @@
// <4=> Debug // <4=> Debug
#ifndef NRFX_TWI_CONFIG_LOG_LEVEL #ifndef NRFX_TWI_CONFIG_LOG_LEVEL
#define NRFX_TWI_CONFIG_LOG_LEVEL 3 #define NRFX_TWI_CONFIG_LOG_LEVEL 4
#endif #endif
// <o> NRFX_TWI_CONFIG_INFO_COLOR - ANSI escape code prefix. // <o> NRFX_TWI_CONFIG_INFO_COLOR - ANSI escape code prefix.
@ -8650,7 +8650,7 @@
// <4=> Debug // <4=> Debug
#ifndef RTC_CONFIG_LOG_LEVEL #ifndef RTC_CONFIG_LOG_LEVEL
#define RTC_CONFIG_LOG_LEVEL 4 #define RTC_CONFIG_LOG_LEVEL 3
#endif #endif
// <o> RTC_CONFIG_INFO_COLOR - ANSI escape code prefix. // <o> RTC_CONFIG_INFO_COLOR - ANSI escape code prefix.
@ -8956,7 +8956,7 @@
// <4=> Debug // <4=> Debug
#ifndef TWI_CONFIG_LOG_LEVEL #ifndef TWI_CONFIG_LOG_LEVEL
#define TWI_CONFIG_LOG_LEVEL 3 #define TWI_CONFIG_LOG_LEVEL 4
#endif #endif
// <o> TWI_CONFIG_INFO_COLOR - ANSI escape code prefix. // <o> TWI_CONFIG_INFO_COLOR - ANSI escape code prefix.

View file

@ -23,9 +23,9 @@
#define DEAD_BEEF 0xDEADBEEF #define DEAD_BEEF 0xDEADBEEF
void assert_nrf_callback(uint16_t line_num, const uint8_t *p_file_name) { // void assert_nrf_callback(uint16_t line_num, const uint8_t *p_file_name) {
app_error_handler(DEAD_BEEF, line_num, p_file_name); // app_error_handler(DEAD_BEEF, line_num, p_file_name);
} // }
static void log_init(void) { static void log_init(void) {
ret_code_t err_code = NRF_LOG_INIT(NULL); ret_code_t err_code = NRF_LOG_INIT(NULL);
@ -55,20 +55,28 @@ static void power_manage(void) {
} }
static uint8_t data; static uint8_t data;
// Here we need to be extra careful with what operations we do. This callback
// has to return fast-ish, otherwise we hit some hard exceptions.
static void rtc_callback() { static void rtc_callback() {
NRF_LOG_INFO("rtc callback running...\n"); NRF_LOG_INFO("rtc callback running...\n");
NRF_LOG_FLUSH(); NRF_LOG_FLUSH();
nrf_gpio_pin_set(PRST_LED_PIN); nrf_gpio_pin_set(PRST_LED_PIN);
prst_shtc3_read_t temp_humi = prst_shtc3_read();
NRF_LOG_INFO("Read temp: " NRF_LOG_FLOAT_MARKER " oC",
NRF_LOG_FLOAT(temp_humi.temp_c));
prst_pwm_init(); prst_pwm_init();
prst_pwm_start(); prst_pwm_start();
// TODO: ADC. // TODO: ADC.
nrf_delay_ms(500); nrf_delay_ms(500);
// TODO: PWM pin seems to be stuch on high after stop.
prst_pwm_stop(); prst_pwm_stop();
prst_ble_update_adv_data(++data); prst_ble_update_adv_data(++data);
prst_adv_start(); prst_adv_start();
nrf_delay_ms(300); nrf_delay_ms(300);
prst_adv_stop(); prst_adv_stop();
nrf_gpio_pin_clear(PRST_LED_PIN); nrf_gpio_pin_clear(PRST_LED_PIN);
NRF_LOG_FLUSH();
} }
int main(void) { int main(void) {
@ -76,12 +84,9 @@ int main(void) {
leds_init(); leds_init();
power_management_init(); power_management_init();
prst_ble_init(); prst_ble_init();
prst_shtc3_init();
prst_sht3c_init();
prst_rtc_set_callback(rtc_callback); prst_rtc_set_callback(rtc_callback);
NRF_LOG_FLUSH(); prst_rtc_init();
// UNUSED_VARIABLE(prst_rtc_init());
UNUSED_VARIABLE(prst_rtc_init));
for (;;) { for (;;) {
power_manage(); power_manage();

View file

@ -16,11 +16,13 @@
// 50% below with PRST_PWM_FLIP_AT_COUNT to be half the max count. // 50% below with PRST_PWM_FLIP_AT_COUNT to be half the max count.
#define PRST_PWM_MAX_COUNT 16 #define PRST_PWM_MAX_COUNT 16
// We will toggle the PWM output when we reach this count. // We will toggle the PWM output when we reach this count.
#define PRST_PWM_FLIP_AT_COUNT PRST_PWM_MAX_COUNT / 2 // #define PRST_PWM_FLIP_AT_COUNT PRST_PWM_MAX_COUNT / 2
#define PRST_PWM_FLIP_AT_COUNT 8
static nrf_drv_pwm_t m_pwm0 = NRF_DRV_PWM_INSTANCE(0); static nrf_drv_pwm_t m_pwm0 = NRF_DRV_PWM_INSTANCE(0);
static nrf_pwm_values_common_t seq_values_[] = {PRST_PWM_FLIP_AT_COUNT}; static nrf_pwm_values_common_t seq_values_[] = {PRST_PWM_FLIP_AT_COUNT};
static const nrf_pwm_sequence_t seq_ = { static const nrf_pwm_sequence_t seq_ = {
.values.p_common = seq_values_, .values.p_common = seq_values_,
.length = NRF_PWM_VALUES_LENGTH(seq_values_), .length = NRF_PWM_VALUES_LENGTH(seq_values_),
@ -28,19 +30,25 @@ static const nrf_pwm_sequence_t seq_ = {
.end_delay = 0}; .end_delay = 0};
void prst_pwm_init() { void prst_pwm_init() {
// We set the PWM pin as output so we can control its state after the PWM is
// stopped. Without this, I'm seeing the PWM pin remaining high after stopped.
nrf_gpio_pin_dir_set(PRST_PWM_PIN, NRF_GPIO_PIN_DIR_OUTPUT);
nrf_drv_pwm_config_t const config0 = { nrf_drv_pwm_config_t const config0 = {
// We have to specify the state of the 4 channels. We only care about the
// first one, so we set all others to not used.
.output_pins = .output_pins =
{ {
PRST_PWM_PIN | NRF_DRV_PWM_PIN_INVERTED, // channel 0 PRST_PWM_PIN | NRF_DRV_PWM_PIN_INVERTED,
NRF_DRV_PWM_PIN_NOT_USED, // channel 1 NRF_DRV_PWM_PIN_NOT_USED,
NRF_DRV_PWM_PIN_NOT_USED, // channel 2 NRF_DRV_PWM_PIN_NOT_USED,
NRF_DRV_PWM_PIN_NOT_USED, // channel 3 NRF_DRV_PWM_PIN_NOT_USED,
}, },
.irq_priority = APP_IRQ_PRIORITY_LOWEST, .irq_priority = APP_IRQ_PRIORITY_LOWEST,
// This is the hal PRESCALER. // This is the hal PRESCALER
.base_clock = NRF_PWM_CLK_16MHz, .base_clock = NRF_PWM_CLK_16MHz,
// This is the hal COUNTERTOP.
.count_mode = NRF_PWM_MODE_UP_AND_DOWN, .count_mode = NRF_PWM_MODE_UP_AND_DOWN,
// This is the hal COUNTERTOP.
.top_value = PRST_PWM_MAX_COUNT, .top_value = PRST_PWM_MAX_COUNT,
.load_mode = NRF_PWM_LOAD_COMMON, .load_mode = NRF_PWM_LOAD_COMMON,
.step_mode = NRF_PWM_STEP_AUTO}; .step_mode = NRF_PWM_STEP_AUTO};
@ -48,12 +56,16 @@ void prst_pwm_init() {
} }
void prst_pwm_start() { void prst_pwm_start() {
// Loop forever. // Loop until stopped.
APP_ERROR_CHECK( APP_ERROR_CHECK(
nrf_drv_pwm_simple_playback(&m_pwm0, &seq_, 1, NRF_DRV_PWM_FLAG_LOOP)); nrf_drv_pwm_simple_playback(&m_pwm0, &seq_, 1, NRF_DRV_PWM_FLAG_LOOP));
} }
void prst_pwm_stop() { void prst_pwm_stop() {
APP_ERROR_CHECK(nrf_drv_pwm_stop(&m_pwm0, /*wait_until_stopped=*/true)); // Careful when using wait_until_stopped! When calling this from within the
// RTC callback, somtimes I'm hitting a hard exception. I haven't figured it
// out yet, but probably some race condition for waiting + rtc?
APP_ERROR_CHECK(nrf_drv_pwm_stop(&m_pwm0, /*wait_until_stopped=*/false));
nrf_drv_pwm_uninit(&m_pwm0); nrf_drv_pwm_uninit(&m_pwm0);
nrf_gpio_pin_clear(PRST_PWM_PIN);
} }

View file

@ -5,44 +5,60 @@
#include <nrf_drv_twi.h> #include <nrf_drv_twi.h>
#include <nrf_gpio.h> #include <nrf_gpio.h>
#include <nrf_log.h> #include <nrf_log.h>
#include <nrf_log_ctrl.h>
// #define PRST_SHT3C_DEFAULT_ADDR 0x70 // #define PRST_SHT3C_DEFAULT_ADDR 0x70
// I'm using a sht30 to test while I wait for the new PCBs.
#define PRST_SHT3C_DEFAULT_ADDR 0x44 #define PRST_SHT3C_DEFAULT_ADDR 0x44
static const nrf_drv_twi_t twi_ = NRF_DRV_TWI_INSTANCE(0); static const nrf_drv_twi_t twi_ = NRF_DRV_TWI_INSTANCE(0);
static nrf_drv_twi_config_t twi_config_ = NRF_DRV_TWI_DEFAULT_CONFIG;
static uint8_t buff[6]; static uint8_t buff[6];
static uint8_t tx_data[] = {0x2c, 0x06};
void prst_sht3c_init() { void prst_shtc3_init() {
nrf_drv_twi_config_t twi_config = NRF_DRV_TWI_DEFAULT_CONFIG; twi_config_.scl = NRF_GPIO_PIN_MAP(0, 3);
twi_config.scl = NRF_GPIO_PIN_MAP(0, 3); twi_config_.sda = NRF_GPIO_PIN_MAP(0, 2);
twi_config.sda = NRF_GPIO_PIN_MAP(0, 28);
// twi_config.clear_bus_init = true; // twi_config.clear_bus_init = true;
twi_config.frequency = NRF_TWI_FREQ_400K; twi_config_.frequency = NRF_TWI_FREQ_100K;
}
prst_shtc3_read_t prst_shtc3_read() {
uint32_t err_code; uint32_t err_code;
// Sends request for data with clock stretching. Currently not working
// very well - sometimes it works, sometimes the read blocks forever.
// uint8_t tx_data[] = {0x2c, 0x06}; // uint8_t tx_data[] = {0x2c, 0x06};
err_code = nrf_drv_twi_init(&twi_, &twi_config, NULL, NULL); // Request for data withour clock stretching. If no data is available yet,
// the result will be a NACK.
uint8_t tx_data[] = {0x24, 0x00};
err_code = nrf_drv_twi_init(&twi_, &twi_config_, NULL, NULL);
APP_ERROR_CHECK(err_code); APP_ERROR_CHECK(err_code);
nrf_delay_ms(10);
nrf_drv_twi_enable(&twi_); nrf_drv_twi_enable(&twi_);
nrf_delay_ms(10); nrf_delay_ms(10);
err_code = nrf_drv_twi_tx(&twi_, PRST_SHT3C_DEFAULT_ADDR, tx_data, err_code = nrf_drv_twi_tx(&twi_, PRST_SHT3C_DEFAULT_ADDR, tx_data,
sizeof(tx_data), true); sizeof(tx_data), false);
APP_ERROR_CHECK(err_code); APP_ERROR_CHECK(err_code);
nrf_delay_ms(10); // TODO(rbaron): timeout.
while (true) {
NRF_LOG_INFO("WILL READ DATA:");
err_code = nrf_drv_twi_rx(&twi_, PRST_SHT3C_DEFAULT_ADDR, buff, 6); err_code = nrf_drv_twi_rx(&twi_, PRST_SHT3C_DEFAULT_ADDR, buff, 6);
NRF_LOG_INFO("OH NO!"); if (err_code == NRF_ERROR_DRV_TWI_ERR_ANACK) {
APP_ERROR_CHECK(err_code); nrf_delay_ms(10);
continue;
NRF_LOG_INFO("READ DATA: \n");
for (int i = 0; i < 6; i++) {
NRF_LOG_INFO("0x%d ", buff[i]);
} }
NRF_LOG_INFO("Okay. \n"); break;
} }
void prst_sht3c_read(); // TODO(rbaron): put the sensor to sleep & save power.
nrf_drv_twi_uninit(&twi_);
NRF_LOG_INFO("Computing...");
double temp_c =
-45 + 175 * ((double)((buff[0] << 8) | buff[1])) / ((1 << 16) - 1);
// double humi = 100 * ( (double) ((buff[0] << 8) | buff[1])) / ((1<<16) - 1);
prst_shtc3_read_t ret = {.temp_c = temp_c, .humidity = 0};
return ret;
}

View file

@ -1,10 +1,12 @@
#ifndef _PRST_SHT3C_H_ #ifndef _PRST_SHT3C_H_
#define _PRST_SHT3C_H_ #define _PRST_SHT3C_H_
typedef struct prst_sht3c_read { typedef struct prst_shtc3_values {
} prst_sh3c_read_t; double temp_c;
double humidity;
} prst_shtc3_read_t;
void prst_sht3c_init(); void prst_shtc3_init();
void prst_sht3c_read(); prst_shtc3_read_t prst_shtc3_read();
#endif // _PRST_SHT3C_H_ #endif // _PRST_SHT3C_H_

View file

@ -426,3 +426,6 @@ Comparison table form Sensirion: [link](https://www.sensirion.com/en/environment
* Google JLC support for assembly [link](https://jlcpcb.com/parts/componentSearch?searchTxt=sht30) * Google JLC support for assembly [link](https://jlcpcb.com/parts/componentSearch?searchTxt=sht30)
* 0.3uA in sleep * 0.3uA in sleep
* KiCad footprint on [GitHub](https://kicad.github.io/symbols/Sensor_Humidity) * KiCad footprint on [GitHub](https://kicad.github.io/symbols/Sensor_Humidity)
# Antenna
* Guide for PCB design on [devzone](https://devzone.nordicsemi.com/nordic/short-range-guides/b/hardware-and-layout/posts/general-pcb-design-guidelines-for-nrf52)