<rss version="2.0" xmlns:yandex="http://news.yandex.ru" xmlns:media="http://search.yahoo.com/mrss/" xmlns:turbo="http://turbo.yandex.ru" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Михаил Юдин</title><link>https://mikhail-yudin.ru/blog/hardware/</link><description/><generator>Hugo -- gohugo.io</generator><language>ru</language><lastBuildDate>Tue, 23 Jul 2024 00:00:00 +0000</lastBuildDate><image><url>https://mikhail-yudin.ru/images/brand/favicon.png</url><title>Михаил Юдин</title><link>https://mikhail-yudin.ru/</link></image><atom:link href="https://mikhail-yudin.ru/blog/hardware/index.xml" rel="self" type="application/rss+xml"/><item turbo="true"><title>Внутренности плеера Explay L88</title><link>https://mikhail-yudin.ru/blog/hardware/explay-l88-internals/</link><pubDate>Tue, 23 Jul 2024 00:00:00 +0000</pubDate><guid>https://mikhail-yudin.ru/blog/hardware/explay-l88-internals/</guid><description>Разобрал плеер, вдруг кому нужно.
Разборка Лицевая сторона держится на двустороннем скотче и четырёх защёлках.
Далее откручиваем крестовой отвёрткой 6 винтов и откидываем основную часть корпуса.
Аккуратно отодвигаем у платы защёлки и освобождаем плату.
Внутренности Аккумулятор промаркирован: REC 301945P, 11YG2803. Размеры: 45мм x 19мм x 3мм.
Аккум успешно заменён на:
Аккумуляторная батарея универсальный 502035p 3,7v Li-Pol 40 Akfis https://wildberries.ru/catalog/199010373/detail.aspx
Основной чип Rockchip RKnano-8 AD1M391 1121.
Приёмник RDA 5807P.</description><turbo:content><![CDATA[
      		<header>
      			<h1>Внутренности плеера Explay L88</h1></header>
            <div class='entry-content'>
              <p>Разобрал плеер, вдруг кому нужно.</p>
<h2 id="разборка">Разборка</h2>
<p>Лицевая сторона держится на двустороннем скотче и четырёх защёлках.</p>
<p><img src="IMG_20240723_191523_835.jpg" alt="Корпус плеера Explay L88"></p>
<p>Далее откручиваем крестовой отвёрткой 6 винтов и откидываем основную часть корпуса.</p>
<p>Аккуратно отодвигаем у платы защёлки и освобождаем плату.</p>
<h2 id="внутренности">Внутренности</h2>
<p><img src="IMG_20240723_191249_591.jpg" alt="Аккумулятор плеера Explay L88">
<img src="IMG_20240723_191254_725.jpg" alt="Лицевая сторона платы плеера Explay L88">
<img src="IMG_20240723_191255_458.jpg" alt="Обратная сторона платы плеера Explay L88"></p>
<p>Аккумулятор промаркирован: REC 301945P, 11YG2803. Размеры: 45мм x 19мм x 3мм.</p>
<p>Аккум успешно заменён на:</p>
<blockquote>
<p>Аккумуляторная батарея универсальный 502035p 3,7v Li-Pol 40 Akfis
<a href="https://wildberries.ru/catalog/199010373/detail.aspx">https://wildberries.ru/catalog/199010373/detail.aspx</a></p>
</blockquote>
<p>Основной чип Rockchip RKnano-8 AD1M391 1121.</p>
<p>Приёмник RDA 5807P.</p>

            </div>
      	]]></turbo:content></item><item turbo="true"><title>Стоит ли менять термопасту процессора ноутбука на КПТ-8</title><link>https://mikhail-yudin.ru/blog/hardware/stoit-li-menyat-termopastu-processora-noutbuka/</link><pubDate>Wed, 08 Jul 2020 00:00:00 +0000</pubDate><guid>https://mikhail-yudin.ru/blog/hardware/stoit-li-menyat-termopastu-processora-noutbuka/</guid><description>Решил почистить ноутбук и заменить термопасту на дешёвую КПТ-8, т.к. процессор ноутбука, которому уже 7 лет от роду, раскалился до 90 градусов по Цельсию.
Открутил радиатор, а заводская термопаста ещё влажненькая. Правда серая и совсем жидкая. Несмотря на это, решил заменить-таки купленной до этого КПТ-8. По многочисленным отзывам рекомендуют менять на дорогую.
Правда опыт показал, что температура процессора после очистки системы охлаждения и замены термопасты на недорогую КПТ-8 стала ниже примерно на 5 градусов:</description><turbo:content><![CDATA[
      		<header>
      			<h1>Стоит ли менять термопасту процессора ноутбука на КПТ-8</h1></header>
            <div class='entry-content'>
              <p>Решил почистить ноутбук и заменить термопасту на дешёвую КПТ-8,
т.к. процессор ноутбука, которому уже <strong>7 лет</strong> от роду, раскалился до 90
градусов по Цельсию.</p>
<p>Открутил радиатор, а заводская термопаста ещё влажненькая. Правда серая и совсем
жидкая. Несмотря на это, решил заменить-таки купленной до этого КПТ-8.
По многочисленным отзывам рекомендуют менять на дорогую.</p>
<p>Правда <strong>опыт показал, что температура процессора</strong> после очистки системы охлаждения
и <strong>замены термопасты на недорогую КПТ-8</strong> <strong>стала ниже</strong> примерно
<strong>на 5 градусов</strong>:</p>
<ul>
<li>в простое было 63..65C, стало 58-62C;</li>
<li>в рабочем режиме (веб-разработка, браузер) было 65..72C, стало 62..68C;</li>
<li>в режиме просмотра видео на YouTube было 72..82C, стало 70..74C!</li>
</ul>
<p>Так же пришлось избавиться от опасного вздутого аккумулятора. Теперь работаю от
сети.</p>
<p>Так что если термопасте больше 3-4 лет, смело меняйте! Пускай ваша техника живёт
долго.</p>

            </div>
      	]]></turbo:content></item><item turbo="true"><title>Прошивка тачскрина ft5316</title><link>https://mikhail-yudin.ru/blog/hardware/proshivka-touchscreen-ft5316/</link><pubDate>Sun, 28 Jul 2019 00:00:00 +0000</pubDate><guid>https://mikhail-yudin.ru/blog/hardware/proshivka-touchscreen-ft5316/</guid><description>Началось всё с того, что мой смартфон ZOPO zp980+ как и у многих его владельцев фантомил при зарядке или перегреве. Фантомы это такие произвольные нажатия на экране, когда сам ничего не делаешь, а на смартфоне что-то делается. Это очень мешает пользоваться устройством. Поэтому полазив на форуме 4PDA решил сменить прошивку в чипе тачскрина FocalTech ft5316.
Несмотря на предостережение красным шрифтом, всё же рискнул. Прошил, перезапустил смартфон и вуаля. Что могло случиться, гарантированно случилось.</description><enclosure url="https://mikhail-yudin.ru/blog/hardware/proshivka-touchscreen-ft5316/ft5316.png" type="image/png"/><turbo:content><![CDATA[
      		<header>
      			<h1>Прошивка тачскрина ft5316</h1></header>
            <div class='entry-content'>
              <p>Началось всё с того, что мой смартфон ZOPO zp980+ как и у многих его владельцев фантомил при зарядке или перегреве. Фантомы это такие произвольные нажатия на экране, когда сам ничего не делаешь, а на смартфоне что-то делается. Это очень мешает пользоваться устройством. Поэтому полазив на форуме 4PDA решил сменить прошивку в чипе тачскрина FocalTech ft5316.</p>
<p>Несмотря на предостережение красным шрифтом, всё же рискнул. Прошил, перезапустил смартфон и вуаля. Что могло случиться, гарантированно случилось. Фантомы исчезли, а вместе с этим и тачскрин совсем перестал работать.</p>
<h2 id="просьба-о-помощи-или-источник-вдохновения">Просьба о помощи или источник вдохновения</h2>
<p>Нужно было восстанавливать, т.к. цена тачскрина была непозволительно большой: половина стоимости телефона.</p>
<p>Начал пробовать прошить разными приложениями под Android, но ничего не выходило, хоть порой и писалось, что всё ок. Но это разработчик просто не учёл, что могло и не прошиться.</p>
<p>Стоило искать другой путь. Отчаивался, пытался купить у людей, чей смартфон был в нерабочем состоянии, а тачскрин с экраном цел. Но безуспешно.</p>
<p>Обратился за помощью к уважаемому Timmnum, пользователю форума 4PDA:</p>
<blockquote>
<p>Приветствую!
Хотел узнать у Вас, что можно сделать с тачем, у меня ft5316&hellip;
Прошил чужим бинарником, в итоге определяется как 0x0, после прошивки бинарника, который до этого шился - отображает 0x7 в обоих полях.
Тест поинт (контакты 28/30) замыкал на землю как в момент перевтыкания шлейфа, так и в момент прошивки с воткнутым шлейфом. Результата не достиг.
Нашел бинарник под этот чип, тоже не ставится ни в какую.
Само устройство zp980+, видел на china-iphone под другой 980 модифицированное ядро, цианогенмод11, в котором шьется, но объединить сие для 980+ не могу, спецификация другая.
Прошу направить меня на путь истинный=)
<cite>— fagci</cite></p>
</blockquote>
<blockquote>
<p>Я бы с радостью&hellip;) Но заполучить убитый 5316 мне не удавалось.
Есть вариант прошивки через COM - UART. Но тут нужен дамп с рабочего&hellip;
<cite>— Timmnum</cite></p>
</blockquote>
<blockquote>
<p>А тот бинарник, который ранее шил, работал, его не удастся поставить через COM?..хотя затруднительно будет подпаяться к ногам..
Спасибо большое за разъяснения, попробую тоже провтыкать=)..
<cite>— fagci</cite></p>
</blockquote>
<p>Был ещё вариант - собрать из исходников CyanogenMod для zp980+, но нужно сначала найти всё нужное, местами подправить, компилить&hellip;Компилилось без остановки на ноуте дня два. В итоге не завелось и забил.</p>
<p>Далее была переписка с ув. Timmnum, оставил только ключевые моменты и вырезал сообщения Timmnum во избежание жалоб, мало ли =)</p>
<blockquote>
<p>А для нас пока и ЦМ нет&hellip; В общем, ковырять-неперековырять=))
<cite>— fagci</cite></p>
</blockquote>
<blockquote>
<p>В преобразователях, которые заказал, стоит чип cp2102, у него есть только DSR\RTS DTR\CTS&hellip;
Я себе заказал Arduino, на нем есть MISO\MOSI и SDA\SCL, как я понял, SDA это аналоговый выход.
Поэтому сдается мне, что лучше приспособить arduino для общения с контроллером.
Видел, как с помощью него можно прошить другой arduino=)
<cite>— fagci</cite></p>
</blockquote>
<blockquote>
<p>Тут недавно пришли нужные детали для коннекта к шлейфу, попробовал запитать контроллер прямо от 3.3в от переходника, чип на нем греется, померил в телефоне какое питание подходит - там 2.8в вообще..теперь непонятно, как быть с этим, может питание вообще взять как-то с тела..
А в даташите написано что operating voltage 2.8-3.6 =)
Запитал от пришедшего с breadboard адаптера питания с &ldquo;кренкой&rdquo;, на контроллере около 2.8в
<cite>— fagci</cite></p>
</blockquote>
<blockquote>
<p>Читаются только нули пока&hellip; То есть получается, ответа с контроллера нет&hellip;
<cite>— fagci</cite></p>
</blockquote>
<blockquote>
<p>С питанием вообще понять не могу=)&hellip; До этого подключал неверно, полярность попутал&hellip;
Пины шлейфа правильно промаркировал, поэтому в расположении VDDA уверен=)
Подключаю с верной полярностью, напряжение проседает до 1.3в, контроллер греется при этом
Самое странное, что при том же питании с телефона контроллер то не греется=)
<cite>— fagci</cite></p>
</blockquote>
<p>Тут уже было отчаялся совсем, но появилась надежда:</p>
<blockquote>
<p>Я ваще наоборот припаял разъем поэтому пины 1..8 = 8..1 =))
<cite>— fagci</cite></p>
</blockquote>
<blockquote>
<p>Теперь пока Device not respond.
Соединил dtr, cts напрямую к sda
Уже и через arduino при помощи такой штуки <a href="http://playground.arduino.cc/Code/I2CEEPROM">http://playground.arduino.cc/Code/I2CEEPROM</a>
читаю, данных нет, одни FF
<cite>— fagci</cite></p>
</blockquote>
<blockquote>
<p>Когда замыкал reset на землю, нули не читались, значит контроллер еще жив=))
<cite>— fagci</cite></p>
</blockquote>
<blockquote>
<p>Походу что-то не так делаю, ACK же получаю..не сгорел же=(
<cite>— fagci</cite></p>
</blockquote>
<p>Снова руки опускались, но я не сдавался!</p>
<blockquote>
<p>На данный момент имею ардуинку в режиме мастера, которая общается через I2C с контроллером.
Только вчера заюзал кастом драйвер от Paolo (для ft5316 под CM для zp980), модифицировал под arduino и не представляешь, уже читаются НЕ нули=)..и даже не то что отправлял, значит кушает=)
Осталось дело за кропотливым..переписать индусокод более тщательно, чтобы ничего не забыть, подцепить SD карточку и можно уже будет передавать прошивку.
Останется только решить проблему с памятью под прошивку, придется читать побайтово, или маленькими пачечками, а то у ардуинки не хватит места для всей=)
<cite>— fagci</cite></p>
</blockquote>
<blockquote>
<p>Питание подаю на ардуинку 3.3в, хотя надо 5..интерфейсы оказались согласованными=)
ACK до этого принимал, значит был контакт уже=)
Уже думал, что спалил тач, а оказалось, что еще надо ввести в нужный режим девайс и не обязательно использовать WAKE. Кстати, у этого контроллера INT на том же пине, что и WAKE=)
<cite>— fagci</cite></p>
</blockquote>
<blockquote>
<p>Кстати, самое странное, что WAKE не теребил вовсе. только ресет и потом чуть иначе команды шлются=)
<cite>— fagci</cite></p>
</blockquote>
<h2 id="что-получилось-в-итоге">Что получилось в итоге</h2>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:2;-o-tab-size:2;tab-size:2"><code class="language-cpp" data-lang="cpp"><span style="color:#ff79c6">#include</span> <span style="color:#ff79c6">&lt;Wire.h&gt;</span><span style="color:#ff79c6">
</span><span style="color:#ff79c6">#include</span> <span style="color:#ff79c6">&lt;SD.h&gt;</span><span style="color:#ff79c6">
</span><span style="color:#ff79c6"></span>
<span style="color:#ff79c6">#define VCC_PIN 3
</span><span style="color:#ff79c6">#define RST_PIN 2
</span><span style="color:#ff79c6">#define DEV_ADDR 0x38
</span><span style="color:#ff79c6">#define FTS_PACKET_LENGTH 2
</span><span style="color:#ff79c6"></span>
File myFile;

<span style="color:#8be9fd">void</span> <span style="color:#50fa7b">initSD</span>(){

  Serial.print(<span style="color:#f1fa8c">&#34;Initializing SD card...&#34;</span>);
  <span style="color:#6272a4">// On the Ethernet Shield, CS is pin 4. It&#39;s set as an output by default.
</span><span style="color:#6272a4"></span>  <span style="color:#6272a4">// Note that even if it&#39;s not used as the CS pin, the hardware SS pin 
</span><span style="color:#6272a4"></span>  <span style="color:#6272a4">// (10 on most Arduino boards, 53 on the Mega) must be left as an output 
</span><span style="color:#6272a4"></span>  <span style="color:#6272a4">// or the SD library functions will not work. 
</span><span style="color:#6272a4"></span>   pinMode(<span style="color:#bd93f9">10</span>, OUTPUT);
   
  <span style="color:#ff79c6">if</span> (<span style="color:#ff79c6">!</span>SD.begin(<span style="color:#bd93f9">4</span>)) {Serial.println(<span style="color:#f1fa8c">&#34;initialization failed!&#34;</span>);<span style="color:#ff79c6">return</span>;}
  Serial.println(<span style="color:#f1fa8c">&#34;initialization done.&#34;</span>);

  myFile <span style="color:#ff79c6">=</span> SD.open(<span style="color:#f1fa8c">&#34;fw.bin&#34;</span>);
  <span style="color:#ff79c6">if</span> (myFile) {
  	fts_ctpm_fw_upgrade();
    <span style="color:#6272a4">// read from the file until there&#39;s nothing else in it:
</span><span style="color:#6272a4"></span>    myFile.close();
  } <span style="color:#ff79c6">else</span> {
  	<span style="color:#6272a4">// if the file didn&#39;t open, print an error:
</span><span style="color:#6272a4"></span>    Serial.println(<span style="color:#f1fa8c">&#34;error opening&#34;</span>);
  }


}

<span style="color:#8be9fd">void</span> <span style="color:#50fa7b">setup</span>(){
	Wire.begin();
  	Serial.begin(<span style="color:#bd93f9">9600</span>);
  	init_device();
  	initSD();
  	
}

<span style="color:#8be9fd">void</span> <span style="color:#50fa7b">loop</span>(){}

<span style="color:#8be9fd">void</span> <span style="color:#50fa7b">init_device</span>() {
  pinMode(VCC_PIN, OUTPUT);
  pinMode(RST_PIN, OUTPUT);
  digitalWrite(RST_PIN, HIGH);
  digitalWrite(VCC_PIN, HIGH);
}

<span style="color:#8be9fd">int</span> <span style="color:#50fa7b">cmd_write</span>(byte <span style="color:#ff79c6">*</span>a, <span style="color:#8be9fd">int</span> n){
        Wire.beginTransmission(DEV_ADDR);
        Wire.write(a,n);
        assert(Wire.endTransmission(DEV_ADDR));
}
 
<span style="color:#8be9fd">int</span> <span style="color:#50fa7b">byte_read</span>(byte<span style="color:#ff79c6">*</span> pbt_buf, <span style="color:#8be9fd">int</span> bt_len){
        <span style="color:#8be9fd">int</span> r<span style="color:#ff79c6">=</span><span style="color:#bd93f9">0</span>;
        byte d<span style="color:#ff79c6">=</span><span style="color:#bd93f9">0xFF</span>;
        Wire.requestFrom(DEV_ADDR, bt_len);
        <span style="color:#ff79c6">while</span>(Wire.available()){
                d<span style="color:#ff79c6">=</span>Wire.read();
                pbt_buf[r]<span style="color:#ff79c6">=</span>d;
                Serial.print(d,HEX);
                r<span style="color:#ff79c6">++</span>;
        }
}

byte <span style="color:#50fa7b">i2c_smbus_read_i2c_block_data</span>(byte command, <span style="color:#8be9fd">int</span> length, byte <span style="color:#ff79c6">*</span>values)
{
	byte r<span style="color:#ff79c6">=</span><span style="color:#bd93f9">0</span>, d<span style="color:#ff79c6">=</span><span style="color:#bd93f9">0xFF</span>;
  Wire.beginTransmission(DEV_ADDR);
  Wire.write(command);
  assert(Wire.endTransmission(DEV_ADDR));
  Wire.requestFrom(DEV_ADDR, length);
  <span style="color:#ff79c6">while</span> (Wire.available()) {
  	d<span style="color:#ff79c6">=</span>Wire.read();
  	values[r]<span style="color:#ff79c6">=</span>d;
    Serial.print(d, HEX);
    r<span style="color:#ff79c6">++</span>;
  }
}
 
<span style="color:#8be9fd">void</span> <span style="color:#50fa7b">assert</span>(<span style="color:#8be9fd">int</span> e){ <span style="color:#ff79c6">if</span>(e){ Serial.print(<span style="color:#f1fa8c">&#34;[E&#34;</span>);Serial.print(e);Serial.print(<span style="color:#f1fa8c">&#34;]&#34;</span>); } }

<span style="color:#6272a4">/*
</span><span style="color:#6272a4">while (myFile.available() &amp;&amp; i++&lt;10) {
</span><span style="color:#6272a4">    	Serial.print(myFile.read(),HEX);Serial.println(&#34; &#34;);
</span><span style="color:#6272a4">    }
</span><span style="color:#6272a4">    // close the file:
</span><span style="color:#6272a4">    
</span><span style="color:#6272a4">*/</span>

boolean  <span style="color:#50fa7b">fts_ctpm_fw_upgrade</span>(<span style="color:#6272a4">/*byte* pbt_buf, unsigned int dw_lenth*/</span>){
	<span style="color:#8be9fd">unsigned</span> <span style="color:#8be9fd">int</span> dw_lenth <span style="color:#ff79c6">=</span> myFile.size();
    byte reg_val[<span style="color:#bd93f9">2</span>] <span style="color:#ff79c6">=</span> {<span style="color:#bd93f9">0</span>};
    byte tmpData[<span style="color:#bd93f9">4</span>] <span style="color:#ff79c6">=</span> {<span style="color:#bd93f9">0</span>,<span style="color:#bd93f9">0</span>,<span style="color:#bd93f9">0</span>,<span style="color:#bd93f9">0</span>};
    <span style="color:#8be9fd">unsigned</span> <span style="color:#8be9fd">int</span> i <span style="color:#ff79c6">=</span> <span style="color:#bd93f9">0</span>;
 
    <span style="color:#8be9fd">unsigned</span> <span style="color:#8be9fd">int</span>  packet_number;
    <span style="color:#8be9fd">unsigned</span> <span style="color:#8be9fd">int</span>  j;
    <span style="color:#8be9fd">unsigned</span> <span style="color:#8be9fd">int</span>  temp;
    <span style="color:#8be9fd">unsigned</span> <span style="color:#8be9fd">int</span>  lenght;
    byte  packet_buf[FTS_PACKET_LENGTH <span style="color:#ff79c6">+</span> <span style="color:#bd93f9">6</span>];
    byte  auc_i2c_write_buf[<span style="color:#bd93f9">10</span>];
    byte bt_ecc;
    <span style="color:#8be9fd">int</span> i_ret;
        <span style="color:#8be9fd">int</span> ret;
        <span style="color:#8be9fd">unsigned</span> <span style="color:#8be9fd">char</span> ver;
 
    <span style="color:#6272a4">/*********Step 1:Reset  CTPM *****/</span>
        pinMode(RST_PIN, OUTPUT);
    digitalWrite(RST_PIN, LOW);  
    delay(<span style="color:#bd93f9">10</span>);  
    pinMode(RST_PIN, OUTPUT);
    digitalWrite(RST_PIN, HIGH);
    Serial.println(<span style="color:#f1fa8c">&#34;[TSP] Step 1: Reset CTPM test&#34;</span>);
   
    delay(<span style="color:#bd93f9">50</span>);  
    <span style="color:#6272a4">/*********Step 2:Enter upgrade mode *****/</span>
    auc_i2c_write_buf[<span style="color:#bd93f9">0</span>] <span style="color:#ff79c6">=</span> <span style="color:#bd93f9">0x55</span>;
    auc_i2c_write_buf[<span style="color:#bd93f9">1</span>] <span style="color:#ff79c6">=</span> <span style="color:#bd93f9">0xaa</span>;
    <span style="color:#ff79c6">do</span>{
        i <span style="color:#ff79c6">++</span>;
        i_ret <span style="color:#ff79c6">=</span> cmd_write(auc_i2c_write_buf, <span style="color:#bd93f9">2</span>);
        delay(<span style="color:#bd93f9">5</span>);
    }<span style="color:#ff79c6">while</span>(i_ret <span style="color:#ff79c6">&lt;=</span> <span style="color:#bd93f9">0</span> <span style="color:#ff79c6">&amp;&amp;</span> i <span style="color:#ff79c6">&lt;</span> <span style="color:#bd93f9">5</span> );
    Serial.println(<span style="color:#f1fa8c">&#34;[TSP] Step 2: Enter upgrade mode&#34;</span>);
 
    <span style="color:#6272a4">/*********Step 3:check READ-ID***********************/</span>
    tmpData[<span style="color:#bd93f9">0</span>]<span style="color:#ff79c6">=</span><span style="color:#bd93f9">0x90</span>;
    cmd_write(tmpData,<span style="color:#bd93f9">4</span>);
        i<span style="color:#ff79c6">=</span><span style="color:#bd93f9">0</span>;
        i_ret<span style="color:#ff79c6">=</span><span style="color:#bd93f9">0</span>;
    <span style="color:#ff79c6">do</span>{
        i <span style="color:#ff79c6">++</span>;
        i_ret <span style="color:#ff79c6">=</span> byte_read(reg_val,<span style="color:#bd93f9">2</span>);
        delay(<span style="color:#bd93f9">10</span>);
    }<span style="color:#ff79c6">while</span>(i_ret <span style="color:#ff79c6">&lt;=</span> <span style="color:#bd93f9">0</span> <span style="color:#ff79c6">&amp;&amp;</span> i <span style="color:#ff79c6">&lt;</span> <span style="color:#bd93f9">5</span> );
    Serial.print(<span style="color:#f1fa8c">&#34;[TSP] Step 3: check ID: &#34;</span>);
    Serial.print(reg_val[<span style="color:#bd93f9">0</span>],HEX);
    Serial.print(<span style="color:#f1fa8c">&#34;, &#34;</span>);
    Serial.print(reg_val[<span style="color:#bd93f9">1</span>],HEX);
        Serial.println(<span style="color:#f1fa8c">&#34; &#34;</span>);
 
    <span style="color:#6272a4">/*********Step 4:erase app*******************************/</span>
    tmpData[<span style="color:#bd93f9">0</span>]<span style="color:#ff79c6">=</span><span style="color:#bd93f9">0x61</span>;
    ret <span style="color:#ff79c6">=</span> cmd_write(tmpData,<span style="color:#bd93f9">1</span>);
   
    delay(<span style="color:#bd93f9">1500</span>);
    Serial.print(<span style="color:#f1fa8c">&#34;[TSP] Step 4: erase.ret=&#34;</span>);
        Serial.print(ret);
        Serial.println(<span style="color:#f1fa8c">&#34; &#34;</span>);
 
    <span style="color:#6272a4">/*********Step 5:write firmware(FW) to ctpm flash*********/</span>
    bt_ecc <span style="color:#ff79c6">=</span> <span style="color:#bd93f9">0</span>;
        Serial.println(<span style="color:#f1fa8c">&#34;[TSP] Step 5: start upgrade.&#34;</span>);
    dw_lenth <span style="color:#ff79c6">=</span> dw_lenth <span style="color:#ff79c6">-</span> <span style="color:#bd93f9">8</span>;
    packet_number <span style="color:#ff79c6">=</span> (dw_lenth) <span style="color:#ff79c6">/</span> FTS_PACKET_LENGTH;
    packet_buf[<span style="color:#bd93f9">0</span>] <span style="color:#ff79c6">=</span> <span style="color:#bd93f9">0xbf</span>;
    packet_buf[<span style="color:#bd93f9">1</span>] <span style="color:#ff79c6">=</span> <span style="color:#bd93f9">0x00</span>;
    <span style="color:#ff79c6">for</span> (j<span style="color:#ff79c6">=</span><span style="color:#bd93f9">0</span>;j<span style="color:#ff79c6">&lt;</span>packet_number;j<span style="color:#ff79c6">++</span>){
        temp <span style="color:#ff79c6">=</span> j <span style="color:#ff79c6">*</span> FTS_PACKET_LENGTH;
        packet_buf[<span style="color:#bd93f9">2</span>] <span style="color:#ff79c6">=</span> (byte)(temp<span style="color:#ff79c6">&gt;&gt;</span><span style="color:#bd93f9">8</span>);
        packet_buf[<span style="color:#bd93f9">3</span>] <span style="color:#ff79c6">=</span> (byte)temp;
        lenght <span style="color:#ff79c6">=</span> FTS_PACKET_LENGTH;
        packet_buf[<span style="color:#bd93f9">4</span>] <span style="color:#ff79c6">=</span> (byte)(lenght<span style="color:#ff79c6">&gt;&gt;</span><span style="color:#bd93f9">8</span>);
        packet_buf[<span style="color:#bd93f9">5</span>] <span style="color:#ff79c6">=</span> (byte)lenght;
 
        <span style="color:#ff79c6">for</span> (i<span style="color:#ff79c6">=</span><span style="color:#bd93f9">0</span>;i<span style="color:#ff79c6">&lt;</span>FTS_PACKET_LENGTH;i<span style="color:#ff79c6">++</span>){
        	myFile.seek(j<span style="color:#ff79c6">*</span>FTS_PACKET_LENGTH <span style="color:#ff79c6">+</span> i);
            packet_buf[<span style="color:#bd93f9">6</span><span style="color:#ff79c6">+</span>i] <span style="color:#ff79c6">=</span> myFile.read();
            bt_ecc <span style="color:#ff79c6">^=</span> packet_buf[<span style="color:#bd93f9">6</span><span style="color:#ff79c6">+</span>i];
        }
       
        ret<span style="color:#ff79c6">=</span>cmd_write( <span style="color:#ff79c6">&amp;</span>packet_buf[<span style="color:#bd93f9">0</span>],FTS_PACKET_LENGTH <span style="color:#ff79c6">+</span> <span style="color:#bd93f9">6</span>);
        <span style="color:#ff79c6">if</span> ((j <span style="color:#ff79c6">*</span> FTS_PACKET_LENGTH <span style="color:#ff79c6">%</span> <span style="color:#bd93f9">1024</span>) <span style="color:#ff79c6">==</span> <span style="color:#bd93f9">0</span>){
              Serial.print(<span style="color:#f1fa8c">&#34;[TSP] upgrade the 0x&#34;</span>);
              Serial.print(((<span style="color:#8be9fd">unsigned</span> <span style="color:#8be9fd">int</span>)j) <span style="color:#ff79c6">*</span> FTS_PACKET_LENGTH);
              Serial.println(<span style="color:#f1fa8c">&#34; th byte.&#34;</span>);
        }
    }
 
    <span style="color:#ff79c6">if</span> ((dw_lenth) <span style="color:#ff79c6">%</span> FTS_PACKET_LENGTH <span style="color:#ff79c6">&gt;</span> <span style="color:#bd93f9">0</span>){
        temp <span style="color:#ff79c6">=</span> packet_number <span style="color:#ff79c6">*</span> FTS_PACKET_LENGTH;
        packet_buf[<span style="color:#bd93f9">2</span>] <span style="color:#ff79c6">=</span> (byte)(temp<span style="color:#ff79c6">&gt;&gt;</span><span style="color:#bd93f9">8</span>);
        packet_buf[<span style="color:#bd93f9">3</span>] <span style="color:#ff79c6">=</span> (byte)temp;
 
        temp <span style="color:#ff79c6">=</span> (dw_lenth) <span style="color:#ff79c6">%</span> FTS_PACKET_LENGTH;
        packet_buf[<span style="color:#bd93f9">4</span>] <span style="color:#ff79c6">=</span> (byte)(temp<span style="color:#ff79c6">&gt;&gt;</span><span style="color:#bd93f9">8</span>);
        packet_buf[<span style="color:#bd93f9">5</span>] <span style="color:#ff79c6">=</span> (byte)temp;
 
        <span style="color:#ff79c6">for</span> (i<span style="color:#ff79c6">=</span><span style="color:#bd93f9">0</span>;i<span style="color:#ff79c6">&lt;</span>temp;i<span style="color:#ff79c6">++</span>){
        	myFile.seek(packet_number<span style="color:#ff79c6">*</span>FTS_PACKET_LENGTH <span style="color:#ff79c6">+</span> i);
            packet_buf[<span style="color:#bd93f9">6</span><span style="color:#ff79c6">+</span>i] <span style="color:#ff79c6">=</span> myFile.read();
            bt_ecc <span style="color:#ff79c6">^=</span> packet_buf[<span style="color:#bd93f9">6</span><span style="color:#ff79c6">+</span>i];
        }
             <span style="color:#6272a4">// printk(&#34;[TSP]temp 0x%x \n&#34;, temp);
</span><span style="color:#6272a4"></span>        ret <span style="color:#ff79c6">=</span> cmd_write( <span style="color:#ff79c6">&amp;</span>packet_buf[<span style="color:#bd93f9">0</span>],temp<span style="color:#ff79c6">+</span><span style="color:#bd93f9">6</span>);    
              <span style="color:#6272a4">//printk(&#34;[TSP] 222 ret 0x%x \n&#34;, ret);
</span><span style="color:#6272a4"></span>        delay(<span style="color:#bd93f9">20</span>);
    }
 
    <span style="color:#6272a4">//send the last six byte
</span><span style="color:#6272a4"></span>    <span style="color:#ff79c6">for</span> (i <span style="color:#ff79c6">=</span> <span style="color:#bd93f9">0</span>; i<span style="color:#ff79c6">&lt;</span><span style="color:#bd93f9">6</span>; i<span style="color:#ff79c6">++</span>){
        temp <span style="color:#ff79c6">=</span> <span style="color:#bd93f9">0x6ffa</span> <span style="color:#ff79c6">+</span> i;
        packet_buf[<span style="color:#bd93f9">2</span>] <span style="color:#ff79c6">=</span> (byte)(temp<span style="color:#ff79c6">&gt;&gt;</span><span style="color:#bd93f9">8</span>);
        packet_buf[<span style="color:#bd93f9">3</span>] <span style="color:#ff79c6">=</span> (byte)temp;
        temp <span style="color:#ff79c6">=</span><span style="color:#bd93f9">1</span>;
        packet_buf[<span style="color:#bd93f9">4</span>] <span style="color:#ff79c6">=</span> (byte)(temp<span style="color:#ff79c6">&gt;&gt;</span><span style="color:#bd93f9">8</span>);
        packet_buf[<span style="color:#bd93f9">5</span>] <span style="color:#ff79c6">=</span> (byte)temp;
        myFile.seek(dw_lenth <span style="color:#ff79c6">+</span> i);
        packet_buf[<span style="color:#bd93f9">6</span>] <span style="color:#ff79c6">=</span> myFile.read();

        bt_ecc <span style="color:#ff79c6">^=</span> packet_buf[<span style="color:#bd93f9">6</span>];
 
        cmd_write(<span style="color:#ff79c6">&amp;</span>packet_buf[<span style="color:#bd93f9">0</span>],<span style="color:#bd93f9">7</span>);  
        delay(<span style="color:#bd93f9">20</span>);
    }
 
    <span style="color:#6272a4">/*********Step 6: read out checksum***********************/</span>
 
    i2c_smbus_read_i2c_block_data(<span style="color:#bd93f9">0xcc</span>, <span style="color:#bd93f9">1</span>, <span style="color:#ff79c6">&amp;</span>(reg_val[<span style="color:#bd93f9">0</span>]));
    Serial.print(<span style="color:#f1fa8c">&#34;[TSP] Step 6:  ecc read 0x&#34;</span>);
    Serial.print(reg_val[<span style="color:#bd93f9">0</span>]);
    Serial.print(<span style="color:#f1fa8c">&#34;, new firmware 0x&#34;</span>);
    Serial.print(bt_ecc);
    Serial.println(<span style="color:#f1fa8c">&#34;.&#34;</span>);
    <span style="color:#ff79c6">if</span>(reg_val[<span style="color:#bd93f9">0</span>] <span style="color:#ff79c6">!=</span> bt_ecc){
        <span style="color:#6272a4">//return ERR_ECC;
</span><span style="color:#6272a4"></span>    }
 
    <span style="color:#6272a4">/*********Step 7: reset the new FW***********************/</span>
    pinMode(RST_PIN, OUTPUT);
    digitalWrite(RST_PIN, LOW);  
    delay(<span style="color:#bd93f9">1</span>);  
    pinMode(RST_PIN, OUTPUT);
    digitalWrite(RST_PIN, HIGH);
 
    <span style="color:#ff79c6">return</span> <span style="color:#8be9fd;font-style:italic">true</span>;
}
</code></pre></div><p>Больше так делать не буду. Возможно =)</p>
<p>С этого я получил несколько важных уроков:</p>
<ul>
<li>никогда нельзя опускать руки, особенно когда кажется, что все методы перепробованы;</li>
<li>если хоть кто-нибудь говорит на форумах, что бесполезно искать решение — не поддаваться;</li>
<li>всё можно сделать самому, важно верить в свои силы, даже когда их нет!</li>
</ul>
<p>Всем, кому пригодится данный материал, желаю успехов в восстановлении и чтобы ничего не ломалось, а только улучшалось. А если и ломается, то восстанавливалось! Это бесценный опыт.</p>

            </div>
      	]]></turbo:content></item><item turbo="true"><title>STM32f103 ADC with DMA</title><link>https://mikhail-yudin.ru/blog/hardware/stm32f103-adc-with-dma/</link><pubDate>Sun, 13 Mar 2016 00:00:00 +0000</pubDate><guid>https://mikhail-yudin.ru/blog/hardware/stm32f103-adc-with-dma/</guid><description>Having troubles with STM32f103 ADC using DMA, solved by introducing timer for external triggering.
Video:
Here is working source:
#include &amp;#34;adc.h&amp;#34; #define ADC_DATA_SIZE 320 #define ADC_PERIOD (SystemCoreClock / 1000) / 2 #define ADCx ADC1 #define ADC_Channel_n ADC_Channel_7 #define RCC_APBnPeriph_ADCx RCC_APB2Periph_ADC1 #define ADC_RCC_APBnPeriphClockCmd RCC_APB2PeriphClockCmd #define ADC_ExternalTrigConv_Tn_trigger ADC_ExternalTrigConv_T3_TRGO #define GPIOx GPIOA #define GPIO_Pin_n GPIO_Pin_7 #define RCC_APBnPeriph_GPIOx RCC_APB2Periph_GPIOA #define GPIO_RCC_APBnPeriphClockCmd RCC_APB2PeriphClockCmd #define TIMx TIM3 #define TIM_RCC_APBnPeriphClockCmd RCC_APB1PeriphClockCmd #define RCC_APBnPeriph_TIMx RCC_APB1Periph_TIM3 #define DMAn_Channeln_IRQn DMA1_Channel1_IRQn #define DMAn_IT_TCn DMA1_IT_TC1 #define DMAn_Channeln DMA1_Channel1 #define RCC_AHBPeriph_DMAn RCC_AHBPeriph_DMA1 static u16 adcDmaData[ADC_DATA_SIZE]; u16 *ADC_getData() { return adcDmaData; } void timer_config(void) { TIM_TimeBaseInitTypeDef tim; TIM_RCC_APBnPeriphClockCmd(RCC_APBnPeriph_TIMx, ENABLE); /* Time base configuration */ TIM_TimeBaseStructInit(&amp;amp;tim); tim.</description><enclosure url="https://mikhail-yudin.ru/blog/hardware/stm32f103-adc-with-dma/stm32f103-adc-with-dma.png" type="image/png"/><turbo:content><![CDATA[
      		<header>
      			<h1>STM32f103 ADC with DMA</h1></header>
            <div class='entry-content'>
              <p>Having troubles with STM32f103 ADC using DMA, solved by introducing timer for external triggering.</p>
<p>Video:</p>
<iframe width="100%" height="315" src="https://www.youtube.com/embed/h16B7YAlttY" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
<p>Here is working source:</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:2;-o-tab-size:2;tab-size:2"><code class="language-cpp" data-lang="cpp"><span style="color:#ff79c6">#include</span> <span style="color:#ff79c6">&#34;adc.h&#34;</span><span style="color:#ff79c6">
</span><span style="color:#ff79c6"></span>
<span style="color:#ff79c6">#define ADC_DATA_SIZE 320
</span><span style="color:#ff79c6"></span>
<span style="color:#ff79c6">#define ADC_PERIOD (SystemCoreClock / 1000) / 2
</span><span style="color:#ff79c6"></span>
<span style="color:#ff79c6">#define ADCx ADC1
</span><span style="color:#ff79c6">#define ADC_Channel_n ADC_Channel_7
</span><span style="color:#ff79c6">#define RCC_APBnPeriph_ADCx RCC_APB2Periph_ADC1
</span><span style="color:#ff79c6">#define ADC_RCC_APBnPeriphClockCmd RCC_APB2PeriphClockCmd
</span><span style="color:#ff79c6">#define ADC_ExternalTrigConv_Tn_trigger ADC_ExternalTrigConv_T3_TRGO
</span><span style="color:#ff79c6"></span>
<span style="color:#ff79c6">#define GPIOx GPIOA
</span><span style="color:#ff79c6">#define GPIO_Pin_n GPIO_Pin_7
</span><span style="color:#ff79c6">#define RCC_APBnPeriph_GPIOx RCC_APB2Periph_GPIOA
</span><span style="color:#ff79c6">#define GPIO_RCC_APBnPeriphClockCmd RCC_APB2PeriphClockCmd
</span><span style="color:#ff79c6"></span>
<span style="color:#ff79c6">#define TIMx TIM3
</span><span style="color:#ff79c6">#define TIM_RCC_APBnPeriphClockCmd RCC_APB1PeriphClockCmd
</span><span style="color:#ff79c6">#define RCC_APBnPeriph_TIMx RCC_APB1Periph_TIM3
</span><span style="color:#ff79c6"></span>
<span style="color:#ff79c6">#define DMAn_Channeln_IRQn DMA1_Channel1_IRQn
</span><span style="color:#ff79c6">#define DMAn_IT_TCn DMA1_IT_TC1
</span><span style="color:#ff79c6">#define DMAn_Channeln DMA1_Channel1
</span><span style="color:#ff79c6">#define RCC_AHBPeriph_DMAn RCC_AHBPeriph_DMA1
</span><span style="color:#ff79c6"></span>
<span style="color:#ff79c6">static</span> u16 adcDmaData[ADC_DATA_SIZE];

u16 <span style="color:#ff79c6">*</span><span style="color:#50fa7b">ADC_getData</span>() { <span style="color:#ff79c6">return</span> adcDmaData; }

<span style="color:#8be9fd">void</span> <span style="color:#50fa7b">timer_config</span>(<span style="color:#8be9fd">void</span>) {
  TIM_TimeBaseInitTypeDef tim;
  TIM_RCC_APBnPeriphClockCmd(RCC_APBnPeriph_TIMx, ENABLE);

  <span style="color:#6272a4">/* Time base configuration */</span>
  TIM_TimeBaseStructInit(<span style="color:#ff79c6">&amp;</span>tim);
  tim.TIM_Period <span style="color:#ff79c6">=</span> (u16)(ADC_PERIOD <span style="color:#ff79c6">/</span> <span style="color:#bd93f9">125</span> <span style="color:#ff79c6">-</span> <span style="color:#bd93f9">1</span>);  <span style="color:#6272a4">// 875 - 1;
</span><span style="color:#6272a4"></span>  tim.TIM_Prescaler <span style="color:#ff79c6">=</span> <span style="color:#bd93f9">0</span>;
  tim.TIM_ClockDivision <span style="color:#ff79c6">=</span> <span style="color:#bd93f9">0</span>;
  tim.TIM_CounterMode <span style="color:#ff79c6">=</span> TIM_CounterMode_Up;
  TIM_TimeBaseInit(TIMx, <span style="color:#ff79c6">&amp;</span>tim);

  TIM_SelectOutputTrigger(TIMx, TIM_TRGOSource_Update);
}

<span style="color:#8be9fd">void</span> <span style="color:#50fa7b">timer_start</span>(<span style="color:#8be9fd">void</span>) { TIM_Cmd(TIMx, ENABLE); }

<span style="color:#8be9fd">void</span> <span style="color:#50fa7b">timer_stop</span>(<span style="color:#8be9fd">void</span>) { TIM_Cmd(TIMx, DISABLE); }

<span style="color:#8be9fd">void</span> <span style="color:#50fa7b">dma_init</span>() {
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMAn, ENABLE);
  <span style="color:#6272a4">// DMA
</span><span style="color:#6272a4"></span>  DMA_InitTypeDef dma;
  DMA_StructInit(<span style="color:#ff79c6">&amp;</span>dma);

  dma.DMA_BufferSize <span style="color:#ff79c6">=</span> ADC_DATA_SIZE;
  dma.DMA_MemoryBaseAddr <span style="color:#ff79c6">=</span> (u32)adcDmaData;
  dma.DMA_PeripheralBaseAddr <span style="color:#ff79c6">=</span> (u32) <span style="color:#ff79c6">&amp;</span> (ADCx<span style="color:#ff79c6">-&gt;</span>DR);
  dma.DMA_Mode <span style="color:#ff79c6">=</span> DMA_Mode_Circular;
  dma.DMA_Priority <span style="color:#ff79c6">=</span> DMA_Priority_High;
  dma.DMA_MemoryInc <span style="color:#ff79c6">=</span> DMA_MemoryInc_Enable;
  dma.DMA_MemoryDataSize <span style="color:#ff79c6">=</span> DMA_MemoryDataSize_HalfWord;
  dma.DMA_PeripheralDataSize <span style="color:#ff79c6">=</span> DMA_PeripheralDataSize_HalfWord;
  DMA_Init(DMAn_Channeln, <span style="color:#ff79c6">&amp;</span>dma);

  NVIC_EnableIRQ(DMAn_Channeln_IRQn);
  DMA_ITConfig(DMAn_Channeln, DMA_IT_TC, ENABLE);
  DMA_Cmd(DMAn_Channeln, ENABLE);
}

<span style="color:#8be9fd">void</span> <span style="color:#50fa7b">gpio_init</span>() {
  GPIO_RCC_APBnPeriphClockCmd(RCC_APBnPeriph_GPIOx, ENABLE);

  GPIO_InitTypeDef gpio;
  gpio.GPIO_Speed <span style="color:#ff79c6">=</span> GPIO_Speed_50MHz;
  gpio.GPIO_Pin <span style="color:#ff79c6">=</span> GPIO_Pin_n;
  gpio.GPIO_Mode <span style="color:#ff79c6">=</span> GPIO_Mode_AIN;
  GPIO_Init(GPIOx, <span style="color:#ff79c6">&amp;</span>gpio);
}

<span style="color:#8be9fd">void</span> <span style="color:#50fa7b">adc_init</span>() {
  <span style="color:#6272a4">// clock for ADC (max 14MHz --&gt; 72/6=12MHz)
</span><span style="color:#6272a4"></span>  <span style="color:#6272a4">// TODO: check for maximum clock
</span><span style="color:#6272a4"></span>  <span style="color:#6272a4">// RCC_ADCCLKConfig(RCC_PCLK2_Div2);
</span><span style="color:#6272a4"></span>  ADC_RCC_APBnPeriphClockCmd(RCC_APBnPeriph_ADCx, ENABLE);

  <span style="color:#6272a4">// ADC
</span><span style="color:#6272a4"></span>  ADC_InitTypeDef adc;
  adc.ADC_ScanConvMode <span style="color:#ff79c6">=</span> DISABLE;
  adc.ADC_ContinuousConvMode <span style="color:#ff79c6">=</span> DISABLE;
  adc.ADC_ExternalTrigConv <span style="color:#ff79c6">=</span> ADC_ExternalTrigConv_Tn_trigger;
  adc.ADC_DataAlign <span style="color:#ff79c6">=</span> ADC_DataAlign_Right;
  adc.ADC_Mode <span style="color:#ff79c6">=</span> ADC_Mode_Independent;
  adc.ADC_NbrOfChannel <span style="color:#ff79c6">=</span> <span style="color:#bd93f9">1</span>;
  ADC_Init(ADCx, <span style="color:#ff79c6">&amp;</span>adc);

  ADC_RegularChannelConfig(ADCx, ADC_Channel_n, <span style="color:#bd93f9">1</span>, ADC_SampleTime_1Cycles5);

  ADC_Cmd(ADCx, ENABLE);  <span style="color:#6272a4">// enable ADCx
</span><span style="color:#6272a4"></span>
  <span style="color:#6272a4">// Calibration
</span><span style="color:#6272a4"></span>  ADC_ResetCalibration(ADCx);  <span style="color:#6272a4">// Reset previous calibration
</span><span style="color:#6272a4"></span>  <span style="color:#ff79c6">while</span> (ADC_GetResetCalibrationStatus(ADCx))
    ;
  ADC_StartCalibration(
      ADCx);  <span style="color:#6272a4">// Start new calibration (ADC must be off at that time)
</span><span style="color:#6272a4"></span>  <span style="color:#ff79c6">while</span> (ADC_GetCalibrationStatus(ADCx))
    ;

  ADC_ExternalTrigConvCmd(ADCx, ENABLE);
  ADC_DMACmd(ADCx, ENABLE);
  ADC_Cmd(ADCx, ENABLE);
}

<span style="color:#8be9fd">void</span> <span style="color:#50fa7b">ADC_init</span>() {
  gpio_init();
  dma_init();
  adc_init();
  timer_config();
  timer_start();
}

<span style="color:#ff79c6">static</span> u8 dataAvailable <span style="color:#ff79c6">=</span> <span style="color:#bd93f9">0</span>;

<span style="color:#ff79c6">inline</span> u8 <span style="color:#50fa7b">isDataAvailable</span>() { <span style="color:#ff79c6">return</span> dataAvailable; }

<span style="color:#ff79c6">inline</span> <span style="color:#8be9fd">void</span> <span style="color:#50fa7b">markDataUsed</span>() {
  dataAvailable <span style="color:#ff79c6">=</span> <span style="color:#bd93f9">0</span>;
  timer_start();
}

<span style="color:#8be9fd">void</span> <span style="color:#50fa7b">DMA1_Channel1_IRQHandler</span>(<span style="color:#8be9fd">void</span>) {
  <span style="color:#ff79c6">if</span> (DMA_GetITStatus(DMAn_IT_TCn) <span style="color:#ff79c6">==</span> SET) {
    <span style="color:#6272a4">//        DMA_Cmd(DMA1_Channel1, DISABLE);
</span><span style="color:#6272a4"></span>    DMA_ClearITPendingBit(DMAn_IT_TCn);
    timer_stop();
    dataAvailable <span style="color:#ff79c6">=</span> <span style="color:#bd93f9">1</span>;
  }
}
</code></pre></div>
            </div>
      	]]></turbo:content></item><item turbo="true"><title>STM32 ILI9341 SPI with DMA</title><link>https://mikhail-yudin.ru/blog/hardware/stm32-ili9341-spi-with-dma/</link><pubDate>Mon, 22 Feb 2016 00:00:00 +0000</pubDate><guid>https://mikhail-yudin.ru/blog/hardware/stm32-ili9341-spi-with-dma/</guid><description>Долго возился с подключением DMA на STM32f103, в итоге удалось завести следующим образом:
u8 dmaWorking = 0; DMA_InitTypeDef dma8, dma16; void dmaInit() { RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); // DMA 8bit DMA_StructInit(&amp;amp;dma8); dma8.DMA_PeripheralBaseAddr = (u32) &amp;amp; (SPI1-&amp;gt;DR); dma8.DMA_DIR = DMA_DIR_PeripheralDST; dma8.DMA_MemoryInc = DMA_MemoryInc_Enable; dma8.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; dma8.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; dma8.DMA_Priority = DMA_Priority_High; // DMA 16bit DMA_StructInit(&amp;amp;dma16); dma16.DMA_PeripheralBaseAddr = (u32) &amp;amp; (SPI1-&amp;gt;DR); dma16.DMA_DIR = DMA_DIR_PeripheralDST; dma16.DMA_MemoryInc = DMA_MemoryInc_Enable; dma16.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; dma16.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; dma16.</description><enclosure url="https://mikhail-yudin.ru/blog/hardware/stm32-ili9341-spi-with-dma/stm32-ili9341-spi-with-dma.jpg" type="image/jpeg"/><turbo:content><![CDATA[
      		<header>
      			<h1>STM32 ILI9341 SPI with DMA</h1></header>
            <div class='entry-content'>
              <p>Долго возился с подключением DMA на STM32f103, в итоге удалось завести следующим образом:</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:2;-o-tab-size:2;tab-size:2"><code class="language-cpp" data-lang="cpp">u8 dmaWorking <span style="color:#ff79c6">=</span> <span style="color:#bd93f9">0</span>;
DMA_InitTypeDef dma8, dma16;

<span style="color:#8be9fd">void</span> <span style="color:#50fa7b">dmaInit</span>() {
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

  <span style="color:#6272a4">// DMA 8bit
</span><span style="color:#6272a4"></span>  DMA_StructInit(<span style="color:#ff79c6">&amp;</span>dma8);
  dma8.DMA_PeripheralBaseAddr <span style="color:#ff79c6">=</span> (u32) <span style="color:#ff79c6">&amp;</span> (SPI1<span style="color:#ff79c6">-&gt;</span>DR);
  dma8.DMA_DIR <span style="color:#ff79c6">=</span> DMA_DIR_PeripheralDST;
  dma8.DMA_MemoryInc <span style="color:#ff79c6">=</span> DMA_MemoryInc_Enable;
  dma8.DMA_PeripheralDataSize <span style="color:#ff79c6">=</span> DMA_PeripheralDataSize_Byte;
  dma8.DMA_MemoryDataSize <span style="color:#ff79c6">=</span> DMA_MemoryDataSize_Byte;
  dma8.DMA_Priority <span style="color:#ff79c6">=</span> DMA_Priority_High;

  <span style="color:#6272a4">// DMA 16bit
</span><span style="color:#6272a4"></span>  DMA_StructInit(<span style="color:#ff79c6">&amp;</span>dma16);
  dma16.DMA_PeripheralBaseAddr <span style="color:#ff79c6">=</span> (u32) <span style="color:#ff79c6">&amp;</span> (SPI1<span style="color:#ff79c6">-&gt;</span>DR);
  dma16.DMA_DIR <span style="color:#ff79c6">=</span> DMA_DIR_PeripheralDST;
  dma16.DMA_MemoryInc <span style="color:#ff79c6">=</span> DMA_MemoryInc_Enable;
  dma16.DMA_PeripheralDataSize <span style="color:#ff79c6">=</span> DMA_PeripheralDataSize_HalfWord;
  dma16.DMA_MemoryDataSize <span style="color:#ff79c6">=</span> DMA_MemoryDataSize_HalfWord;
  dma16.DMA_Priority <span style="color:#ff79c6">=</span> DMA_Priority_High;

  <span style="color:#6272a4">// IRQs
</span><span style="color:#6272a4"></span>  NVIC_EnableIRQ(DMA1_Channel3_IRQn);
  DMA_ITConfig(DMA1_Channel3, DMA_IT_TC, ENABLE);
  SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Tx, ENABLE);
}

<span style="color:#8be9fd">void</span> <span style="color:#50fa7b">dmaSend</span>(u8 <span style="color:#ff79c6">*</span>data, u32 n) {
  dma8.DMA_MemoryBaseAddr <span style="color:#ff79c6">=</span> (u32)data;
  dma8.DMA_BufferSize <span style="color:#ff79c6">=</span> n;
  DMA_Init(DMA1_Channel3, <span style="color:#ff79c6">&amp;</span>dma8);
  dmaWorking <span style="color:#ff79c6">=</span> <span style="color:#bd93f9">1</span>;
  TFT_CS_RESET;
  DMA_Cmd(DMA1_Channel3, ENABLE);
}

<span style="color:#8be9fd">void</span> <span style="color:#50fa7b">dmaSend16</span>(u16 <span style="color:#ff79c6">*</span>data, u16 n) {
  dma16.DMA_MemoryBaseAddr <span style="color:#ff79c6">=</span> (u32)data;
  dma16.DMA_BufferSize <span style="color:#ff79c6">=</span> n;
  DMA_Init(DMA1_Channel3, <span style="color:#ff79c6">&amp;</span>dma16);
  dmaWorking <span style="color:#ff79c6">=</span> <span style="color:#bd93f9">1</span>;
  TFT_CS_RESET;
  DMA_Cmd(DMA1_Channel3, ENABLE);
}

<span style="color:#ff79c6">#define dmaWait()    \
</span><span style="color:#ff79c6">  while (dmaWorking) \
</span><span style="color:#ff79c6">    ;
</span><span style="color:#ff79c6"></span>
<span style="color:#8be9fd">void</span> <span style="color:#50fa7b">dmaSendData8</span>(u8 <span style="color:#ff79c6">*</span>data, u16 n) {
  TFT_DC_SET;
  dmaSend(data, n);
  dmaWait();
}

<span style="color:#8be9fd">void</span> <span style="color:#50fa7b">dmaSendData16</span>(u16 <span style="color:#ff79c6">*</span>data, u16 n) {
  TFT_DC_SET;
  dmaSend16(data, n);
  dmaWait();
}

<span style="color:#6272a4">// TX
</span><span style="color:#6272a4"></span><span style="color:#8be9fd">void</span> <span style="color:#50fa7b">DMA1_Channel3_IRQHandler</span>(<span style="color:#8be9fd">void</span>) {
  <span style="color:#ff79c6">if</span> (DMA_GetITStatus(DMA1_IT_TC3)) {
    DMA_ClearITPendingBit(DMA1_IT_TC3);
    DMA_Cmd(DMA1_Channel3, DISABLE);
    TFT_CS_SET;
    dmaWorking <span style="color:#ff79c6">=</span> <span style="color:#bd93f9">0</span>;
  }
}

<span style="color:#8be9fd">void</span> <span style="color:#50fa7b">dmaSendCmd</span>(u8 cmd) {
  TFT_DC_RESET;
  dmaSend(<span style="color:#ff79c6">&amp;</span>cmd, <span style="color:#bd93f9">1</span>);
  dmaWait();
}
</code></pre></div><p>Видео примера работы:</p>
<iframe width="100%" height="315" src="https://www.youtube.com/embed/-2-tuqgc90k" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
<p>ссылка на библиотеку: <a href="https://github.com/fagci/stm-ILI9341-spi" target=_blank rel="noopener noreferrer">Github</a></p>

            </div>
      	]]></turbo:content></item></channel></rss>