<commit_before>#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <stdio.h>
#include <string.h>

#include "xmega_lib/clksys_driver.h"
#include "xmega_lib/serial.h"
#include "xbootapi.h"

#include "nordic_wireless.h"

/*
 * Pins:
 *
 * Port A:
 *  1: Debug LED
 *  5: nordic CE
 *  6: nordic _CS_
 *
 * Port B:
 *  2: nordic IRQ
 *
 * Port D: (uses SPI)
 *  1: nordic SCK
 *  2: nordic MISO
 *  3: nordic MOSI
 *
 * Port E:
 *  2: Serial Rx
 *  3: Serial Tx
 */
void
setup_pins(void) {
  /* For direction: 0 = input, 1 = output. */

  /* Port A: 1, 5, 6 output, rest don't care (output). */
  PORTA.DIR = 0xff;
  // Leave the IR LED, nordic CE, nordic _CS_ all low.
  PORTA.OUT = 0x00;

  /* Port B: 2 input, rest don't care (output). */
  PORTB.DIR = (PIN0_bm | PIN1_bm | PIN3_bm | PIN4_bm | PIN5_bm | PIN6_bm |
               PIN7_bm);
  PORTB.OUT = 0x00;
  /* Turn on a low level interrupt on the nordic IRQ pin. */
  PORTB.INTCTRL = PORT_INT0LVL_LO_gc;
  PORTB.INT0MASK = PIN2_bm;
  /* Trigger on a falling edge. */
  PORTB.PIN2CTRL = PORT_ISC_FALLING_gc;

  /* Port C: don't care: all outputs, start at 0. */
  PORTC.DIR = 0xff;
  PORTC.OUT = 0x00;

  /* Port D: 1, 3 outputs; 2 input, reset don't care (output). */
  PORTD.DIR = (PIN0_bm | PIN1_bm | PIN3_bm | PIN4_bm | PIN5_bm | PIN6_bm |
               PIN7_bm);
  // Leave all the nordic pins low.
  PORTD.OUT = 0x00;

  /* Port E: 2 input, 3 output, reset don't care (output). */
  PORTE.DIR = (PIN0_bm | PIN1_bm | PIN3_bm);
  // Start all lines out low.
  PORTE.OUT = 0x00;
}

volatile static uint8_t nordic_interrupt = 0;

/* Interrupt routine for the nordic IRQ. */
ISR(PORTB_INT0_vect) {
  nordic_interrupt = 1;
}

void
blink(int count) {
  int i;

  for (i = 0; i < count; i++) {
    PORTA.OUTSET = PIN1_bm;
    _delay_ms(125);
    PORTA.OUTCLR = PIN1_bm;
    _delay_ms(250);
    PORTA.OUTSET = PIN1_bm;
    _delay_ms(125);
  }

  _delay_ms(400);
}

void
setup_clock(void) {
  // Enable the 32 MHz internal oscillator.
  CLKSYS_Enable(OSC_RC32MEN_bm);

  // Wait for the 32 MHz clock to be ready.
  do {
  } while (CLKSYS_IsReady(OSC_RC32MRDY_bm) == 0);

  // Switch to the 32 MHz clock for the main system clock.
  // XXX Check the return value!
  CLKSYS_Main_ClockSource_Select(CLK_SCLKSEL_RC32M_gc);

  // Turn off all the other clocks.
  // XXX What about the external clock?
  CLKSYS_Disable(OSC_PLLEN_bm | OSC_RC32KEN_bm | OSC_RC2MEN_bm);

  // Enable automatic calibration of the 32MHz clock.
  OSC.DFLLCTRL = OSC_RC32MCREF_XOSC32K_gc;
  DFLLRC32M.CTRL = DFLL_ENABLE_bm;
}

static uint8_t broadcast_address[5] = {0xe7, 0xe7, 0xe7, 0xe7, 0xe7};
static uint8_t boot_address[5] = {0x3e, 0x3e, 0x3e, 0x3e, 0x3e};

void
nordic_setup(void) {
  nordic_init();
  nordic_set_channel(1);
  nordic_setup_pipe(0, broadcast_address, 5, 1, VARIABLE_PAYLOAD_LEN);
  /* Set up a second pipe to receive firmware updates. */
  nordic_setup_pipe(1, boot_address, 5, 1, VARIABLE_PAYLOAD_LEN);

#ifdef SERIAL_DEBUG
  // XXX Delay so serial write works correctly...
  _delay_ms(1000);
  serial_write_string("Bob\r\n");
  _delay_ms(1000);
  serial_write_string("Fred\r\n");
  nordic_print_radio_config();
#endif
}

void
setup(void) {
  setup_clock();

  setup_pins();

  usart_115200();

  /* Enable a low level interrupt on port A, pin 2. */
  PORTA.INTCTRL = PORT_INT0LVL_LO_gc;
  PORTA.INT0MASK = PIN2_bm;

  // Enable low and medium level interrupts.
  PMIC.CTRL = PMIC_LOLVLEN_bm | PMIC_MEDLVLEN_bm;

  /* Enable interrupts. */
  sei();

  /* Set up the nordic radio. */
  nordic_setup();
  nordic_start_listening();
}

/**
 * Send device info needed to correctly program the chip.
 */
void
send_device_info(void) {
  uint8_t data[8];

  /* Message identifier. */
  data[0] = 's';
  /* Three bytes of the device id. */
  data[1] = SIGNATURE_2;
  data[2] = SIGNATURE_1;
  data[3] = SIGNATURE_0;
  /* Two bytes of the device page size. */
  data[4] = (SPM_PAGESIZE >> 8) & 0xff;
  data[5] = SPM_PAGESIZE & 0xff;
  /* Two bytes of the xboot app size. */
  data[4] = (XB_APP_SIZE >> 8) & 0xff;
  data[5] = XB_APP_TEMP_SIZE & 0xff;

  /* For now, assume the sender is listening on the boot adress. */
  nordic_set_tx_addr(boot_address, sizeof(boot_address));
  nordic_set_rx_addr(boot_address, sizeof(boot_address), 0);
  nordic_write_data(data, sizeof(data));
}

#define DEBUG_CRC 0

void
process_data(uint8_t data[], uint8_t len) {
  static uint8_t page_buffer[SPM_PAGESIZE];
  static uint32_t addr = 0;
  static uint8_t page_committed = 0;
  static uint16_t buffer_offset = 0;
  uint16_t target_crc, crc;
#if DEBUG_CRC
  uint8_t byte;
  uint16_t i;
#endif
  char txt[32];

  if (len < 1) {
    return;
  }
<commit_msg>Fixing the byte offsets of the device info.<commit_after>#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <stdio.h>
#include <string.h>

#include "xmega_lib/clksys_driver.h"
#include "xmega_lib/serial.h"
#include "xbootapi.h"

#include "nordic_wireless.h"

/*
 * Pins:
 *
 * Port A:
 *  1: Debug LED
 *  5: nordic CE
 *  6: nordic _CS_
 *
 * Port B:
 *  2: nordic IRQ
 *
 * Port D: (uses SPI)
 *  1: nordic SCK
 *  2: nordic MISO
 *  3: nordic MOSI
 *
 * Port E:
 *  2: Serial Rx
 *  3: Serial Tx
 */
void
setup_pins(void) {
  /* For direction: 0 = input, 1 = output. */

  /* Port A: 1, 5, 6 output, rest don't care (output). */
  PORTA.DIR = 0xff;
  // Leave the IR LED, nordic CE, nordic _CS_ all low.
  PORTA.OUT = 0x00;

  /* Port B: 2 input, rest don't care (output). */
  PORTB.DIR = (PIN0_bm | PIN1_bm | PIN3_bm | PIN4_bm | PIN5_bm | PIN6_bm |
               PIN7_bm);
  PORTB.OUT = 0x00;
  /* Turn on a low level interrupt on the nordic IRQ pin. */
  PORTB.INTCTRL = PORT_INT0LVL_LO_gc;
  PORTB.INT0MASK = PIN2_bm;
  /* Trigger on a falling edge. */
  PORTB.PIN2CTRL = PORT_ISC_FALLING_gc;

  /* Port C: don't care: all outputs, start at 0. */
  PORTC.DIR = 0xff;
  PORTC.OUT = 0x00;

  /* Port D: 1, 3 outputs; 2 input, reset don't care (output). */
  PORTD.DIR = (PIN0_bm | PIN1_bm | PIN3_bm | PIN4_bm | PIN5_bm | PIN6_bm |
               PIN7_bm);
  // Leave all the nordic pins low.
  PORTD.OUT = 0x00;

  /* Port E: 2 input, 3 output, reset don't care (output). */
  PORTE.DIR = (PIN0_bm | PIN1_bm | PIN3_bm);
  // Start all lines out low.
  PORTE.OUT = 0x00;
}

volatile static uint8_t nordic_interrupt = 0;

/* Interrupt routine for the nordic IRQ. */
ISR(PORTB_INT0_vect) {
  nordic_interrupt = 1;
}

void
blink(int count) {
  int i;

  for (i = 0; i < count; i++) {
    PORTA.OUTSET = PIN1_bm;
    _delay_ms(125);
    PORTA.OUTCLR = PIN1_bm;
    _delay_ms(250);
    PORTA.OUTSET = PIN1_bm;
    _delay_ms(125);
  }

  _delay_ms(400);
}

void
setup_clock(void) {
  // Enable the 32 MHz internal oscillator.
  CLKSYS_Enable(OSC_RC32MEN_bm);

  // Wait for the 32 MHz clock to be ready.
  do {
  } while (CLKSYS_IsReady(OSC_RC32MRDY_bm) == 0);

  // Switch to the 32 MHz clock for the main system clock.
  // XXX Check the return value!
  CLKSYS_Main_ClockSource_Select(CLK_SCLKSEL_RC32M_gc);

  // Turn off all the other clocks.
  // XXX What about the external clock?
  CLKSYS_Disable(OSC_PLLEN_bm | OSC_RC32KEN_bm | OSC_RC2MEN_bm);

  // Enable automatic calibration of the 32MHz clock.
  OSC.DFLLCTRL = OSC_RC32MCREF_XOSC32K_gc;
  DFLLRC32M.CTRL = DFLL_ENABLE_bm;
}

static uint8_t broadcast_address[5] = {0xe7, 0xe7, 0xe7, 0xe7, 0xe7};
static uint8_t boot_address[5] = {0x3e, 0x3e, 0x3e, 0x3e, 0x3e};

void
nordic_setup(void) {
  nordic_init();
  nordic_set_channel(1);
  nordic_setup_pipe(0, broadcast_address, 5, 1, VARIABLE_PAYLOAD_LEN);
  /* Set up a second pipe to receive firmware updates. */
  nordic_setup_pipe(1, boot_address, 5, 1, VARIABLE_PAYLOAD_LEN);

#ifdef SERIAL_DEBUG
  // XXX Delay so serial write works correctly...
  _delay_ms(1000);
  serial_write_string("Bob\r\n");
  _delay_ms(1000);
  serial_write_string("Fred\r\n");
  nordic_print_radio_config();
#endif
}

void
setup(void) {
  setup_clock();

  setup_pins();

  usart_115200();

  /* Enable a low level interrupt on port A, pin 2. */
  PORTA.INTCTRL = PORT_INT0LVL_LO_gc;
  PORTA.INT0MASK = PIN2_bm;

  // Enable low and medium level interrupts.
  PMIC.CTRL = PMIC_LOLVLEN_bm | PMIC_MEDLVLEN_bm;

  /* Enable interrupts. */
  sei();

  /* Set up the nordic radio. */
  nordic_setup();
  nordic_start_listening();
}

/**
 * Send device info needed to correctly program the chip.
 */
void
send_device_info(void) {
  uint8_t data[8];

  /* Message identifier. */
  data[0] = 's';
  /* Three bytes of the device id. */
  data[1] = SIGNATURE_2;
  data[2] = SIGNATURE_1;
  data[3] = SIGNATURE_0;
  /* Two bytes of the device page size. */
  data[4] = (SPM_PAGESIZE >> 8) & 0xff;
  data[5] = SPM_PAGESIZE & 0xff;
  /* Two bytes of the xboot app size. */
  data[6] = (XB_APP_SIZE >> 8) & 0xff;
  data[7] = XB_APP_TEMP_SIZE & 0xff;

  /* For now, assume the sender is listening on the boot adress. */
  nordic_set_tx_addr(boot_address, sizeof(boot_address));
  nordic_set_rx_addr(boot_address, sizeof(boot_address), 0);
  nordic_write_data(data, sizeof(data));
}

#define DEBUG_CRC 0

void
process_data(uint8_t data[], uint8_t len) {
  static uint8_t page_buffer[SPM_PAGESIZE];
  static uint32_t addr = 0;
  static uint8_t page_committed = 0;
  static uint16_t buffer_offset = 0;
  uint16_t target_crc, crc;
#if DEBUG_CRC
  uint8_t byte;
  uint16_t i;
#endif
  char txt[32];

  if (len < 1) {
    return;
  }

{'fraction_non_alphanumeric': 0.12635264162953533, 'fraction_numerical': 0.04073838319541693, 'mean_word_length': 3.283053157655611, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1832979', 'n_tokens_mistral': 4184, 'n_tokens_neox': 3896, 'n_words': 997}