Код:
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/gpio.h"
#include "hardware/uart.h"
#include "pico/rand.h"
#define UART_ID uart0
#define BAUD_RATE 115200
// We are using pins 0 and 1, but see the GPIO function select table in the
// datasheet for information on which other pins can be used.
#define UART_TX_PIN 0
#define UART_RX_PIN 1
#define A01 2
#define A02 3
#define A03 4
#define A04 5
#define A05 6
#define A06 7
#define A07 8
#define A08 9
// reserved for RU7
#define A09 10
#define ADDRESS_SHIFT 2
#define D00 11
#define D01 12
#define D02 13
#define D03 14
#define D04 15
#define D05 16
#define D06 17
#define D07 18
#define DATA_SHIFT 11
#define RAS1 20
#define RAS2 19
#define WE_L 21
#define WE_M 22
#define CAS 26
#define DATA_DIR 27
#define SHIFT_EN 28
uint32_t gpio_address_mask;
uint32_t gpio_data_mask, gpio_controls_mask;
void write_address(uint8_t wr_bank, uint8_t ras_bank, uint16_t high_address, uint16_t low_address, uint8_t write_data) {
gpio_set_dir_out_masked (gpio_data_mask);
gpio_put (DATA_DIR, 0);
__asm volatile ("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\n");
gpio_put_masked (gpio_data_mask, write_data << DATA_SHIFT);
gpio_put (wr_bank, 0);
__asm volatile ("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\n");
gpio_put_masked (gpio_address_mask, low_address << ADDRESS_SHIFT);
__asm volatile ("nop\nnop\n");
gpio_put (ras_bank, 0);
__asm volatile ("nop\nnop\n");
gpio_put_masked (gpio_address_mask, high_address << ADDRESS_SHIFT);
//__asm volatile ("nop\nnop\n");
gpio_put (CAS, 0);
__asm volatile ("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\n");
__asm volatile ("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\n");
gpio_put (CAS, 1);
gpio_put (ras_bank, 1);
gpio_put (wr_bank, 1);
}
uint8_t read_address(uint8_t wr_bank, uint8_t ras_bank, uint16_t high_address, uint16_t low_address) {
gpio_set_dir_in_masked (gpio_data_mask);
gpio_put (DATA_DIR, 1);
__asm volatile ("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\n");
__asm volatile ("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\n");
gpio_put_masked (gpio_address_mask, low_address << ADDRESS_SHIFT);
__asm volatile ("nop\nnop\n");
gpio_put (ras_bank, 0);
__asm volatile ("nop\nnop\n");
gpio_put_masked (gpio_address_mask, high_address << ADDRESS_SHIFT);
//__asm volatile ("nop\nnop\n");
gpio_put (CAS, 0);
__asm volatile ("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\n");
__asm volatile ("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\n");
volatile uint32_t gpio_value = gpio_get_all();
volatile uint8_t gpio_value1 = gpio_value >> DATA_SHIFT;
//читаем
gpio_put (CAS, 1);
gpio_put (ras_bank, 1);
return gpio_value1;
}
void ram_refresh(uint8_t wr_bank, uint8_t ras_bank, uint16_t low_address) {
gpio_set_dir_in_masked (gpio_data_mask);
gpio_put (DATA_DIR, 1);
__asm volatile ("nop\nnop\n");
gpio_put_masked (gpio_address_mask, low_address << ADDRESS_SHIFT);
__asm volatile ("nop\nnop\n");
gpio_put (ras_bank, 0);
__asm volatile ("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\n");
__asm volatile ("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\n");
gpio_put (ras_bank, 1);
__asm volatile ("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\n");
}
bool check_bytes(uint8_t wr_bank, uint8_t ras_bank, uint16_t high_address, uint16_t low_address, uint8_t data_check, bool stop_on_error) {
uint8_t data = read_address (wr_bank, ras_bank, high_address, low_address);
if (data != data_check) {
for (uint8_t k = 0; k <= 0x7F; k++) {
ram_refresh (wr_bank, ras_bank, k);
}
printf("0x%02x 0x%02x: 0x%02x (0x%02x)\n", high_address, low_address, data, data_check);
if (stop_on_error == true) uart_getc(UART_ID);
return (1);
}
return (0);
}
void check_bank(uint8_t WE_line, uint8_t RAS_line) {
uint16_t i, j, k;
uint32_t count = 0;
printf("PRESS ANY KEY TO START\n");
uart_getc(UART_ID);
if (WE_line == WE_L)
gpio_put (SHIFT_EN, 0);
else
gpio_put (SHIFT_EN, 1);
for (k = 0; k <= 0x7F; k++) {
ram_refresh (WE_line, RAS_line, k);
}
for (i = 0; i <= 0xFF; i++) {
for (j = 0; j <= 0xFF; j++) {
write_address (WE_line, RAS_line, i, j, 0xAA);
}
}
for (i = 0; i <= 0xFF; i++) {
for (j = 0; j <= 0xFF; j++) {
count = count + check_bytes (WE_line, RAS_line, i, j, 0xAA, false);
}
}
for (i = 0; i <= 0xFF; i++) {
for (j = 0; j <= 0xFF; j++) {
write_address (WE_line, RAS_line, i, j, 0x55);
}
}
for (i = 0; i <= 0xFF; i++) {
for (j = 0; j <= 0xFF; j++) {
count = count + check_bytes (WE_line, RAS_line, i, j, 0x55, false);
}
}
printf ("FOUND %d ERRORS\n", count);
}
void check_bank_random(uint8_t WE_line, uint8_t RAS_line) {
uint16_t i, j, k;
uint32_t count = 0;
uint32_t Rn0 = get_rand_32();
uint32_t Rn = Rn0;
if (WE_line == WE_L)
gpio_put (SHIFT_EN, 0);
else
gpio_put (SHIFT_EN, 1);
for (k = 0; k <= 0x7F; k++) {
ram_refresh (WE_line, RAS_line, k);
}
for (i = 0; i <= 0xFF; i++) {
for (j = 0; j <= 0xFF; j++) {
write_address (WE_line, RAS_line, i, j, (uint8_t)Rn);
Rn = Rn * 1664525 + 1013904223;
}
}
Rn = Rn0;
for (i = 0; i <= 0xFF; i++) {
for (j = 0; j <= 0xFF; j++) {
count = count + check_bytes (WE_line, RAS_line, i, j, (uint8_t)Rn, true);
Rn = Rn * 1664525 + 1013904223;
}
}
printf ("%d ERR\n", count);
}
int main()
{
stdio_init_all();
// Set up our UART with the required speed.
uart_init(UART_ID, BAUD_RATE);
// Set the TX and RX pins by using the function select on the GPIO
// Set datasheet for more information on function select
gpio_set_function(UART_TX_PIN, UART_FUNCSEL_NUM(UART_ID, UART_TX_PIN));
gpio_set_function(UART_RX_PIN, UART_FUNCSEL_NUM(UART_ID, UART_RX_PIN));
gpio_address_mask = (1 << A01) | (1 << A02) | (1 << A03) | (1 << A04) | (1 << A05) | (1 << A06) | (1 << A07) | (1 << A08);
gpio_data_mask = (1 << D00) | (1 << D01) | (1 << D02) | (1 << D03) | (1 << D04) | (1 << D05) | (1 << D06) | (1 << D07);
gpio_controls_mask = (1 << RAS1) | (1 << RAS2) | (1 << WE_L) | (1 << WE_M) | (1 << CAS)| (1 << DATA_DIR) | (1 << SHIFT_EN);
gpio_init_mask (gpio_address_mask | gpio_data_mask | gpio_controls_mask);
gpio_set_dir_out_masked (gpio_address_mask | gpio_controls_mask);
gpio_set_dir_out_masked (gpio_data_mask);
gpio_set_outover (WE_L, GPIO_OVERRIDE_INVERT);
gpio_set_outover (WE_M, GPIO_OVERRIDE_INVERT);
gpio_set_outover (CAS, GPIO_OVERRIDE_INVERT);
gpio_set_outover (RAS1, GPIO_OVERRIDE_INVERT);
gpio_set_outover (RAS2, GPIO_OVERRIDE_INVERT);
gpio_put (RAS1, 1);
gpio_put (RAS2, 1);
gpio_put (WE_L, 1);
gpio_put (WE_M, 1);
gpio_put (CAS, 1);
gpio_put (DATA_DIR, 1);
gpio_put (SHIFT_EN, 1);
uint32_t pass = 0;
printf("BANKS 1-4: CONN -> XS1, pin 2 -> XS2:A3\n");
printf("BANKS 5-8: CONN -> XS2, pin 1 -> XS1:B16\n\n");
printf("TEST START\n");
printf("\nROW 1 (WE_L, RAS1)\n");
check_bank (WE_L, RAS1);
printf("\nROW 2 (WE_L, RAS2)\n");
check_bank (WE_L, RAS2);
printf("\nROW 3 (WE_M, RAS2)\n");
check_bank (WE_M, RAS2);
printf("\nROW 4 (WE_M, RAS1)\n");
check_bank (WE_M, RAS1);
printf("RANDOM VALUES TEST (INFINITE)\n\n");
while (true) {
pass++;
printf ("PASS %d\n", pass);
printf("ROW 1 (WE_L, RAS1): ");
check_bank_random (WE_L, RAS1);
printf("ROW 2 (WE_L, RAS2): ");
check_bank_random (WE_L, RAS2);
printf("ROW 3 (WE_M, RAS2): ");
check_bank_random (WE_M, RAS2);
printf("ROW 4 (WE_M, RAS1): ");
check_bank_random (WE_M, RAS1);
}
}