/**
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/structs/watchdog.h"
// Это приложение показывает влияние записи байтов и полуслов на регистры ввода/вывода. Все
// регистры ввода-вывода на RP2040 будут производить выборку всей 32-битной шины данных записи при любой
// записи; размер передачи и 2 младших бита адреса "игнорируются".
//
// Это может привести к неинтуитивным результатам, особенно с учетом того, как шинные мастера RP2040
// реплицируют узкие данные записи по всей 32-битной шине данных записи.
// Однако такое поведение может быть весьма полезным, если вы о нем знаете!
int main() {
stdio_init_all();
// Мы будем использовать WATCHDOG_SCRATCH0 как удобный 32-битный регистр чтения / записи,
// которому мы можем присвоить произвольные значения.
io_rw_32 *scratch32 = &watchdog_hw->scratch[0];
// Псевдоним временного регистра как два полуслова со смещениями +0x0 и +0x2
volatile uint16_t *scratch16 = (volatile uint16_t *) scratch32;
// Псевдоним временного регистра как четыре байта со смещениями +0x0, +0x1, +0x2, +0x3:
volatile uint8_t *scratch8 = (volatile uint8_t *) scratch32;
// Покажем, что мы можем читать/записывать рабочий регистр как обычно:
printf("Запись тридцатидвухбитного значения\n");
*scratch32 = 0xdeadbeef;
printf("Должно быть 0xdeadbeef: 0x%08x\n", *scratch32);
// Мы можем выполнять узкие чтения просто отлично - регистры ввода-вывода обрабатывают это как 32-битное
// чтение, а процессор/контроллер прямого доступа к памяти выберет правильные байтовые полосы на основании
// размера передачи и адресов LSB.
printf("\nЧтение по одному байту за раз\n");
// Little-endian!
printf("Должно быть ef be ad de: %02x %02x %02x %02x\n",
scratch8[0], scratch8[1], scratch8[2], scratch8[3]);
// Cortex-M0+ и контроллер прямого доступа к памяти RP2040 реплицируют байтовые записи по шине,
// а регистры ввода-вывода всегда производят выборку всей шины записи.
printf("\nЗапись восьмибитного значения 0xa5 so smecheniem 0\n");
scratch8[0] = 0xa5;
// Прочитаем весь регистр за раз
printf("Должно быть 0xa5a5a5a5: 0x%08x\n", *scratch32);
// Регистр ввода-вывода игнорирует младшие биты адреса [1: 0], а также размер передачи,
// поэтому не имеет значения, какое смещение байта мы используем.
printf("\nЗапись восьмибитного значения со смещением 1\n");
scratch8[1] = 0x3c;
printf("Должно быть 0x3c3c3c3c: 0x%08x\n", *scratch32);
// Запись половинного слова также реплицируется через шину записи данных.
printf("\nЗапись шестнадцатибитного значения со смещением 0\n");
scratch16[0] = 0xf00d;
printf("Должно быть 0xf00df00d: 0x%08x\n", *scratch32);
}