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.
//==========================================================
#ifndef NRFX_PWM_CONFIG_LOG_ENABLED
#define NRFX_PWM_CONFIG_LOG_ENABLED 0
#define NRFX_PWM_CONFIG_LOG_ENABLED 1
#endif
// <o> NRFX_PWM_CONFIG_LOG_LEVEL - Default Severity level
@ -2846,7 +2846,7 @@
// <4=> Debug
#ifndef NRFX_PWM_CONFIG_LOG_LEVEL
#define NRFX_PWM_CONFIG_LOG_LEVEL 3
#define NRFX_PWM_CONFIG_LOG_LEVEL 4
#endif
// <o> NRFX_PWM_CONFIG_INFO_COLOR - ANSI escape code prefix.
@ -4351,7 +4351,7 @@
// <4=> Debug
#ifndef NRFX_TWI_CONFIG_LOG_LEVEL
#define NRFX_TWI_CONFIG_LOG_LEVEL 3
#define NRFX_TWI_CONFIG_LOG_LEVEL 4
#endif
// <o> NRFX_TWI_CONFIG_INFO_COLOR - ANSI escape code prefix.
@ -8650,7 +8650,7 @@
// <4=> Debug
#ifndef RTC_CONFIG_LOG_LEVEL
#define RTC_CONFIG_LOG_LEVEL 4
#define RTC_CONFIG_LOG_LEVEL 3
#endif
// <o> RTC_CONFIG_INFO_COLOR - ANSI escape code prefix.
@ -8956,7 +8956,7 @@
// <4=> Debug
#ifndef TWI_CONFIG_LOG_LEVEL
#define TWI_CONFIG_LOG_LEVEL 3
#define TWI_CONFIG_LOG_LEVEL 4
#endif
// <o> TWI_CONFIG_INFO_COLOR - ANSI escape code prefix.

View file

@ -23,9 +23,9 @@
#define DEAD_BEEF 0xDEADBEEF
void assert_nrf_callback(uint16_t line_num, const uint8_t *p_file_name) {
app_error_handler(DEAD_BEEF, line_num, 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);
// }
static void log_init(void) {
ret_code_t err_code = NRF_LOG_INIT(NULL);
@ -55,20 +55,28 @@ static void power_manage(void) {
}
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() {
NRF_LOG_INFO("rtc callback running...\n");
NRF_LOG_FLUSH();
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_start();
// TODO: ADC.
nrf_delay_ms(500);
// TODO: PWM pin seems to be stuch on high after stop.
prst_pwm_stop();
prst_ble_update_adv_data(++data);
prst_adv_start();
nrf_delay_ms(300);
prst_adv_stop();
nrf_gpio_pin_clear(PRST_LED_PIN);
NRF_LOG_FLUSH();
}
int main(void) {
@ -76,12 +84,9 @@ int main(void) {
leds_init();
power_management_init();
prst_ble_init();
prst_sht3c_init();
prst_shtc3_init();
prst_rtc_set_callback(rtc_callback);
NRF_LOG_FLUSH();
// UNUSED_VARIABLE(prst_rtc_init());
UNUSED_VARIABLE(prst_rtc_init));
prst_rtc_init();
for (;;) {
power_manage();

View file

@ -16,11 +16,13 @@
// 50% below with PRST_PWM_FLIP_AT_COUNT to be half the max count.
#define PRST_PWM_MAX_COUNT 16
// 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_pwm_values_common_t seq_values_[] = {PRST_PWM_FLIP_AT_COUNT};
static const nrf_pwm_sequence_t seq_ = {
.values.p_common = seq_values_,
.length = NRF_PWM_VALUES_LENGTH(seq_values_),
@ -28,19 +30,25 @@ static const nrf_pwm_sequence_t seq_ = {
.end_delay = 0};
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 = {
// 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 =
{
PRST_PWM_PIN | NRF_DRV_PWM_PIN_INVERTED, // channel 0
NRF_DRV_PWM_PIN_NOT_USED, // channel 1
NRF_DRV_PWM_PIN_NOT_USED, // channel 2
NRF_DRV_PWM_PIN_NOT_USED, // channel 3
PRST_PWM_PIN | NRF_DRV_PWM_PIN_INVERTED,
NRF_DRV_PWM_PIN_NOT_USED,
NRF_DRV_PWM_PIN_NOT_USED,
NRF_DRV_PWM_PIN_NOT_USED,
},
.irq_priority = APP_IRQ_PRIORITY_LOWEST,
// This is the hal PRESCALER.
// This is the hal PRESCALER
.base_clock = NRF_PWM_CLK_16MHz,
// This is the hal COUNTERTOP.
.count_mode = NRF_PWM_MODE_UP_AND_DOWN,
// This is the hal COUNTERTOP.
.top_value = PRST_PWM_MAX_COUNT,
.load_mode = NRF_PWM_LOAD_COMMON,
.step_mode = NRF_PWM_STEP_AUTO};
@ -48,12 +56,16 @@ void prst_pwm_init() {
}
void prst_pwm_start() {
// Loop forever.
// Loop until stopped.
APP_ERROR_CHECK(
nrf_drv_pwm_simple_playback(&m_pwm0, &seq_, 1, NRF_DRV_PWM_FLAG_LOOP));
}
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_gpio_pin_clear(PRST_PWM_PIN);
}

View file

@ -5,44 +5,60 @@
#include <nrf_drv_twi.h>
#include <nrf_gpio.h>
#include <nrf_log.h>
#include <nrf_log_ctrl.h>
// #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
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 tx_data[] = {0x2c, 0x06};
void prst_sht3c_init() {
nrf_drv_twi_config_t twi_config = NRF_DRV_TWI_DEFAULT_CONFIG;
twi_config.scl = NRF_GPIO_PIN_MAP(0, 3);
twi_config.sda = NRF_GPIO_PIN_MAP(0, 28);
void prst_shtc3_init() {
twi_config_.scl = NRF_GPIO_PIN_MAP(0, 3);
twi_config_.sda = NRF_GPIO_PIN_MAP(0, 2);
// 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;
// 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};
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);
nrf_delay_ms(10);
nrf_drv_twi_enable(&twi_);
nrf_delay_ms(10);
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);
nrf_delay_ms(10);
NRF_LOG_INFO("WILL READ DATA:");
err_code = nrf_drv_twi_rx(&twi_, PRST_SHT3C_DEFAULT_ADDR, buff, 6);
NRF_LOG_INFO("OH NO!");
APP_ERROR_CHECK(err_code);
NRF_LOG_INFO("READ DATA: \n");
for (int i = 0; i < 6; i++) {
NRF_LOG_INFO("0x%d ", buff[i]);
// TODO(rbaron): timeout.
while (true) {
err_code = nrf_drv_twi_rx(&twi_, PRST_SHT3C_DEFAULT_ADDR, buff, 6);
if (err_code == NRF_ERROR_DRV_TWI_ERR_ANACK) {
nrf_delay_ms(10);
continue;
}
break;
}
NRF_LOG_INFO("Okay. \n");
}
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_
#define _PRST_SHT3C_H_
typedef struct prst_sht3c_read {
} prst_sh3c_read_t;
typedef struct prst_shtc3_values {
double temp_c;
double humidity;
} prst_shtc3_read_t;
void prst_sht3c_init();
void prst_sht3c_read();
void prst_shtc3_init();
prst_shtc3_read_t prst_shtc3_read();
#endif // _PRST_SHT3C_H_

View file

@ -425,4 +425,7 @@ Comparison table form Sensirion: [link](https://www.sensirion.com/en/environment
* ~ $1.5 each
* Google JLC support for assembly [link](https://jlcpcb.com/parts/componentSearch?searchTxt=sht30)
* 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)