Skip to content

Instantly share code, notes, and snippets.

@ishtob
Last active April 15, 2018 01:51
Show Gist options
  • Save ishtob/22769c217bc0954d5ab4e73014850fb3 to your computer and use it in GitHub Desktop.
Save ishtob/22769c217bc0954d5ab4e73014850fb3 to your computer and use it in GitHub Desktop.
mitosis-mod
//#define COMPILE_RIGHT
#define COMPILE_LEFT
#include "mitosis.h"
#include "nrf_drv_config.h"
#include "nrf_gzll.h"
#include "nrf_gpio.h"
#include "nrf_delay.h"
#include "nrf_drv_clock.h"
#include "nrf_drv_rtc.h"
/*****************************************************************************/
/** Configuration */
/*****************************************************************************/
const nrf_drv_rtc_t rtc_maint = NRF_DRV_RTC_INSTANCE(0); /**< Declaring an instance of nrf_drv_rtc for RTC0. */
const nrf_drv_rtc_t rtc_deb = NRF_DRV_RTC_INSTANCE(1); /**< Declaring an instance of nrf_drv_rtc for RTC1. */
// Define payload length
#define TX_PAYLOAD_LENGTH 3 ///< 3 byte payload length when transmitting
// Data and acknowledgement payloads
static uint8_t data_payload[TX_PAYLOAD_LENGTH]; ///< Payload to send to Host.
static uint8_t ack_payload[NRF_GZLL_CONST_MAX_PAYLOAD_LENGTH]; ///< Placeholder for received ACK payloads from Host.
// Debounce time (dependent on tick frequency)
#define DEBOUNCE 5
#define ACTIVITY 500
// Key buffers
static uint32_t keys, keys_snapshot;
static uint32_t debounce_ticks, activity_ticks;
static volatile bool debouncing = false;
// Debug helper variables
static volatile bool init_ok, enable_ok, push_ok, pop_ok, tx_success;
// Setup switch pins with pullups
static void gpio_config(void)
{
nrf_gpio_cfg_sense_input(S01, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_SENSE_LOW);
nrf_gpio_cfg_sense_input(S02, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_SENSE_LOW);
nrf_gpio_cfg_sense_input(S03, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_SENSE_LOW);
nrf_gpio_cfg_sense_input(S04, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_SENSE_LOW);
nrf_gpio_cfg_sense_input(S05, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_SENSE_LOW);
nrf_gpio_cfg_sense_input(S06, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_SENSE_LOW);
nrf_gpio_cfg_sense_input(S07, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_SENSE_LOW);
nrf_gpio_cfg_sense_input(S08, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_SENSE_LOW);
nrf_gpio_cfg_sense_input(S09, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_SENSE_LOW);
nrf_gpio_cfg_sense_input(S10, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_SENSE_LOW);
nrf_gpio_cfg_sense_input(S11, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_SENSE_LOW);
nrf_gpio_cfg_sense_input(S12, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_SENSE_LOW);
nrf_gpio_cfg_sense_input(S13, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_SENSE_LOW);
nrf_gpio_cfg_sense_input(S14, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_SENSE_LOW);
nrf_gpio_cfg_sense_input(S15, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_SENSE_LOW);
nrf_gpio_cfg_sense_input(S16, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_SENSE_LOW);
nrf_gpio_cfg_sense_input(S17, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_SENSE_LOW);
nrf_gpio_cfg_sense_input(S18, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_SENSE_LOW);
nrf_gpio_cfg_sense_input(S19, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_SENSE_LOW);
nrf_gpio_cfg_sense_input(S20, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_SENSE_LOW);
nrf_gpio_cfg_sense_input(S21, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_SENSE_LOW);
nrf_gpio_cfg_sense_input(S22, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_SENSE_LOW);
nrf_gpio_cfg_sense_input(S23, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_SENSE_LOW);
nrf_gpio_cfg_sense_input(S24, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_SENSE_LOW);
}
// Return the key states, masked with valid key pins
static uint32_t read_keys(void)
{
return ~NRF_GPIO->IN & INPUT_MASK;
}
// Assemble packet and send to receiver
static void send_data(void)
{
data_payload[0] = ((keys & 1<<S01) ? 1:0) << 7 | \
((keys & 1<<S02) ? 1:0) << 6 | \
((keys & 1<<S03) ? 1:0) << 5 | \
((keys & 1<<S04) ? 1:0) << 4 | \
((keys & 1<<S05) ? 1:0) << 3 | \
((keys & 1<<S06) ? 1:0) << 2 | \
((keys & 1<<S07) ? 1:0) << 1 | \
((keys & 1<<S08) ? 1:0) << 0;
data_payload[1] = ((keys & 1<<S09) ? 1:0) << 7 | \
((keys & 1<<S10) ? 1:0) << 6 | \
((keys & 1<<S11) ? 1:0) << 5 | \
((keys & 1<<S12) ? 1:0) << 4 | \
((keys & 1<<S13) ? 1:0) << 3 | \
((keys & 1<<S14) ? 1:0) << 2 | \
((keys & 1<<S15) ? 1:0) << 1 | \
((keys & 1<<S16) ? 1:0) << 0;
data_payload[2] = ((keys & 1<<S17) ? 1:0) << 7 | \
((keys & 1<<S18) ? 1:0) << 6 | \
((keys & 1<<S19) ? 1:0) << 5 | \
((keys & 1<<S20) ? 1:0) << 4 | \
((keys & 1<<S21) ? 1:0) << 3 | \
((keys & 1<<S22) ? 1:0) << 2 | \
((keys & 1<<S23) ? 1:0) << 1 | \
((keys & 1<<S24) ? 1:0) << 0;
nrf_gzll_add_packet_to_tx_fifo(PIPE_NUMBER, data_payload, TX_PAYLOAD_LENGTH);
}
// 8Hz held key maintenance, keeping the reciever keystates valid
static void handler_maintenance(nrf_drv_rtc_int_type_t int_type)
{
send_data();
}
// 1000Hz debounce sampling
static void handler_debounce(nrf_drv_rtc_int_type_t int_type)
{
// debouncing, waits until there have been no transitions in 5ms (assuming five 1ms ticks)
if (debouncing)
{
// if debouncing, check if current keystates equal to the snapshot
if (keys_snapshot == read_keys())
{
// DEBOUNCE ticks of stable sampling needed before sending data
debounce_ticks++;
if (debounce_ticks == DEBOUNCE)
{
keys = keys_snapshot;
send_data();
}
}
else
{
// if keys change, start period again
debouncing = false;
}
}
else
{
// if the keystate is different from the last data
// sent to the receiver, start debouncing
if (keys != read_keys())
{
keys_snapshot = read_keys();
debouncing = true;
debounce_ticks = 0;
}
}
// looking for 500 ticks of no keys pressed, to go back to deep sleep
if (read_keys() == 0)
{
activity_ticks++;
if (activity_ticks > ACTIVITY)
{
nrf_drv_rtc_disable(&rtc_maint);
nrf_drv_rtc_disable(&rtc_deb);
}
}
else
{
activity_ticks = 0;
}
}
// Low frequency clock configuration
static void lfclk_config(void)
{
nrf_drv_clock_init();
nrf_drv_clock_lfclk_request(NULL);
}
// RTC peripheral configuration
static void rtc_config(void)
{
//Initialize RTC instance
nrf_drv_rtc_init(&rtc_maint, NULL, handler_maintenance);
nrf_drv_rtc_init(&rtc_deb, NULL, handler_debounce);
//Enable tick event & interrupt
nrf_drv_rtc_tick_enable(&rtc_maint,true);
nrf_drv_rtc_tick_enable(&rtc_deb,true);
//Power on RTC instance
//nrf_drv_rtc_enable(&rtc_maint);
//nrf_drv_rtc_enable(&rtc_deb);
}
int main()
{
// Initialize Gazell
nrf_gzll_init(NRF_GZLL_MODE_DEVICE);
// Attempt sending every packet up to 100 times
nrf_gzll_set_max_tx_attempts(100);
// Addressing
nrf_gzll_set_base_address_0(0x01020304);
nrf_gzll_set_base_address_1(0x05060708);
// Enable Gazell to start sending over the air
nrf_gzll_enable();
// Configure 32kHz xtal oscillator
lfclk_config();
// Configure RTC peripherals with ticks
rtc_config();
// Configure all keys as inputs with pullups
gpio_config();
// Set the GPIOTE PORT event as interrupt source, and enable interrupts for GPIOTE
NRF_GPIOTE->INTENSET = GPIOTE_INTENSET_PORT_Msk;
NVIC_EnableIRQ(GPIOTE_IRQn);
// Main loop, constantly sleep, waiting for RTC and gpio IRQs
while(1)
{
__SEV();
__WFE();
__WFE();
}
}
// This handler will be run after wakeup from system ON (GPIO wakeup)
void GPIOTE_IRQHandler(void)
{
if(NRF_GPIOTE->EVENTS_PORT)
{
//clear wakeup event
NRF_GPIOTE->EVENTS_PORT = 0;
//enable rtc interupt triggers
nrf_drv_rtc_enable(&rtc_maint);
nrf_drv_rtc_enable(&rtc_deb);
debouncing = false;
debounce_ticks = 0;
activity_ticks = 0;
}
}
/*****************************************************************************/
/** Gazell callback function definitions */
/*****************************************************************************/
void nrf_gzll_device_tx_success(uint32_t pipe, nrf_gzll_device_tx_info_t tx_info)
{
uint32_t ack_payload_length = NRF_GZLL_CONST_MAX_PAYLOAD_LENGTH;
if (tx_info.payload_received_in_ack)
{
// Pop packet and write first byte of the payload to the GPIO port.
nrf_gzll_fetch_packet_from_rx_fifo(pipe, ack_payload, &ack_payload_length);
}
}
// no action is taken when a packet fails to send, this might need to change
void nrf_gzll_device_tx_failed(uint32_t pipe, nrf_gzll_device_tx_info_t tx_info)
{
}
// Callbacks not needed
void nrf_gzll_host_rx_data_ready(uint32_t pipe, nrf_gzll_host_rx_info_t rx_info)
{}
void nrf_gzll_disabled()
{}
#define HAND_SENSE 11
#define RIGHT_HAND true
#define LEFT_HAND false
#define ALPHA_SENSE 7
#define ALPABETICAL false
// left hand pins
#define L_LED 6
#define L_S01 21
#define L_S02 23
#define L_S03 24
#define L_S04 29
#define L_S05 0
#define L_S06 2
#define L_S07 22
#define L_S08 25
#define L_S09 28
#define L_S10 30
#define L_S11 1
#define L_S12 3
#define L_S13 19
#define L_S14 17
#define L_S15 15
#define L_S16 13
#define L_S17 9
#define L_S18 4
#define L_S19 20
#define L_S20 18
#define L_S21 16
#define L_S22 14
#define L_S23 10
#define L_S24 8
#define L_MASK (1<<L_S01 | \
1<<L_S02 | \
1<<L_S03 | \
1<<L_S04 | \
1<<L_S05 | \
1<<L_S06 | \
1<<L_S07 | \
1<<L_S08 | \
1<<L_S09 | \
1<<L_S10 | \
1<<L_S11 | \
1<<L_S12 | \
1<<L_S13 | \
1<<L_S14 | \
1<<L_S15 | \
1<<L_S16 | \
1<<L_S17 | \
1<<L_S18 | \
1<<L_S19 | \
1<<L_S20 | \
1<<L_S21 | \
1<<L_S22 | \
1<<L_S23 | \
1<<L_S24)
// right hand pins
#define R_LED 6
#define R_S01 9
#define R_S02 10
#define R_S03 14
#define R_S04 16
#define R_S05 18
#define R_S06 20
#define R_S07 4
#define R_S08 9
#define R_S09 13
#define R_S10 15
#define R_S11 17
#define R_S12 19
#define R_S13 3
#define R_S14 1
#define R_S15 30
#define R_S16 28
#define R_S17 25
#define R_S18 22
#define R_S19 2
#define R_S20 0
#define R_S21 29
#define R_S22 24
#define R_S23 23
#define R_S24 21
#define R_MASK (1<<R_S01 | \
1<<R_S02 | \
1<<R_S03 | \
1<<R_S04 | \
1<<R_S05 | \
1<<R_S06 | \
1<<R_S07 | \
1<<R_S08 | \
1<<R_S09 | \
1<<R_S10 | \
1<<R_S11 | \
1<<R_S12 | \
1<<R_S13 | \
1<<R_S14 | \
1<<R_S15 | \
1<<R_S16 | \
1<<R_S17 | \
1<<R_S18 | \
1<<R_S19 | \
1<<R_S20 | \
1<<R_S21 | \
1<<R_S22 | \
1<<R_S23 | \
1<<R_S24)
#ifdef COMPILE_LEFT
#define PIPE_NUMBER 0
#define LED_PIN L_LED
#define S01 L_S01
#define S02 L_S02
#define S03 L_S03
#define S04 L_S04
#define S05 L_S05
#define S06 L_S06
#define S07 L_S07
#define S08 L_S08
#define S09 L_S09
#define S10 L_S10
#define S11 L_S11
#define S12 L_S12
#define S13 L_S13
#define S14 L_S14
#define S15 L_S15
#define S16 L_S16
#define S17 L_S17
#define S18 L_S18
#define S19 L_S19
#define S20 L_S20
#define S21 L_S21
#define S22 L_S22
#define S23 L_S23
#define S24 L_S24
#define INPUT_MASK L_MASK
#endif
#ifdef COMPILE_RIGHT
#define PIPE_NUMBER 1
#define LED_PIN R_LED
#define S01 R_S01
#define S02 R_S02
#define S03 R_S03
#define S04 R_S04
#define S05 R_S05
#define S06 R_S06
#define S07 R_S07
#define S08 R_S08
#define S09 R_S09
#define S10 R_S10
#define S11 R_S11
#define S12 R_S12
#define S13 R_S13
#define S14 R_S14
#define S15 R_S15
#define S16 R_S16
#define S17 R_S17
#define S18 R_S18
#define S19 R_S19
#define S20 R_S20
#define S21 R_S21
#define S22 R_S22
#define S23 R_S23
#define S24 R_S24
#define INPUT_MASK R_MASK
#endif
// Low frequency clock source to be used by the SoftDevice
#define NRF_CLOCK_LFCLKSRC {.source = NRF_CLOCK_LF_SRC_XTAL, \
.rc_ctiv = 0, \
.rc_temp_ctiv = 0, \
.xtal_accuracy = NRF_CLOCK_LF_XTAL_ACCURACY_20_PPM}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment