summaryrefslogtreecommitdiff
path: root/src/drivers/TwiMaster.cpp
blob: 646823d076fcf2a3629151fe341e3dc6bbf42274 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#include "TwiMaster.h"
#include <cstring>
#include <hal/nrf_gpio.h>
#include <nrfx_log.h>
#include <nrfx_twim.h>
#include <nrf_drv_twi.h>
using namespace Pinetime::Drivers;

// TODO use shortcut to automatically send STOP when receive LastTX, for example
// TODO use DMA/IRQ

TwiMaster::TwiMaster(const Modules module, const Parameters& params) : module{module}, params{params}, mutex{xSemaphoreCreateBinary()} {
  ASSERT(mutex != nullptr);
  switch(module) {
    case Modules::TWIM1:
    default:
      twim = NRFX_TWIM_INSTANCE(1);
      break;
  }
}

void TwiMaster::Init() {
  nrfx_twim_config_t config;
  config.frequency = static_cast<nrf_twim_frequency_t>(params.frequency);
  config.hold_bus_uninit = false;
  config.interrupt_priority = 0;
  config.scl = params.pinScl;
  config.sda = params.pinSda;
  nrfx_twim_init(&twim,
                 &config,
                 nullptr,
                 nullptr);
  nrfx_twim_enable(&twim);

  xSemaphoreGive(mutex);
}

TwiMaster::ErrorCodes TwiMaster::Read(uint8_t deviceAddress, uint8_t registerAddress, uint8_t *data, size_t size) {
  xSemaphoreTake(mutex, portMAX_DELAY);
  TwiMaster::ErrorCodes ret;

  auto err = nrfx_twim_tx(&twim, deviceAddress, &registerAddress, 1, false);
  if(err != 0) {
    return TwiMaster::ErrorCodes::TransactionFailed;
  }

  err = nrfx_twim_rx(&twim, deviceAddress, data, size);
  if(err != 0) {
    return TwiMaster::ErrorCodes::TransactionFailed;
  }
  xSemaphoreGive(mutex);

  return TwiMaster::ErrorCodes::NoError;
}

TwiMaster::ErrorCodes TwiMaster::Write(uint8_t deviceAddress, uint8_t registerAddress, const uint8_t *data, size_t size) {
  ASSERT(size <= maxDataSize);
  xSemaphoreTake(mutex, portMAX_DELAY);
  TwiMaster::ErrorCodes ret;

  internalBuffer[0] = registerAddress;
  std::memcpy(internalBuffer+1, data, size);
  auto err = nrfx_twim_tx(&twim, deviceAddress, internalBuffer , size+1, false);
  if(err != 0){
    return TwiMaster::ErrorCodes::TransactionFailed;
  }

  xSemaphoreGive(mutex);
  return TwiMaster::ErrorCodes::NoError;
}

void TwiMaster::Sleep() {
  nrfx_twim_disable(&twim);
  nrfx_twim_uninit(&twim);

  nrf_gpio_cfg_default(6);
  nrf_gpio_cfg_default(7);
  NRF_LOG_INFO("[TWIMASTER] Sleep");
}

void TwiMaster::Wakeup() {
  Init();
  NRF_LOG_INFO("[TWIMASTER] Wakeup");
}