Случайны выбор дневника Раскрыть/свернуть полный список возможностей


Найдено 141 сообщений
Cообщения с меткой

uart - Самое интересное в блогах

Следующие 30  »
SoXiE

CH340G драйвер

Воскресенье, 10 Декабря 2017 г. 22:19 (ссылка)

Есть определённые сложности на Windows 10 с установкой драйвера USB-serial чипа CH340G, который так любят в среде Arduino. CH340G - волшебный чип по своей простоте, мост USB-UART, умеет в существующей реализации скорости UART до 250 kbps, добавляет в систему COM-порт, висящий на USB.



В свежеустановленной Windows 7 SP1 тоже имеется проблема с подключением устройств CH340, и связана она как с человеческим фактором, так и с паранойей M$ по поводу цифровой подписи драйверов.


DEVMGMT CH340G (412x448, 21Kb)

Если первая решается выбором однозначно более свежего драйвера CH340 (CH341), который во вложении, его версия 11/04/2011, 3.3.2011.11 кодируется VID/PID USB\VID_1A86&PID_7523&REV_0254. Версия от 2007 года не работает, точнее, работает плохо, делает вид, что работает. Устанавливаем через DRVSETUP64.EXE, этакой pre-install, и вот начинаются пляски с подписью драйверов.


DRVSETUP (420x269, 6Kb)

Пропихнуть драйвер в систему поможет утилита DSEO13b (Driver Signature Enforcement Overrider), в аттаче есть. Утиль позволяет подписать файл драйвера CH341S64.SYS, что даёт обойтись без включения тестового режима. Ну и напоследок перестраховываемся отключением проверки подписи драйверов в Windows.


Как понять, что не устройство плохое, а драйвер, и прошивка вполне нормальная (в случае с Atmega)? С 2007 драйвером у меня плохо шла отработка обратной связи от устройства, т.е. даже поиграв с буферизацией UART в винде (Использовать буферы FIFO UART 16550), я всё равно получал ответ устройства раньше, чем управляющая программа начинала его обрабатывать за счёт лагов драйвера, что приводило к обрыву связи по тайм-ауту.

Вложение: 5182599_ch340g_driver.rar

Метки:   Комментарии (0)КомментироватьВ цитатник или сообщество
SoXiE

Нестандартные скорости UART MSCOMM32

Воскресенье, 18 Июня 2017 г. 17:06 (ссылка)

Удалось связаться с AVR по UART через MSCOMM32.OCX на скорости 250000 бод. Частота кварца избыточная - 16 МГц. Действительно и для Arduino. Как? Подсказка на VBForums, используем Win32 API SetCommState и GetCommState из Kernel32. Немного костылей в выборе менюшки скоростей, т.е. для галочки открываем порт на допустимой стандартной скорости 115200, а затем уже задаём любую, вплоть до 2МБит.


AVR software uart 250000 baud (452x115, 5Kb)
MSComm 250000baud (206x172, 13Kb)

Сразу оговорюсь, что UART со стороны AVR программный, поэтому скорость такая низкая. Схемотехнически у меня программный RX/TX висит на свободных ногах ATMega328P, потому как аппаратный занят шиной данных с NAND флешкой.



Итак, управляющая программа на VB6 использует компонент MSComm и разрешает из коробки подключаться только на следующих скоростях (бит/с, бод): 110, 300, 600, 1200, 2400, 4800, 9600, 14400, 19200, 28800, 38400, 57600, 115200, 128000, 256000. Успехом увенчалась попытка подключения на 128000, а 256000 уже не приводила к желанному результату увидеть ответ устройства по UART. Возможно, дело в том, что если для аппаратного приёмопередатчика UART можно запросто подобрать скорость UART в зависимоти от частоты задающего генератора, то для программного, который зависит от кучи прерываний и лагов обработчика, высокие частоты упираются уже не в последнюю милю кабеля и разводку с экранировкой, а в специфику работы программного UART. Боюсь предположить, но аппаратный UART на AVR в теории может давать бодрейт до 2 МБит/с, т.е. 2000000. Разумеется, со стороны компьютера я ловлю его не через родной COM-порт материнки, а через преобразователь CH340G, который стоит в каждой ардуине, и его предел аппаратных возможностей с подобающей обвязкой по даташиту заканчивается как раз таки на 2 Mbps. Это ограничение уже упирается в физическую реализацию последней мили - длину проводов USB, разводку на плате, конденсаторы и качество кабеля.



Что я получил на скоростях 250 КБит/с? Чтение блока с флешки (135168 байт) за 6,16 секунд. Запись, правда, до сих пор ограничивается скоростью в 135168 байт за 35,9 сек, что обусловлено моей осторожностью и программными задержками при записи в NAND flash. Однако мой любимый дисплейчик ❤️️ LCD 160x128 16 битного цвета заполняется из флешки полностью картинкой за 215 мс, то есть можно глядеть кино с FPS ~5 кадров/сек., что я считаю пределом для 16 МГц, софтварном SPI через дрыганье ногами и попутном чтении с флешки, то смею предположить, что видеобуфер (ОЗУ дисплея) составляет 40 960 байт, и по UART напрямую при скорости 250 КБит заполнится за 2 секунды. Всё равно медленно, чтение флешки размером в 1 ГБ (NAND flash K9K8G08U0M-PIB0) займёт 14 часов.


Однако команда CLS, оформленная AVR-ASM просто дёрганьем CLK дисплея при постоянной единице на шине DATA очищает 160х128 за 0,105 сек, то есть за 105 мс., что как бы намекает на непредельность скорости. То есть используя полупрограммный-полуаппаратный SPI из-за того, что 9-й бит приходится дёргать вручную, остальные 8 будет слать аппаратный SPI, при быстром ОЗУ контроллера я бы смог добиться скорости вывода одного экрана (не пустого) за 105 мс при скорости UART в 1,5...2 МБит. Без промежуточной флешки, а картинку бы формировал на стороне компьютера. Тогда и кино в 10 FPS можно было бы крутить.


AVR Parallel output for Nokia 1616 LCD (700x451, 108Kb)

А самым забавным решением было бы применение внешнего аппаратного SPI, который из параллельной шины делает последовательную, и клок дёргать вручную. Однако это то же самое, что и полупрограммный SPI, потому как совсем блокируется возможность передавать данные в обратную сторону от дисплея (читать ОЗУ дисплея, SPFD54124B это позволяет). Но это уже больная фантазия.

Метки:   Комментарии (0)КомментироватьВ цитатник или сообщество
rss_rss_hh_new

Портирование MIPSfpga на другие платы и интеграция периферии в систему. Часть 3

Среда, 31 Мая 2017 г. 06:55 (ссылка)

https://habrahabr.ru/post/329854/

Комментарии (0)КомментироватьВ цитатник или сообщество
rss_rss_hh_new

Портирование MIPSfpga на другие платы и интеграция периферии в систему. Часть 2

Среда, 31 Мая 2017 г. 06:39 (ссылка)

Портирование MIPSfpga на другие платы и интеграция периферии в систему. Часть 2





MIPSfpga микропроцессор MIPS32 microAptiv описаный на языке Verilog для образовательных целей фирмы Imagination, который имеет кэш-память и блок управления памятью. Код процессора доступен пользователю (инструкция по скачиванию) и может использоваться для моделирования и реализации процессора на FPGA плате.



Данная статья является продолжением статьи о том как портировать MIPSfpga-plus на другие платы, и в ней будет описано как интегрировать периферию в систему MIPSfpga:





Так же о том как начать работать с MIPSfpga написано в статье:

habrahabr.ru/post/275215



Процессор использует интерфейс памяти для связи с периферийными устройствами. То есть, это означает что данные записываются и считываются с подключенной периферии так же, как и с блока памяти RAM. Интеграция периферии в процессор осуществляется подключением к шине AHB-Lite(подробная документация). Подробней попробуем разобраться в процессе подключения.



Для начала нужно иметь понятие как будут проходить сигналы по шине AHB-Lite:





Видно, что процесс считывания данных с периферии осуществляется по сигналу HRDATA, передача данных производится по HWRITE с активным высоким уровнем на сигнале разрешения записи, выбор GPIO осуществляется выбором адреса на HADDR.



1. Подключение клавиатуры Digilent Pmod KYPD



Первым датчиком который был подключён это 16 кнопочный pmod KYPD (даташит)





Распиновка и сигналы клавиатуры описаны в таблице:


























































Пин Сигнал Назначение Пин Сигнал Назначение
1 Col4 4 колонка 7 ROW4 4 ряд
2 Col3 3 колонка 8 ROW3 3 ряд
3 Col2 2 колонка 9 ROW2 2 ряд
4 Col1 1 колонка 10 ROW1 1 ряд
5 GND контакт земли 11 GND контакт земли
6 GND контакт питания 12 VCC контакт питания




схема подключения клавиатуры очень простая:





Следующим шагом для интеграции клавиатуры к шине AHB-lite будет написание модуля на Verilog. На схеме показано что ряды подтянуты к питанию сопротивлениями в R=10к, это значит что активный сигнал на них будет низким, а на каждую колонку с определенной частотой подается тактовый сигнал (низкий уровень). В момент когда активный сигнал на входе совпадёт с колонкой (col) на которой нажата кнопка на выходе рядка появится низкий уровень. Для реализации такого процесса нужно написать дешифратор (пример реализации модуля так же описан в данной статье).



Сам модуль имеет вид:

module kypd_decoder(
input i_clk,
input i_rst_n,
input [3:0] i_row,

output reg [3:0] o_col,
output reg [3:0] o_number
);

reg [19:0] counter;
reg [3:0] col;
reg [3:0] row;

// row col
parameter ZERO = 8'b11100111,
ONE = 8'b01110111,
TWO = 8'b01111011,
THREE = 8'b01111101,
FOUR = 8'b10110111,
FIVE = 8'b10111011,
SIX = 8'b10111101,
SEVEN = 8'b11010111,
EIGHT = 8'b11011011,
NINE = 8'b11011101,
A = 8'b01111110,
B = 8'b10111110,
C = 8'b11011110,
D = 8'b11101110,
E = 8'b11101101,
F = 8'b11101011;


always @(posedge i_clk or negedge i_rst_n)
if (i_rst_n == 0)
counter <= 20'b0;
else
counter <= counter + 1'b1;


always @(posedge i_clk or negedge i_rst_n)
if (i_rst_n == 1'b0) begin

o_col <= 4'b1110;
col <= 4'b1110;
row <= 4'b1111;

end else if (!counter) begin

o_col <= {o_col [0], o_col [3:1]};
col <= o_col;
row <= i_row;

end

always @(posedge i_clk or negedge i_rst_n)
if (i_rst_n == 0)
o_number <= 4'b0;
else
case ({row, col})

ZERO: o_number <= 4'h0;

ONE: o_number <= 4'h1;

TWO: o_number <= 4'h2;

THREE: o_number <= 4'h3;

FOUR: o_number <= 4'h4;

FIVE: o_number <= 4'h5;

SIX: o_number <= 4'h6;

SEVEN: o_number <= 4'h7;

EIGHT: o_number <= 4'h8;

NINE: o_number <= 4'h9;

A: o_number <= 4'hA;

B: o_number <= 4'hB;

C: o_number <= 4'hC;

D: o_number <= 4'hD;

E: o_number <= 4'hE;

F: o_number <= 4'hF;


endcase

endmodule


Схема модуля в Vivado будет иметь вид:





Если кратко, то добавить модуль дешифратора в проект Vivado нужно так: Add Sources -> Add or create design sources -> Next -> Create File -> (написать имя файла) -> Ok -> Ok -> Yes. Создан пустой Verilog файл, после создания файла, нужно его найти в иерархии системы MIPSfpga-plus, написать код дешифратора и сохранить. Более подробное описание как добавить модуль в проект и просто как работать с Vivado описано в предыдущей моей статье:



Портирование MIPSfpga на другие платы и интеграция периферии в систему. Часть 1



Теперь приступим к подключению входов и выходов к шине AHB-Lite и физическим выходам нашей платы.



Иерархия mipsfpga_ahb имеет вид:





Для начала в директории Verilog Header mfp_ahb_lite_matrix_config.vh пропишем с помощью директивы `define название периферии которую будем подключать. Для этого найдем строку с идентификатором добавления в систему датчика освещённости (подробнее о датчике описано в предыдущей статье):



Строку нужно закомментировать, это позволит выключить все строки которые связаны с кодом подключения датчика освещённости к шине AHB-Lite:

//`define MFP_DEMO_LIGHT_SENSOR


Пропишем и расскоментируем строку для нащей периферии:

`define MFP_PMOD_KYPD


Откроем «mfp_system» найдем строки подключения екземпляра датчика освещенности:

`ifdef MFP_DEMO_LIGHT_SENSOR


И рядом добавим екземпляр своего модуля дешифратора:

`ifdef MFP_PMOD_KYPD
kypd_decoder kypd_decoder
(
.i_clk ( SI_ClkIn ),
.i_rst_n ( KEY_0 ),
.o_col ( KYPD_DATA [3:0] ),
.i_row ( KYPD_DATA [7:4] ),
.o_number ( KYPD_OUT )
);
`endif


Сигналы модуля дешифратора нужно подключить к екземпляру шины mfp_ahb_lite_matrix_with_loader (где прописывать нужные строчки можно смотреть по примеру интеграции датчика освещённости с помощью поиска по модулю MFP_DEMO_LIGHT_SENSOR):

`ifdef MFP_PMOD_KYPD
.KYPD_OUT ( KYPD_OUT ),
`endif


Для соединения экземпляров модуля дешифратора и шины добавим сигнал типа wire:

`ifdef MFP_PMOD_KYPD
wire [3:0] KYPD_OUT;
`endif


После подключения нашего модуля дешифратора к шине перейдём в «mfp_ahb_lite_matrix_with_loader» который находится по иерархии ниже модуля «mfp_system» и добавим порт ввода/вывода:

`ifdef MFP_PMOD_KYPD
input [3:0] KYPD_OUT,
`endif


Так же добавим эти сигналы в екземпляр «mfp_ahb_lite_matrix»:

`ifdef MFP_PMOD_KYPD
.KYPD_OUT ( KYPD_OUT ),
`endif


Те же действия проделаем в «mfp_ahb_lite_matrix» который находится по иерархии ниже модуля «mfp_ahb_lite_matrix_with_loader» и добавим порт ввода/вывода:

`ifdef MFP_PMOD_KYPD
input [3:0] KYPD_OUT,
`endif


Так же добавим эти сигналы в екземпляр «mfp_ahb_gpio_slave»:

`ifdef MFP_PMOD_KYPD
.KYPD_OUT ( KYPD_OUT ),
`endif


Перейдем в модуль «mfp_ahb_gpio_slave», это именно тот блок (GPIO) в который мы так рвались, добавим порт ввода/вывода:

`ifdef MFP_PMOD_KYPD
input [3:0] KYPD_OUT,
`endif


Теперь следует изменить модуль «mfp_ahb_gpio_slave» так, чтобы он обнаруживал адрес ввода/вывода с отображением в память (которые мы ещё определим) и записывал данные (HWDATA) в соответствующий обнаруженному адресу регистр:

`ifdef MFP_PMOD_KYPD
`MFP_PMOD_KYPD_IONUM : HRDATA <= { 28'b0, KYPD_OUT };
`endif


Чтобы указать адрес по которому мы будем обращаться, откроем заголовочный файл «mfp_ahb_lite_matrix_config.vh» и добавим:

`ifdef MFP_PMOD_KYPD
`define MFP_PMOD_KYPD_ADDR 32'h1f800018
`endif


Модуль GPIO использует младшие биты адреса, чтобы определить, с каким периферийным устройством следует осуществлять операцию чтения или записи информации.

`ifdef MFP_PMOD_KYPD            
`define MFP_PMOD_KYPD_IONUM 4'h6
`endif


Вернемся назад по иерархии в модуль «mfp_system» и добавим порты ввода/вывода:

     `ifdef MFP_PMOD_KYPD
inout [7:0] KYPD_DATA,
input KEY_0,
`endif


Стоит заметить что это уже не совсем те порты которые мы подключали к шине. Перейдем в топ модуль оболочку (у меня «cmoda7») и добавим в екземпляр «mfp_system» строчки:

        `ifdef MFP_PMOD_KYPD
.KYPD_DATA ( JA ),
.KEY_0 ( ~ i_btn1 ),
`endif


Таким образом мы добавили к JA[7:0] выводам модуль нашего декодера и соединили декодер с процессором по шине AHB-Lite.



В нашем случае порты ввода/вывода JA в модуле оболочке и в файле ограничений (у меня «cmoda7.xdc») добавлять не потребуется так как они уже использовались для датчика освещённости. Но в других случаях такие действия потребуются, потому для понимания я просто покажу эти строки:

module cmoda7
(
...
...
...
inout [ 7:0] JA
);




cmoda7.xdc
## Pmod Header JA
set_property -dict {PACKAGE_PIN G17 IOSTANDARD LVCMOS33} [get_ports {JA[0]}]
set_property -dict {PACKAGE_PIN G19 IOSTANDARD LVCMOS33} [get_ports {JA[1]}]
set_property -dict {PACKAGE_PIN N18 IOSTANDARD LVCMOS33} [get_ports {JA[2]}]
set_property -dict {PACKAGE_PIN L18 IOSTANDARD LVCMOS33} [get_ports {JA[3]}]
set_property -dict {PACKAGE_PIN H17 IOSTANDARD LVCMOS33} [get_ports {JA[4]}]
set_property -dict {PACKAGE_PIN H19 IOSTANDARD LVCMOS33} [get_ports {JA[5]}]
set_property -dict {PACKAGE_PIN J19 IOSTANDARD LVCMOS33} [get_ports {JA[6]}]
set_property -dict {PACKAGE_PIN K18 IOSTANDARD LVCMOS33} [get_ports {JA[7]}]




И если мы вспомним в «mfp_ahb_lite_matrix_config.vh» мы закомментировали строку:

//`define MFP_DEMO_LIGHT_SENSOR


тем самым при синтезе системы весь код прописаный между

`ifdef MFP_DEMO_LIGHT_SENSOR
...
`endif


будет игнорироваться, и конфликтов использования портов не будет.



Мы можем посмотреть схему созданой системы MIPSfpga-plus со встроенным дешифратором для нашей клавиатуры, для этого откройте во вкладке RTL Analysys -> Open Elaborated Design -> Schematic. Здесь отображается вся схема системы, чтобы проверить правильность подключёного модуля дешифратора желательно пройтись по RTL Netlist и проверить все контакты.

Теперь можно сгенерировать bitstream файл (.bit) и загрузить в FPGA.



Напишем простую программу для взаимодействия клавиатуры и процессора.

Для загрузки кода в систему нужно перейти в папку скачаного mipsfpga plus ->github->mipsfpga-plus->programs->01_pmod_kypd откроем «mfp_memory_mapped_registers.h»

#define MFP_PMOD_KYPD_ADDR      0xBF800018
и
#define MFP_PMOD_KYPD (* (volatile unsigned *) MFP_PMOD_KYPD_ADDR )


далее откроем main.c и напишем пару строк для демонстрации:

#include "mfp_memory_mapped_registers.h"

int main ()
{
int n = 0;

for (;;)
{
MFP_7_SEGMENT_HEX = MFP_PMOD_KYPD;
}

return 0;
}


После в папке находим скрипт который компилирует код:

02_compile_and_link


Генерируем motorola_s_record файл:

08_generate_motorola_s_record_file


Проверяем к какому СОМ порту подключен USB UART преобразователь:

11_check_which_com_port_is_used


Изменяем файл 12_upload_to_the_board_using_uart:

set a=7 
mode com%a% baud=115200 parity=n data=8 stop=1 to=off xon=off odsr=off octs=off dtr=off rts=off idsr=off type program.rec >\.\COM%a%


где а – номер СОМ порта, к которому подключен USB UART преобразователь.

И загружаем программу:

12_upload_to_the_board_using_uart


Результат:







В следующей части расскажу как добавить в MIPSfpga встроеный в cmoda7 АПЦ, и LCD дисплей от Nokia 5100.
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/329852/

Комментарии (0)КомментироватьВ цитатник или сообщество
rss_rss_hh_new

[Из песочницы] Портирование MIPSfpga на другие платы и интеграция периферии в систему. Часть 1

Вторник, 30 Мая 2017 г. 16:19 (ссылка)

MIPSfpga представляет собой предназначенный для образовательных целей микропроцессор MIPS32 microAptiv фирмы Imagination, который имеет кэш-память и блок управления памятью. Код процессора на языке Verilog доступен пользователю и может использоваться для моделирования и реализации процессора на FPGA плате.



В даной статье будет описано на примере Digilent cmodA7 как портировать процессор MIPSfpga-plus на другие платы.







На сегодняшний день MIPSFPGA портирован на популярные платы таких фирм как ALTERA и Xilinx, среди них Basys 3, Nexys4 ddr, и другие (полный список находится на github). Такие платы наиболее популярны среди разработчиков на FPGA. Цена на такие платы довольно не маленькая, да и загружаются программы в ядро MIPSfpga с использованием интерфейса EJTAG и адаптера Bus Blaster ценой около 50$. Адаптер Bus Blaster получает команды по высокоскоростному кабелю USB 2.0 и преобразует их в последовательный протокол EJTAG, это позволяет загружать программы в ядро MIPSfpga и управлять отладкой программ, которые на нем выполняются. Проблема с относительно дорогим Bus Blaster была решена введением в систему MIPSfpga ряда улучшений. Улучшеный вариант системи MIPSfpga, названый MIPSfpga-plus включает в себя такие новые функции:



— Возможность загрузки программного обеспечения с использованием USB-to-UART коннектора ценой в $ 5 FTDI вместо $ 50 Bus Blaster, который иногда не так уж и легко достать.



— Возможность изменять тактовую частоту на лету с 50 или 25 МГц до 1 Гц (один цикл в секунду) для наблюдения за работой процессора в режиме реального времени, включая промахи в кэш-памяти и перенаправления конвеера.



— Пример интеграции датчика освещенности с протоколом SPI.



— Небольшая последовательность инициализации программного обеспечения, которая вписывается в 1 КБ вместо 32 КБ памяти, что позволяет переносить MIPSfpga на более широкий выбор плат FPGA без использования внешней памяти. Реализация UART описана в статье: MIPSfpga и UART.



Создание проекта в Xilinx Vivado с MIPSfpga-plus



Кто работал с MIPSFPGA-plus на платах фирмы Xilinx, могут пропустить данный этап. В связи с постоянно растущим количеством различных FPGA плат и набирающим популярность проектом по предоставлению исходников промышленных процессоров для университетов (а именно на базовую конфигурацию экономичного процессорного ядра MIPS microAptiv UP). Подробнее тут: Исходники промышленных процессоров станут доступными для университетов?, инструкция по портированию системы MIPSfpga+ в новую плату по мнению автора не будет лишней:



1. Для начала нужно получить пакет c системой MIPSFPGA. Подробная инструкция о том как это сделать:



-> mipsfpga-download-instruction



Если у вас уже есть MIPSfpga система и требуется использование usb-to-uart преобразователя (в плате cmodA7, а так же на многих других платах фирмы Xilinx есть встроенный uart), то вам потребуется скачать актуальную версию расширения MIPSfpga-plus:



-> Mipsfpga-plus



2. Для плат фирмы Xilinx используется программное обеспечение Vivado, актуальную версию можно скачать по ссылке:



-> Download Vivado



3. Теперь давайте создадим новый проект в Vivado:







Выбираем где будет хранится созданный проект:







Жмем далее:







Выбираем RTL проект и жмем далее:







Теперь добавим файлы системы оригинального MIPSfpga:











А так же MIPSfpga-plus которые находятся в архиве скачаном с mipsfpga-plus:







Добавим в проект модуль uart о котором ранее шла речь:







Пропускаем создание IP и файлов констрейнов создадим их позже:











Далее нужно либо выбрать микросхему либо добавить вашу плату.



Плата Digilent cmod A7 была выбрана в связи с ее не большой ценой и наличием АЦП которое мы потом используем. Чтобы выбрать FPGA схему нужно прочитать на вашу плату документацию, на cmodA7 размещен чип xc7a35tcpg236-1:







Другим способом является добавление файла вашей платы в библиотеку Vivado, этот способ лучше тем что, во первых, запомнить название платы удобней чем чипа, во вторых если вы в будущем захотите использовать block designer в Vivado, то у вас будет дополнительный инструментарий для удобной работы с интерфейсами платы, IP ядрами, и т.д. Скачать их можно на GitHub, сохранить эти файлы нужно в ~\Vivado\2015.1\data\boards\ (актуально для Vivado 2015.1 и новее).











Вот мы и создали проект с MIPSfpga-plus.



Инструкция по портированию на примере платы Digilent CmodA7 на базе микросхемы Artix-7



Если вкратце то на борту платы cmodA7 находится чип семейства Artix-7, имеет 20800 LUT, 41600 FF, 225 KB блочной памяти, имеется 48 пинов, среди которых 2 является выходами АЦП, также имеется usb-uart преобразователь, Quad-SPI Flash, и JTAG, 2 тактовые кнопки, а также 5 светодиодов 3 из которых это RGB (даташит).



Чтобы перенести систему MIPSfpga на плату cmodA7, следует:



Шаг 1. Написать модуль-оболочку, который устанавливает соответствие между вводами/выводами MIPSfpga и вводами/выводами платы Basys3

Шаг 2. Уменьшить объем памяти системы MIPSfpga для соответствия плате Basys3

Шаг 3. Добавить файл ограничений, который устанавливает соответствие между вводами/выводами платы и выводами корпуса FPGA.



Шаг 1. Добавим новый файл оболочки cmoda7.v































Установим cmoda7.v топ модулем в иерархии системы.







Так как на плате cmoda7 нет переключателей которые можно было бы использовать для понижения частоты процессора (эта модификация появилась в MIPSfpga-plus), этот модуль просто не был включен в модуль оболочку. Так же можно исключить выход EJTAG к которому подключается BUS Blaster.



Для начала нужно добавить заголовочный файл конфигурации шины AHB_lite.



`include "mfp_ahb_lite_matrix_config.vh"


Усовершенствованная высокопроизводительная шина (Advanced High-performance Bus, AHB) является открытым интерфейсом, который используется во многих микропроцессорных системах, особенно во встроенных. Шина AHB облегчает организацию соединения нескольких устройств. AHB-Lite является упрощенной версией AHB с одним ведущим устройством.







Эта конфигурация имеет одно ведущее устройство, процессор MIPSfpga, и три ведомых: RAM0, RAM1 и GPIO, которые представляют собой (соответственно) два блока ОЗУ и модуль доступа к устройствам ввода/вывода платы. Мы как раз и будем работать с блоком GPIO и писать модули взаимодействия с периферией.



Пропишем основные порты ввода-вывода:



module cmoda7
(
input i_clk,
input i_btn0,
input i_btn1,
input RsRx,

output [ 6:0] seg,
output dp,
output [ 3:0] an,
output led0_r,
output led0_g,
output led0_b,

inout [ 7:0] JA

);


i_clk — сигнал тактового генератора платы частотой (для cmodA7 12 МГц).

i_btn0 — кнопка используется для перезагрузки процессора.

i_btn1 — n/c.

RsRx — сигнал приема по uart.

seg, dp, an, — контакты для подключения семисегментного 4 разрядного индикатора.

led_r, led_g, led_b, — выводи размещённого на плате RGB Led.

JA — Pmod интерфейс.



Основными сигналами являются сигнал тактовой частоты и reset (i_btn0) остальные для подключения периферии.







Основной целью модуля cmoda7.v является создание экземпляра системы MIPSfpga-plus (mipsfpga_sys) и ее соединение с вводами/выводами платы.




wire clock;
wire reset = i_btn0;

wire display_clock;
wire [7:0] anodes;

wire [`MFP_N_BUTTONS - 1:0] IO_Buttons;
wire [`MFP_7_SEGMENT_HEX_WIDTH - 1:0] IO_7_SegmentHEX;

assign IO_Buttons = { { `MFP_N_BUTTONS - 2 { 1'b0 } } , i_btn0, i_btn1 };

mfp_system mfp_system
(
.SI_ClkIn ( clock ),
.SI_Reset ( reset ),

.HADDR ( ),
.HRDATA ( ),
.HWDATA ( ),
.HWRITE ( ),

.EJ_TRST_N_probe ( ),
.EJ_TDI ( ),
.EJ_TDO ( ),
.EJ_TMS ( ),
.EJ_TCK ( ),
.SI_ColdReset ( ),
.EJ_DINT ( 1'b0 ),

.IO_Switches ( ),
.IO_Buttons ( IO_Buttons ),
.IO_RedLEDs ( ),
.IO_GreenLEDs ( ),
.IO_7_SegmentHEX ( IO_7_SegmentHEX ),

`ifdef MFP_DEMO_LIGHT_SENSOR
.SPI_CS ( JA [0] ),
.SPI_SCK ( JA [3] ),
.SPI_SDO ( JA [2] ),
`endif

.UART_RX ( RsRx ),
.UART_TX ( )
);

`ifdef MFP_DEMO_LIGHT_SENSOR
assign JA [1] = 1'b0;
`endif


MFP_DEMO_LIGHT_SENSOR будем использовать при тестировании портированой системы. Как видим на выходе системы mfp_system будет 32-х разрядная шина IO_7_SegmentHEX которую мы выводим в модуль дешифратора 4-х разрядного 7 сегментного индикатора, подключим в оболочку модуль екземпляра «mfp_multi_digit_display»:



mfp_multi_digit_display multi_digit_display
(
.clock ( display_clock ),
.resetn ( ~ reset ),
.number ( IO_7_SegmentHEX ),

.seven_segments ( seg ),
.dot ( dp ),
.anodes ( an )
);


При создании дешифратора стоит узнать является ли индикатор с общим анодом или катодом.

Код дешифратора семисегментного индикатора с общим анодом имеет такой вид:



module mfp_single_digit_seven_segment_display
(
input [3:0] digit,
output reg [6:0] seven_segments
);

always @*
case (digit)
'h0: seven_segments = 'b1000000; // a b c d e f g
'h1: seven_segments = 'b1111001;
'h2: seven_segments = 'b0100100; // --a--
'h3: seven_segments = 'b0110000; // | |
'h4: seven_segments = 'b0011001; // f b
'h5: seven_segments = 'b0010010; // | |
'h6: seven_segments = 'b0000010; // --g--
'h7: seven_segments = 'b1111000; // | |
'h8: seven_segments = 'b0000000; // e c
'h9: seven_segments = 'b0011000; // | |
'ha: seven_segments = 'b0001000; // --d--
'hb: seven_segments = 'b0000011;
'hc: seven_segments = 'b1000110;
'hd: seven_segments = 'b0100001;
'he: seven_segments = 'b0000110;
'hf: seven_segments = 'b0001110;
endcase

endmodule

//--------------------------------------------------------------------

module mfp_multi_digit_display
(
input clock,
input resetn,
input [31:0] number,

output reg [ 6:0] seven_segments,
output reg dot,
output reg [ 7:0] anodes
);

function [6:0] bcd_to_seg (input [3:0] bcd);

case (bcd)
'h0: bcd_to_seg = 'b1000000; // a b c d e f g
'h1: bcd_to_seg = 'b1111001;
'h2: bcd_to_seg = 'b0100100; // --a--
'h3: bcd_to_seg = 'b0110000; // | |
'h4: bcd_to_seg = 'b0011001; // f b
'h5: bcd_to_seg = 'b0010010; // | |
'h6: bcd_to_seg = 'b0000010; // --g--
'h7: bcd_to_seg = 'b1111000; // | |
'h8: bcd_to_seg = 'b0000000; // e c
'h9: bcd_to_seg = 'b0010000; // | |
'ha: bcd_to_seg = 'b0001000; // --d--
'hb: bcd_to_seg = 'b0000011;
'hc: bcd_to_seg = 'b1000110;
'hd: bcd_to_seg = 'b0100001;
'he: bcd_to_seg = 'b0000110;
'hf: bcd_to_seg = 'b0001110;
endcase

endfunction

reg [2:0] i;

always @ (posedge clock or negedge resetn)
begin
if (! resetn)
begin
seven_segments <= bcd_to_seg (0);
dot <= 0;
anodes <= 8'b00000001;

i <= 0;
end
else
begin
seven_segments <= bcd_to_seg (number [i * 4 +: 4]);
dot <= 0;
anodes <= (1 << i);

i <= i + 1;
end
end

endmodule


Как можно увидеть по каждому переднему фронту clock в seven_segments выводится соответствующий сигнал bcd_to_seg, а переключение между разрядами индикатора производится с помощью переключения активного сигнала на соответствующих анодах (либо катодах).



Так как на вход процессора поступает сигнал в частотой в 50 МГц который мы создадим далее, если ми будем с такой частотой менять значения на индикаторе наш глаз не будет замечать эти изменения(для нормального отображения значений на 7 сегментном индикаторе необходима частота приблизительно в 763 Гц). Для этого подключим экземпляр делителя частоты:



   mfp_clock_divider_50_MHz_to_763_Hz mfp_clock_divider_50_MHz_to_763_Hz
(clock, display_clock);


В исходных файлах делителя частоты с 50 MГц в 763 Гц нет. Поэтому мы добавим его в файл mfp_clock_dividers.v:







module mfp_clock_divider_50_MHz_to_763_Hz
(
input clki,
output clko
);

mfp_clock_divider
# (.DIV_POW_SLOWEST (16))
mfp_clock_divider
(
.clki ( clki ),
.sel_lo ( 1'b1 ),
.sel_mid ( 1'b0 ),
.clko ( clko )
);

endmodule


На вход системы поступают сигналы reset и clock, RsRx, IO_Buttons. Но у нас на входе топ модуля сигнал i_clk, а не clock. Дело в том что на плате присутствует тактовый генератор в 12 МГц, а процессор в FPGA может работать на частотах 50 МГц и выше, а что делать если у вас другая плата с другой тактовой частотой (например Nexys 4 DDR имеет тактовую частоту 100 МГц). Решается проблема созданием IP ядра Clocking Wizard (PLL), для этого откроем IP каталог:







Откроем Clocking Wizard:







Вкладку board оставляем как есть, либо настраиваем нужные нам входы и переходим на вкладку clocking options можно выбрать либо MMCM имеет более широкий диапазон входных частот 10...800МГц, чем PLL 19...800МГц, поскольку на cmoda7 всего 12 МГц выбираем MMCM, но для других плат можно выбирать другие параметры:







Во вкладке output clocks устанавливаем частоту 50 МГц (с частотой можно и нужно экспериментировать, так на других FPGA могут быть другие характеристики):







Также убираем reset и locked:







Port renaming, MMCM setting и Summary смотрим и оставляем как есть, жмем ОК, ОК, в следующем окне выбираем generate:



image



Последним штрихом сделаем непрерывное присваивание для RGB Led, поскольку как видно из схемы в плавающем состоянии они будут тускло светится, а мы хотим что бы они были выключены:



image



assign led0_r = 1'b1;
assign led0_g = 1'b1;
assign led0_b = 1'b1;


В конце напишем:



endmodule


Модуль оболочка создан, перейдем к изменению размера памяти.



Шаг 2. Уменьшаем объем памяти системы MIPSfpga для соответствия плате cmoda7



Плата cmoda7 имеет 225 Кбайт блоковой памяти. Таким образом, два блока памяти (128 Кбайт ОЗУ сброса и 256 Кбайт ОЗУ программ) не помещаются на плате cmoda7. Так как, загрузочный код может уместиться в 32 Кбайт, и можно ограничить потребности программ объемом 64 Кбайт. Таким образом, общая необходимая память (32 Kбайт + 64 Kбайт = 96 Kбайт) соответствует объему памяти платы cmoda7. Оставшиеся 225-96 = 129 Kбайт памяти могут быть использованы для других нужд системы MIPSfpga, например, в качестве кэш-памяти.



Уменьшить объем памяти можно, изменив размер памяти, заявленный в заголовочном файле Verilog который мы подключали в файл оболочку «mfp_ahb_lite_matrix_config.vh». Открываем файл mipsfpga_ahb_const.vh. Адреса ОЗУ сброса (или ОЗУ загрузки) состоят из 13 бит. Таким образом, объем ОЗУ сброса равен 213 32-битных слов = 215 байт = 32 Kбайт.







`define H_RAM_RESET_ADDR_WIDTH  13 


Адреса ОЗУ программ состоят из 14 бит. Таким образом, объем ОЗУ программ равен 214 32-битных слов = 216 байт = 64 Kбайт.



`define H_RAM_ADDR_WIDTH  14


Шаг 3. Создаем файл ограничений cmoda7



Теперь создадим «cmoda7.xdc» который устанавливает соответствие между внешними сигналами модуля-оболочки и выводами корпуса FPGA платы cmoda7 (xdc файл с полным списком выводов для cmoda7):












## Clock signal 12 MHz
set_property -dict {PACKAGE_PIN L17 IOSTANDARD LVCMOS33} [get_ports i_clk]
create_clock -period 83.330 -name sys_clk_pin -waveform {0.000 41.660} -add [get_ports i_clk]

## Buttons
set_property -dict {PACKAGE_PIN A18 IOSTANDARD LVCMOS33} [get_ports i_btn0]
set_property -dict {PACKAGE_PIN B18 IOSTANDARD LVCMOS33} [get_ports i_btn1]

## LEDs
set_property -dict {PACKAGE_PIN B17 IOSTANDARD LVCMOS33} [get_ports led0_b]
set_property -dict {PACKAGE_PIN B16 IOSTANDARD LVCMOS33} [get_ports led0_g]
set_property -dict {PACKAGE_PIN C17 IOSTANDARD LVCMOS33} [get_ports led0_r]

## Pmod Header JA
set_property -dict {PACKAGE_PIN G17 IOSTANDARD LVCMOS33} [get_ports {JA[0]}]
set_property -dict {PACKAGE_PIN G19 IOSTANDARD LVCMOS33} [get_ports {JA[1]}]
set_property -dict {PACKAGE_PIN N18 IOSTANDARD LVCMOS33} [get_ports {JA[2]}]
set_property -dict {PACKAGE_PIN L18 IOSTANDARD LVCMOS33} [get_ports {JA[3]}]
set_property -dict {PACKAGE_PIN H17 IOSTANDARD LVCMOS33} [get_ports {JA[4]}]
set_property -dict {PACKAGE_PIN H19 IOSTANDARD LVCMOS33} [get_ports {JA[5]}]
set_property -dict {PACKAGE_PIN J19 IOSTANDARD LVCMOS33} [get_ports {JA[6]}]
set_property -dict {PACKAGE_PIN K18 IOSTANDARD LVCMOS33} [get_ports {JA[7]}]

## GPIO Pins 1 - 6 7_segment_ind
set_property -dict {PACKAGE_PIN M3 IOSTANDARD LVCMOS33} [get_ports {seg[1]}]
set_property -dict {PACKAGE_PIN L3 IOSTANDARD LVCMOS33} [get_ports {an[1]} ]
set_property -dict {PACKAGE_PIN A16 IOSTANDARD LVCMOS33}[get_ports {an[2]} ]
set_property -dict {PACKAGE_PIN K3 IOSTANDARD LVCMOS33} [get_ports {seg[5]}]
set_property -dict {PACKAGE_PIN C15 IOSTANDARD LVCMOS33}[get_ports {seg[0]}]
set_property -dict {PACKAGE_PIN H1 IOSTANDARD LVCMOS33} [get_ports {an[3]} ]

## GPIO Pins 43 - 48 7_segment_ind
set_property -dict {PACKAGE_PIN U3 IOSTANDARD LVCMOS33} [get_ports {seg[3]}]
set_property -dict {PACKAGE_PIN W6 IOSTANDARD LVCMOS33} [get_ports {seg[4]}]
set_property -dict {PACKAGE_PIN U7 IOSTANDARD LVCMOS33} [get_ports dp ]
set_property -dict {PACKAGE_PIN W7 IOSTANDARD LVCMOS33} [get_ports {seg[2]}]
set_property -dict {PACKAGE_PIN U8 IOSTANDARD LVCMOS33} [get_ports {seg[6]}]
set_property -dict {PACKAGE_PIN V8 IOSTANDARD LVCMOS33} [get_ports {an[0]} ]

## UART
#set_property -dict { PACKAGE_PIN J18 IOSTANDARD LVCMOS33 } [get_ports { uart_rxd_out }]; #IO_L7N_T1_D10_14 Sch=uart_rxd_out
set_property -dict {PACKAGE_PIN J17 IOSTANDARD LVCMOS33} [get_ports RsRx]


Например, следующая строка устанавливает соответствие между входом i_clk и выводом корпуса FPGA L17, на который поступает тактовый сигнал с частотой 12 МГц с платы cmoda7.



set_property -dict {PACKAGE_PIN L17 IOSTANDARD LVCMOS33} [get_ports i_clk]
create_clock -period 83.330 -name sys_clk_pin -waveform {0.000 41.660} -add [get_ports i_clk]


Так же в файл ограничений нужно добавить следующие выходные временные ограничения для сигналов:



# I/O virtual clock
create_clock -period 83.330 -name "clk_virt"

# tsu/th constraints
set_input_delay -clock "clk_virt" -min -add_delay 0.000 [get_ports i_btn0]
set_input_delay -clock "clk_virt" -max -add_delay 10.000 [get_ports i_btn0]
set_input_delay -clock "clk_virt" -min -add_delay 0.000 [get_ports i_btn1]
set_input_delay -clock "clk_virt" -max -add_delay 10.000 [get_ports i_btn1]
set_input_delay -clock "clk_virt" -min -add_delay 0.000 [get_ports led0_b]
set_input_delay -clock "clk_virt" -max -add_delay 10.000 [get_ports led0_b]
set_input_delay -clock "clk_virt" -min -add_delay 0.000 [get_ports led0_g]
set_input_delay -clock "clk_virt" -max -add_delay 10.000 [get_ports led0_g]
set_input_delay -clock "clk_virt" -min -add_delay 0.000 [get_ports led0_r]
set_input_delay -clock "clk_virt" -max -add_delay 10.000 [get_ports led0_r]

## PMOD ALS
set_output_delay -clock "clk_virt" -min -add_delay 0.000 [get_ports {JA[0]}]
set_output_delay -clock "clk_virt" -max -add_delay 10.000 [get_ports {JA[0]}]
set_output_delay -clock "clk_virt" -min -add_delay 0.000 [get_ports {JA[1]}]
set_output_delay -clock "clk_virt" -max -add_delay 10.000 [get_ports {JA[1]}]
set_input_delay -clock "clk_virt" -min -add_delay 0.000 [get_ports {JA[2]}]
set_input_delay -clock "clk_virt" -max -add_delay 10.000 [get_ports {JA[2]}]
set_output_delay -clock "clk_virt" -min -add_delay 0.000 [get_ports {JA[3]}]
set_output_delay -clock "clk_virt" -max -add_delay 10.000 [get_ports {JA[3]}]

set_input_delay -clock "clk_virt" -min -add_delay 0.000 [get_ports {seg[]}]
set_input_delay -clock "clk_virt" -max -add_delay 10.000 [get_ports {seg[]}]
set_input_delay -clock "clk_virt" -min -add_delay 0.000 [get_ports {an[]}]
set_input_delay -clock "clk_virt" -max -add_delay 10.000 [get_ports {an[]}]
set_input_delay -clock "clk_virt" -min -add_delay 0.000 [get_ports dp]
set_input_delay -clock "clk_virt" -max -add_delay 10.000 [get_ports dp]
set_output_delay -clock "clk_virt" -min -add_delay 0.000 [get_ports RsRx]
set_output_delay -clock "clk_virt" -max -add_delay 10.000 [get_ports RsRx]


Тест MIPSfpga



Мы можем протестировать портированый на нашу плату процессор, для этого нужно зайти в файл конфигурации «mfp_ahb_lite_matrix_config.vh» и расскоментируем строку:



`define MFP_DEMO_LIGHT_SENSOR






Таким образом мы подключили написанный на Verilog модуль интерфейса SPI к шине AHB Lite для соединения с датчиком освещённости PmodALS фирмы Digilent.



Модуль SPI
module mfp_pmod_als_spi_receiver
(
input clock,
input reset_n,
output cs,
output sck,
input sdo,
output reg [15:0] value
);

reg [21:0] cnt;
reg [15:0] shift;

always @ (posedge clock or negedge reset_n)
begin
if (! reset_n)
cnt <= 22'b100;
else
cnt <= cnt + 22'b1;
end

assign sck = ~ cnt [3];
assign cs = cnt [8];

wire sample_bit = ( cs == 1'b0 && cnt [3:0] == 4'b1111 );
wire value_done = ( cnt [21:0] == 22'b0 );

always @ (posedge clock or negedge reset_n)
begin
if (! reset_n)
begin
shift <= 16'h0000;
value <= 16'h0000;
end
else if (sample_bit)
begin
shift <= (shift << 1) | sdo;
end
else if (value_done)
begin
value <= shift;
end
end

endmodule








Схема подключения изображена на рисунке:







Датчик подключен к порту Pmod, выходи которого описаны в «cmoda7.xdc» прописаны как JA[7..0].



## Pmod Header JA
set_property -dict {PACKAGE_PIN G17 IOSTANDARD LVCMOS33} [get_ports {JA[0]}]
...
set_property -dict {PACKAGE_PIN K18 IOSTANDARD LVCMOS33} [get_ports {JA[7]}]


Полученую RTL схему можно доследить во вкладке RTL Analisys -> Schematic, где модуль интерфейса SPI «mfp_pmod_als_spi_receiver» находится в «mfp_system»:







Что бы загрузить в FPGA созданный проект нужно сгенерировать bitstream файл «cmoda7.bit», для этого во вкладке Program and Debug -> Generate Bitstream и подождать завершения операции:







После создания bitstream файла нужно его загрузить в плату, для этого во вкладке Program and Debug -> откроем Open Hardware Manager -> Open Target -> Auto Connect -> Program Device и загрузим систему:







Загрузка программы для работы с датчиком



Чтобы процессор обменивался с датчиком данными нужно написать программу и загрузить в блок RAM1 который так же подключён к шине AHB Lite.



Процессор MIPSfpga программируют с использованием инструментов разработки Codescape компании Imagination. Установите Codescape SDK и OpenOCD. Codescape поддерживает программирование как на языке C, так и на языке ассемблера.



Для загрузки кода в систему нужно перейти в папку скачаного mipsfpga plus -> github -> mipsfpga-plus -> programs-> 01_light_sensor откроем «mfp_memory_mapped_registers.h».



#define MFP_LIGHT_SENSOR_ADDR   0xBF800014

и

#define MFP_LIGHT_SENSOR (* (volatile unsigned *) MFP_LIGHT_SENSOR_ADDR )


далее откроем main.c и напишем пару строк:



#include "mfp_memory_mapped_registers.h"

int main ()
{
int n = 0;

for (;;)
{
MFP_7_SEGMENT_HEX = MFP_LIGHT_SENSOR;
}

return 0;
}


После в папке находим скрипт который компилирует код:



02_compile_and_link


Генерируем motorola_s_record файл:



08_generate_motorola_s_record_file


Проверяем к какому СОМ порту подключен USB UART преобразователь:



11_check_which_com_port_is_used


Изменяем файл 12_upload_to_the_board_using_uart:



set a=7 
mode com%a% baud=115200 parity=n data=8 stop=1 to=off xon=off odsr=off octs=off dtr=off rts=off idsr=off type program.rec >\.\COM%a%


где а – номер СОМ порта, к которому подключен USB UART преобразователь. И загружаем программу:



12_upload_to_the_board_using_uart


Результат портирования системы можно посмотреть на видео:









Для понимания работы процессора, и возможности написания новых модулей на языке описания аппаратуры (Verilog, VHDL), а так же схемотехники, архитектуры компьютера, микроархитектуры (организация процессорного конвейера) и программирования на ассемблере, и много чего другого что поможет вам взять старт в изучении всего что связано с электроникой рекомендуется прочитать книгу про которую написано в статье: Бесплатный учебник электроники, архитектуры компьютера и низкоуровневого программирования на русском языке.



В следующей части будет описано как подключать различную периферию в систему MIPSfpga на примере клавиатуры Digilent Pmod KYPD, встроенной АЦП, и LCD дисплея от Nokia.
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/329808/

Комментарии (0)КомментироватьВ цитатник или сообщество
Аноним

Среда, 01 Декабря 1970 г. 03:00 (ссылка)

Комментарии ()КомментироватьВ цитатник или сообщество
Аноним

Среда, 01 Декабря 1970 г. 03:00 (ссылка)

Комментарии ()КомментироватьВ цитатник или сообщество
Аноним

Среда, 01 Декабря 1970 г. 03:00 (ссылка)

Комментарии ()КомментироватьВ цитатник или сообщество
Аноним

Среда, 01 Декабря 1970 г. 03:00 (ссылка)

Комментарии ()КомментироватьВ цитатник или сообщество
Аноним

Среда, 01 Декабря 1970 г. 03:00 (ссылка)

Комментарии ()КомментироватьВ цитатник или сообщество
Аноним

Среда, 01 Декабря 1970 г. 03:00 (ссылка)

Комментарии ()КомментироватьВ цитатник или сообщество

Следующие 30  »

<uart - Самое интересное в блогах

Страницы: [1] 2 3 ..
.. 10

LiveInternet.Ru Ссылки: на главную|почта|знакомства|одноклассники|фото|открытки|тесты|чат
О проекте: помощь|контакты|разместить рекламу|версия для pda