void microbit_display_obj_t::advanceRow() { // First, clear the old row. // Clear the old bit pattern for this row. // Clear port 0 4-7 and retain lower 4 bits. nrf_gpio_port_write(NRF_GPIO_PORT_SELECT_PORT0, 0xF0 | (nrf_gpio_port_read(NRF_GPIO_PORT_SELECT_PORT0) & 0x0F)); // Clear port 1 8-12 for the current row. nrf_gpio_port_write(NRF_GPIO_PORT_SELECT_PORT1, strobe_mask | 0x1F); // Move on to the next row. strobe_mask <<= 1; strobe_row++; // Reset the row counts and bit mask when we have hit the max. if (strobe_row == MICROBIT_DISPLAY_ROW_COUNT) { strobe_row = 0; strobe_mask = 0x20; } // Prepare row for rendering. for (int i = 0; i < MICROBIT_DISPLAY_COLUMN_COUNT; i++) { int x = display_map[i][strobe_row].x; int y = display_map[i][strobe_row].y; row_brightness[i] = microbit_display_obj.image_buffer[x][y]; } // Turn on any pixels that are at max. setPinsForRow(MAX_BRIGHTNESS); }
/* If the transmission failed, send a new packet. * This callback does not occur by default since NRF_GZLL_DEFAULT_MAX_TX_ATTEMPTS * is 0 (inifinite retransmits) */ void nrf_gzll_device_tx_failed(uint32_t pipe, nrf_gzll_device_tx_info_t tx_info) { tx_success = false; // Load data into TX queue data_payload[0] = nrf_gpio_port_read(BUTTONS); push_ok = nrf_gzll_add_packet_to_tx_fifo(pipe, data_payload, TX_PAYLOAD_LENGTH); }
/** * @brief Function for application main entry. */ int main(void) { // Start 16 MHz crystal oscillator. NRF_CLOCK->EVENTS_HFCLKSTARTED = 0; NRF_CLOCK->TASKS_HFCLKSTART = 1; // Wait for the external oscillator to start up. while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0) { // Do nothing. } // Set Port 0 as input. nrf_gpio_range_cfg_input(BUTTON_START, BUTTON_STOP, BUTTON_PULL); // Set Port 1 as output. nrf_gpio_range_cfg_output(LED_START, LED_STOP); // Set radio configuration parameters. radio_configure(); // Set payload pointer. NRF_RADIO->PACKETPTR = (uint32_t)packet; while (true) { // Read Data to send, button signals are default high, and low when pressed. packet[0] = ~(nrf_gpio_port_read(NRF_GPIO_PORT_SELECT_PORT0)); // Write GPIO to payload byte 0. NRF_RADIO->EVENTS_READY = 0U; NRF_RADIO->TASKS_TXEN = 1; // Enable radio and wait for ready. while (NRF_RADIO->EVENTS_READY == 0U) { // Do nothing. } // Start transmission. NRF_RADIO->TASKS_START = 1U; NRF_RADIO->EVENTS_END = 0U; while (NRF_RADIO->EVENTS_END == 0U) // Wait for end of the transmission packet. { // Do nothing. } // Write sent data to port 1. nrf_gpio_port_write(NRF_GPIO_PORT_SELECT_PORT1, packet[0]); NRF_RADIO->EVENTS_DISABLED = 0U; NRF_RADIO->TASKS_DISABLE = 1U; // Disable the radio. while (NRF_RADIO->EVENTS_DISABLED == 0U) { // Do nothing. } } }
/** @brief Function for getting the next sample. * @return sample_value computed sample. */ static __INLINE uint32_t next_sample_get(void) { static uint32_t sample_value = 8; // Read button input. sample_value = (~(nrf_gpio_port_read(NRF_GPIO_PORT_SELECT_PORT0)) & 0x000000FFUL); // This is to avoid having two CC events happen at the same time, // CC1 will always create an event on 0 so CC0 and CC2 should not. if (sample_value == 0) { sample_value = 8; } return (uint32_t)sample_value; }
inline void microbit_display_obj_t::setPinsForRow(uint8_t brightness) { int column_strobe = 0; // Calculate the bitpattern to write. for (int i = 0; i < MICROBIT_DISPLAY_COLUMN_COUNT; i++) { if (row_brightness[i] >= brightness) { column_strobe |= (1 << i); } } // Wwrite the new bit pattern. // Set port 0 4-7 and retain lower 4 bits. nrf_gpio_port_write(NRF_GPIO_PORT_SELECT_PORT0, (~column_strobe<<4 & 0xF0) | (nrf_gpio_port_read(NRF_GPIO_PORT_SELECT_PORT0) & 0x0F)); // Set port 1 8-12 for the current row. nrf_gpio_port_write(NRF_GPIO_PORT_SELECT_PORT1, strobe_mask | (~column_strobe>>4 & 0x1F)); }
// If a data packet was received, we write the first byte to LEDS. void nrf_gzll_host_rx_data_ready(uint32_t pipe, nrf_gzll_host_rx_info_t rx_info) { uint32_t data_payload_length = NRF_GZLL_CONST_MAX_PAYLOAD_LENGTH; packet_received = true; // Pop packet and write first byte of the payload to the GPIO port. pop_ok = nrf_gzll_fetch_packet_from_rx_fifo(pipe, data_payload, &data_payload_length); if (data_payload_length > 0) { nrf_gpio_port_write(LEDS,~data_payload[0]); } // Read buttons and load ACK payload into TX queue ack_payload[0] = nrf_gpio_port_read(BUTTONS); // Button logic is inverted. push_ok = nrf_gzll_add_packet_to_tx_fifo(pipe, ack_payload, TX_PAYLOAD_LENGTH); }
// If an ACK was received, we send another packet. 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; tx_success = true; if (tx_info.payload_received_in_ack) { // Pop packet and write first byte of the payload to the GPIO port. pop_ok = nrf_gzll_fetch_packet_from_rx_fifo(pipe, ack_payload, &ack_payload_length); if (ack_payload_length > 0) { nrf_gpio_port_write(LEDS, ~ack_payload[0]); // Button press is active low. } } // Read buttons and load data payload into TX queue data_payload[0] = nrf_gpio_port_read(BUTTONS); push_ok = nrf_gzll_add_packet_to_tx_fifo(pipe, data_payload, TX_PAYLOAD_LENGTH); }
int main() { uint8_t debug_led_output; // Setup port directions nrf_gpio_port_dir_set(BUTTONS, NRF_GPIO_PORT_DIR_INPUT); nrf_gpio_port_dir_set(LEDS, NRF_GPIO_PORT_DIR_OUTPUT); // Initialize Gazell init_ok = nrf_gzll_init(NRF_GZLL_MODE_DEVICE); // Attempt sending every packet up to 100 times init_ok &= nrf_gzll_set_max_tx_attempts(100); // Load data into TX queue data_payload[0] = nrf_gpio_port_read(BUTTONS); push_ok = nrf_gzll_add_packet_to_tx_fifo(PIPE_NUMBER, data_payload, TX_PAYLOAD_LENGTH); // Enable Gazell to start sending over the air enable_ok = nrf_gzll_enable(); while(1) { // Error handling debug_led_output = ((uint8_t)tx_success << 4) | ((uint8_t)pop_ok << 3) | ((uint8_t)push_ok << 2) | ((uint8_t)enable_ok << 1) | (uint8_t)init_ok; // If an error has occured if(debug_led_output != 0x1F) { nrf_gpio_port_write(LEDS,0xFF); nrf_delay_us(1000000); // 1 second delay nrf_gpio_port_write(LEDS, debug_led_output); nrf_delay_us(1000000); // 1 second delay nrf_gpio_port_write(LEDS,0xF0 + (uint32_t)nrf_gzll_get_error_code()); nrf_delay_us(1000000); // 1 second delay } // Optionally send the CPU to sleep while waiting for a callback. // __WFI(); } }
/** * @brief Function for application main entry. */ int main(void) { uint32_t *addr; uint8_t patwr; uint8_t patrd; uint8_t patold; uint32_t i; uint32_t pg_size; uint32_t pg_num; init(); patold = 0; pg_size = NRF_FICR->CODEPAGESIZE; pg_num = NRF_FICR->CODESIZE - 1; // Use last page in flash while (true) { // Start address: addr = (uint32_t *)(pg_size * pg_num); // Erase page: flash_page_erase(addr); i = 0; do { // Read pattern from port 0 (pins0-7), and write it to flash: patwr = nrf_gpio_port_read(NRF_GPIO_PORT_SELECT_PORT0); if (patold != patwr) { patold = patwr; flash_word_write(++addr, (uint32_t)patwr); i += 4; } // Read pattern from flash and write it to port 1 (pins8-15): patrd = (uint8_t)*addr; nrf_gpio_port_write(NRF_GPIO_PORT_SELECT_PORT1, patrd); } while (i < pg_size); } }