roboforum.ru

Технический форум по робототехнике.


RootAdmin - заметки

Блоги посетителей.
Правила форума
В данном разделе каждый может иметь не более одной темы. Тема должна начинаться с логина (ника) робофорума.

Re: RootAdmin - заметки

Сообщение RootAdmin » 11 дек 2012, 17:36

У меня сын родился. :)
Дым, идущий из всех устройств в помещении предвещает появление электрика.
RootAdmin
 
Сообщения: 1725
Зарегистрирован: 07 авг 2010, 21:29
Откуда: КМВ
прог. языки: C
ФИО: Андрей

Re: RootAdmin - заметки

Сообщение Dmitry__ » 11 дек 2012, 17:42

Гы, паздравлям!!!
Аватара пользователя
Dmitry__
 
Сообщения: 8033
Зарегистрирован: 13 янв 2011, 15:25
Откуда: Санкт-Петербург

Re: RootAdmin - заметки

Сообщение elmot » 11 дек 2012, 17:54

Поздравлямс!
Аватара пользователя
elmot
 
Сообщения: 5691
Зарегистрирован: 10 ноя 2011, 12:02
Откуда: Turku, Finland
Skype: elmot73
прог. языки: Java и все-все=все
ФИО: Илья

Re: RootAdmin - заметки

Сообщение RootAdmin » 11 дек 2012, 18:07

elmot писал(а):Поздравлямс!
Dmitry__ писал(а):Гы, паздравлям!!!

Благодарю! Вот сижу со старшим дома - даже на форум не хожу. :)
Дым, идущий из всех устройств в помещении предвещает появление электрика.
RootAdmin
 
Сообщения: 1725
Зарегистрирован: 07 авг 2010, 21:29
Откуда: КМВ
прог. языки: C
ФИО: Андрей

Re: RootAdmin - заметки

Сообщение RootAdmin » 14 янв 2014, 11:32

Установка ROS под Debian на CubieBoard
Пакет collada-dom-dev собрал, чтобы обойти требование пакета sbcl
идем в ros_catkin_ws
и делаем
Код: Выделить всёРазвернуть
cd src
wstool rm roslisp
rm -rf roslisp
cd ..

Ибо он нужен только для roslisp

Забавно то, что при загрузке с sd карточки надо в скрипте прописывать включение питания на SATA.
sata_power_en = port:PB08<1><default><default><0>
При загрузке с nand - оно включено сразу.

Для того чтоб собирался qt_gui_cpp
надо удалить shiboken и shiboken-dev иначе падает в сегфаулт.
Пришлось включить в список источников sid
Поставить liblapack3

Плюнул, залил через LiveSuite Ubuntu

Чтоб перенести ее на карту надо
http://www.mediafire.com/download/v2888 ... th-spl.bin



Данный метод не работает.

# To switch VGA/HDMI display mode in command line. e.g.
$ cb-display-tool -o 8 -m 11
# Note: can switch to the same resolutions only currently.
А вот если изменить script.fex

[disp_init]
disp_init_enable = 1
disp_mode = 0
screen0_output_type = 4
screen0_output_mode = 4
screen1_output_type = 2
screen1_output_mode = 14
То все работает.

Обязательно добавляем себя в нужные группы, иначе сокеты - недоступны.

Взлетело.
Иксы однако нужны будут apt-get install --no-install-recommends ubuntu-desktop
apt-get install gnome-session-fallback
Дым, идущий из всех устройств в помещении предвещает появление электрика.
RootAdmin
 
Сообщения: 1725
Зарегистрирован: 07 авг 2010, 21:29
Откуда: КМВ
прог. языки: C
ФИО: Андрей

Сообщение RootAdmin » 01 фев 2014, 17:57

Проектор GP1 (ака GP_2, gp2 и прочие)
Хорошее описание http://cheshirca.livejournal.com/44278.html
Купил этот девайс с год назад. Был удивлен тем, что переходник VGA - нестандартный разъем проектора надо покупать отдельно. И в продаже нет.
Ладно, поигрался - отложил. Сегодня достал, взял VGA кабель, откусил один разъем. Подпаял 7 BLS коннекторов "мам" на плату проектора, на кабель VGS - "папы". Ибо курение даташита на микросхему MST6M182VG позволило только определить RGB по сопротивлению на землю 72-77 ом.
Синхронизацию определял методом тыка.
Итак, разъем VGA от IR-приемника:
1 - NC
2 - GND
3 - B
4 - GND
5 - G
6 - GND
7 - R
8 - GND
9 - NC
10 - GND
11 - Hsync
12 - GND
13 - Vsync
14 - GND
15 - NC
16 - GND
17 - Bit0
18 - Bit1
Дым, идущий из всех устройств в помещении предвещает появление электрика.
RootAdmin
 
Сообщения: 1725
Зарегистрирован: 07 авг 2010, 21:29
Откуда: КМВ
прог. языки: C
ФИО: Андрей

Re: RootAdmin - заметки

Сообщение RootAdmin » 20 фев 2014, 17:57

Для получения "облака точек" планирую использовать примитивную идею
Дальномер.jpg

Логика работы: берем кадр. Включаем лазер (светит горизонтальной линией) и берем еще кадр.
Вычитаем первый из второго - остается в основном лазер.
Набросал на ардуинке код, воспринимающий команды включить-выключить лазер и повернуть шаговик.
Код: Выделить всёРазвернуть

/*
Управление лазером и шаговиком для дальномера.
*/
#define StepFreq 250 //Частота шагов зеркала в герцах
#define motor_X_pin_1 8
#define motor_X_pin_2 9
#define motor_X_pin_3 10
#define motor_X_pin_4 11
#define laserpin 7
#define PosSensor 6
#define PosVCC 5 //Питание для светодиода сенсора
#define PosGND 4 //Земля для светодиода сенсора

int led = 13;
int ii=0;
int id=0;
int inByte[]={0,0,0,0,0,0,0,0};         // Для принятых байтов
volatile int CountByte = 0;         // Счетчик принятых
int countwrong=0; //Счетчик неверных длин команд

int MotorPins[] = {motor_X_pin_1, motor_X_pin_2, motor_X_pin_3, motor_X_pin_4};


volatile byte curstep=0; //Текущий "шаг" включения обмоток
volatile byte MOTstep=0; //Текущий шаг мотора
volatile byte USTstep=0; //Заданный шаг мотора
unsigned char timerLoadValue; //Количестов "начальных" тиков таймера

void setup() {               
  // initialize the digital pin as an output.
  pinMode(led, OUTPUT);

  pinMode(motor_X_pin_1, OUTPUT);
  pinMode(motor_X_pin_2, OUTPUT);
  pinMode(motor_X_pin_3, OUTPUT);
  pinMode(motor_X_pin_4, OUTPUT);
  pinMode(laserpin, OUTPUT);
  pinMode(PosSensor, INPUT);
  digitalWrite(PosSensor, HIGH); //Подтянем вход датчика вверх

  pinMode(PosGND, OUTPUT);
  digitalWrite(PosGND, LOW); //поставим ноль питанию датчика
  pinMode(PosVCC, OUTPUT);
  digitalWrite(PosVCC, HIGH); //поставим единицу (запитаем датчик)
 
    Serial.begin(9600);
   
  //Запускает таймер и получает загружаемое значение таймера.
timerLoadValue=SetupTimer2(StepFreq); //Параметр - частота, Шагов в секунду. Двигатель и больше может...
//Выводит загружаемое значение таймера
  Serial.print("Timer2 Load:");
  Serial.println(timerLoadValue,HEX);

}

// the loop routine runs over and over again forever:
void loop()
{
 
if  (digitalRead(PosSensor)) {digitalWrite(led, HIGH);}
  for (int i=0; i<20; i++)
  {
  //  Serial.println (i);
  //  Serial.println (CountByte);
  //  delay(100);               // wait for a second
    if (i==1) //Секция отладки
    {
      id++;
      if (id>31000)
      {
        id=0;
      digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
      Serial.print ("A_");
      Serial.print (ii);
      Serial.println ("      ");
   //     Serial.print ("CB=");
   //     Serial.println (CountByte);
       /* Serial.print ("InByte=");
        Serial.write (inByte[0]);
        Serial.write (inByte[1]);
        Serial.write (inByte[2]);
        Serial.write (inByte[3]);
        //Если первый символ=S тогда следующие два - номер шага
        //Serial.println();
        */
        ii++;
      //delay(1);               // wait for a second
      digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
   //   delay(50);               // wait for a second
      }
    }


   
   if (CountByte>2)
   {
        CountByte=0;
        //Если первый символ=S тогда следующие два - номер шага
        //Serial.println();
       // Serial.println(inByte[0]);
        if (inByte[0]==83) //83 - код "S"
        {
              Serial.write ("Kom S");
              if (inByte[1]==48) //48 - код "0"
              {//stepMotor(0);
              USTstep--;
              Serial.println ("0 ok");}
              if (inByte[1]==49) //49 - код "1"
              {//stepMotor(1);
              USTstep++;
              Serial.println ("1 ok");}
             
        }
        if (inByte[0]==76) //76 - код "L"
        {
              Serial.println (i);
              Serial.write ("Kom L");
              if (inByte[1]==48) //48 - код "0"
              {digitalWrite(laserpin, LOW);
              Serial.println ("0 ok");}
              if (inByte[1]==49) //49 - код "1"
              {digitalWrite(laserpin, HIGH);
              Serial.println ("1 ok"); }
         }
        if (inByte[0]==77) //77 - код "M"
        {
              Serial.write ("Kom M");
              USTstep=inByte[1]; //Ставим нужный шаг
              Serial.print (USTstep);
              Serial.println (" ok");
         }
        if (inByte[0]==82) //82 - код "R" Начальное позиционирование - дописать
        {
              Serial.write ("Kom R");
              ZeroPos();
              Serial.println (" ok");
         }
    }
 
}
   //   Разберемся с "потерянными" командами
   if (CountByte) //Если в буфере есть что-то
    {
      countwrong++; //Увеличиваем счетчик
    }
    else
    {countwrong=0;}
    if (countwrong>500)//Если это что-то (типа 1 байт) больше 500 циклов
    {
      Serial.println ("CountWrong!");
      countwrong=0;
      CountByte=0;
    }
   
}



void serialEvent() {
//Serial.write ("Event0");
  if (Serial.available()) {
    digitalWrite(led, HIGH);
   //Serial.write ("Event1");
    // get the new byte:
    inByte[CountByte] = Serial.read();
    // if the incoming character is a newline, set a flag
    // so the main loop can do something about it:
    if (inByte[CountByte] == 10) {// '\n', новая строка
      CountByte=3;
         //Serial.write ("EndString!");
         //Serial.write ("EndL!");
    }
    else{    CountByte++;}
  }
}




void stepMotor( int Step) // Step 0 или +1
{
//Serial.println(curstep[Motor]);
int i; //Сдвиг для номеров пинов мотора
  if (Step)
   {
//      Serial.println("StepMotor Step=1");
     if (curstep==3)
     {curstep=0;}
    else
     {curstep++;}
   }
  else
  {
//    Serial.println("StepMotor Step=0");
    if (curstep==0)
     {curstep=3;}
    else
      {curstep--;}
   }
   
   switch (curstep) { //переделать, убрать массив с ногами моторов, аменить на дефиненные
      case 0:    // 1000
      digitalWrite(MotorPins[0], HIGH);
      digitalWrite(MotorPins[1], LOW);
      digitalWrite(MotorPins[2], LOW);
      digitalWrite(MotorPins[3], LOW);
      break;
     case 1:    // 0010
      digitalWrite(MotorPins[0], LOW);
      digitalWrite(MotorPins[1], LOW);
      digitalWrite(MotorPins[2], HIGH);
      digitalWrite(MotorPins[3], LOW);
      break;
     case 2:    // 0100
      digitalWrite(MotorPins[0], LOW);
      digitalWrite(MotorPins[1], HIGH);
      digitalWrite(MotorPins[2], LOW);
      digitalWrite(MotorPins[3], LOW);
      break;
     case 3:    // 0001
      digitalWrite(MotorPins[0], LOW);
      digitalWrite(MotorPins[1], LOW);
      digitalWrite(MotorPins[2], LOW);
      digitalWrite(MotorPins[3], HIGH);
      break;

  }
}



#define TIMER_CLOCK_FREQ 15625.0
//15625 for /1024
//2MHz for /8 prescale from 16MHz
//Установка Таймера2.
//Конфигурирует 8-битный Таймер2 ATMega168 для выработки прерывания
//с заданной частотой.
//Возвращает начальное значение таймера, которое должно быть загружено в TCNT2
//внутри вашей процедуры ISR.
//Смотри пример использования ниже.
unsigned char SetupTimer2(float timeoutFrequency)
{
  unsigned char result; //Начальное значение таймера.
  //Подсчет начального значения таймера
  result=(int)((257.0-(TIMER_CLOCK_FREQ/timeoutFrequency))+0.5);
  //257 на самом деле должно быть 256, но я получил лучшие результаты с 257.
   
  //Установки Таймер2: Делитель частоты /8, режим 0
  //Частота = 16MHz/1024 = 15625 герц или 64 мкс
  //Делитель /1024 дает нам хороший рабочий диапазон
  //так что сейчас мы просто жестко запрограммируем это.
  TCCR2A = 0;
  //TCCR2B = 0<<CS22 | 1<<CS21 | 0<<CS20; //это на 8
  TCCR2B = 7;
   
  //Подключение прерывания по переполнению Timer2
  TIMSK2 = 1<<TOIE2;
  //загружает таймер для первого цикла
  TCNT2=result;
  return(result); //значение (начальное) счетчика.
}


//Timer2 указатель вектора прерывания по переполнению
ISR(TIMER2_OVF_vect) {

  if (MOTstep>USTstep)
    {
      stepMotor(0);
      MOTstep--;
    }
  if (MOTstep<USTstep)
    {
      stepMotor(1);
      MOTstep++;
    }
/*TestPerem++;
if (TestPerem>80){
  //Переключение IO-вывода в другое состояние.
  digitalWrite(TOGGLE_IO,!digitalRead(TOGGLE_IO));
  TestPerem=0;
}

//Захват текущего значения таймера. Это величина ошибки
//из-за задержки обработки прерывания и работы этой функции
int latency=TCNT2;

//Перезагрузка таймера и коррекция по задержке
//TCNT2=latency+timerLoadValue;
*/
TCNT2=timerLoadValue;
}


void ZeroPos() //калибровка шаговика
{
  USTstep=0; //Уставка - ноль
  Serial.print ("Reset ");
  while(digitalRead(PosSensor)) //До срабатывания датчика - шагать
  {
    MOTstep=1;
  }
  Serial.println ("OK");
}




Шагов ~230
IMG_20140325_102419.jpg
Механика

Надо писать программу.
Дым, идущий из всех устройств в помещении предвещает появление электрика.
RootAdmin
 
Сообщения: 1725
Зарегистрирован: 07 авг 2010, 21:29
Откуда: КМВ
прог. языки: C
ФИО: Андрей

Re: RootAdmin - заметки

Сообщение RootAdmin » 25 мар 2014, 10:53

Кадр с лазером.png
Пример кадра
Дым, идущий из всех устройств в помещении предвещает появление электрика.
RootAdmin
 
Сообщения: 1725
Зарегистрирован: 07 авг 2010, 21:29
Откуда: КМВ
прог. языки: C
ФИО: Андрей

Re: RootAdmin - заметки

Сообщение RootAdmin » 11 фев 2015, 17:55

Сдох у меня видеорегистратор автомобильный. Как сдох - запускается, даже показать изображение с камеры пытается, а дальше - места на экране, куда выводится служебная информация заполняются мусором. Грушу на прошивку, которая сидит в флешке 25Q80SCP. Прошивку нашел, но чем шить? LPT все, нету. Недолго погуглил - нашел замечательную вещь,https://github.com/nfd/spi-flash-programmer
Готовый программатор SPI флеш на ардуине. Только питон поставил - вроде уже читается...

Добавлено спустя 3 минуты 27 секунд:
Код: Выделить всёРазвернуть
C:\Temp\ProgSPI>C:\Python34\python.exe spi_flash_programmer_client.py -d com3 --flash-offset 0 -s 1024 -f dump.bin read
1048320 of 1048576
C:\Temp\ProgSPI>C:\Python34\python.exe spi_flash_programmer_client.py -d com3 --flash-offset 0 -s 1024 -f dump.bin verify
Verifying dump.bin with flash start 0 and file start 0
1048576
Прочиталось, даже проверка прошла удачно!
Причем флешку подключал к ардуинке напрямую, даже без резисторов. Только питание на нее (флешку) подал 3.3 вольта.

Добавлено спустя 48 минут 26 секунд:
Нда, а при попытке записи - ошибка. Причем питон я не знаю, а ошибка ИМХО в нем. :)

Добавлено спустя 1 час 55 минут 45 секунд:
Если ручками выполняю в консоли ардуины команды на чтение-запись то все работает. по крайней мере несколько блоков.

Добавлено спустя 16 минут 12 секунд:
Нет, скорее всего чип битый. :(

Добавлено спустя 1 минуту 19 секунд:
Каждые 6 страниц - ошибка.

Добавлено спустя 14 минут 2 секунды:
Не 6 а 16. Нда, чип однозначно дохлый. Причем при стирании - все байты FF. А пишется в них (в некоторые) мусор. Видно некоторые биты глючат.
Дым, идущий из всех устройств в помещении предвещает появление электрика.
RootAdmin
 
Сообщения: 1725
Зарегистрирован: 07 авг 2010, 21:29
Откуда: КМВ
прог. языки: C
ФИО: Андрей

Re: RootAdmin - заметки

Сообщение Dmitry__ » 11 фев 2015, 19:45

А данные от камеры в эту флеш пишутся? Сколько записей отработала примерно?
Аватара пользователя
Dmitry__
 
Сообщения: 8033
Зарегистрирован: 13 янв 2011, 15:25
Откуда: Санкт-Петербург

Re: RootAdmin - заметки

Сообщение RootAdmin » 12 фев 2015, 10:34

Нет, там только программа и настройки. Так что запись довольно редко происходит. Видео пишется на сд карту.
Дым, идущий из всех устройств в помещении предвещает появление электрика.
RootAdmin
 
Сообщения: 1725
Зарегистрирован: 07 авг 2010, 21:29
Откуда: КМВ
прог. языки: C
ФИО: Андрей

Re: RootAdmin - заметки

Сообщение RootAdmin » 02 апр 2015, 14:44

Кому надо прошить на скорую руку SPI флеш - сюда.
Починил видеорегистратор. Заодно поправил "прошивочный скетч ардуины, добавил задержку при стирании блока. И ралочку чипа (команда "u" в порт).
Компилится под IDE 1.5.x, под 1.6 - ругается на PROGMEM, лень разобраться.
Код: Выделить всёРазвернуть
 
#include <avr\pgmspace.h>
//#include "C:\Work\arduino-1.6.1\hardware\arduino\sam\cores\arduino\avr\pgmspace.h"

#define DATAOUT 11//MOSI
#define DATAIN  12//MISO
#define SPICLOCK  13//sck
#define SLAVESELECT 10//ss

//opcodes
#define WREN  6
#define WRDI  4
#define RDSR  5
#define WRSR  1
#define READ  3
#define WRITE 2
#define SECTOR_ERASE 0x20
#define CHIP_ERASE 0xC7

byte buffer [256];

/* // Via http://excamera.com/sphinx/article-crc.html
static PROGMEM prog_uint32_t crc_table[16] = {
    0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac,
    0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
    0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c,
    0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c
};
*/

  prog_uint32_t crc_table[16] PROGMEM = {
    0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac,
    0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
    0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c,
    0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c
};

unsigned long crc_update(unsigned long crc, byte data)
{
    byte tbl_idx;
    tbl_idx = crc ^ (data >> (0 * 4));
    crc = pgm_read_dword_near(crc_table + (tbl_idx & 0x0f)) ^ (crc >> 4);
    tbl_idx = crc ^ (data >> (1 * 4));
    crc = pgm_read_dword_near(crc_table + (tbl_idx & 0x0f)) ^ (crc >> 4);
    return crc;
}

unsigned long crc_buffer(void)
{
  unsigned long crc = ~0L;
  for(int i=0; i < 256; i++)
    crc = crc_update(crc, buffer[i]);
  crc = ~crc;
  return crc;
}

void setup()
{
  Serial.begin(115200);

  pinMode(DATAOUT, OUTPUT);
  pinMode(DATAIN, INPUT);
  pinMode(SPICLOCK,OUTPUT);
  pinMode(SLAVESELECT,OUTPUT);
   
  digitalWrite(SLAVESELECT,HIGH); //disable device
  // SPCR = 01010000
  //interrupt disabled,spi enabled,msb 1st,master,clk low when idle,
  //sample on leading edge of clk,system clock/4 rate (fastest)
  //SPCR = (1<<SPE)|(1<<MSTR);
  SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPI2X);
 
  byte clr;
  clr=SPSR;
  clr=SPDR;
 
  delay(10);

  buffer[0] = 0xca;
  buffer[1] = 0xfe;   
 
 

/*                digitalWrite(SLAVESELECT,LOW); //Выбираем чип
                delay(20);
                spi_transfer(1); //Регистр статуса на запись
                delay(20);
                spi_transfer(0); //Запись в регистр
                //spi_transfer(0); //Запрос статуса (регистра)
                delay(20);
                Serial.println(spi_transfer(0xff));
                delay(20);
              digitalWrite(SLAVESELECT,HIGH); //release chip, signal end transfer
*/   
 
 
 
 
}

void loop()
{
  byte addr1, addr2;
 
  while(Serial.available() == 0)
    ;

  int cmd = Serial.read();
 
  switch(cmd) {
  case '>':
    Serial.print('>');
    break;
  case 'e':
    erase_all();
    break;
  case 'r':
    addr1 = read_hex();
    addr2 = read_hex();
    read_page(addr1, addr2);
    break;
  case 'w':
    addr1 = read_hex();
    addr2 = read_hex();
    write_page(addr1, addr2);
    break;
  case 'd':
    dump_buffer();
    break;
  case 'c':
    dump_buffer_crc();
    break;
  case 'l':
    load_buffer();
    break;
  case 's':
    addr1 = read_hex();
    addr2 = read_nybble() << 4;
    erase_sector(addr1, addr2);
    break;
  case '?':
  case 'h':
    Serial.println("\nSPI Flash programmer");
    Serial.println(" e    : erase chip");
    Serial.println(" sXXX : erase 4k sector XXX (hex)");
    Serial.println(" c    : print buffer CRC-32");
    Serial.println(" rXXXX: read 256-byte page XXXX (hex) to buffer");
    Serial.println(" wXXXX: write buffer to 256-byte page XXXX (hex)");
    Serial.println(" d    : display the buffer (in hex)");
    Serial.println(" l<b> : load the buffer with <b>, where b is 256 bytes of data");
    Serial.println();
    Serial.println("Ex: r3700 - read 256 bytes from page 0x3700");
    Serial.println("Ex: lcafe[...]3737 - load the buffer with 256 bytes, first byte 0xca...");
    break;
 
    case 't':
    int counter;
    Serial.println("Testing");
    read_page(0, 0);
    Serial.println("Read 1");
    dump_buffer();
//    erase_sector(0, 0);
    for(counter = 0; counter < 256; counter++)
    {
    buffer[counter] = 0x55;
    }
    dump_buffer();
    write_page(0, 0);
    Serial.println("Writing");
        for(counter = 0; counter < 256; counter++)
    {
    buffer[counter] = 0x11;
    }
    read_page(0, 0);
    Serial.println("Read 2");
    dump_buffer();
      //READ EEPROM
   break;
    case 'u':
    digitalWrite(SLAVESELECT,LOW); //Выбираем чип
    spi_transfer(5); //Запрос статуса (регистра)
    Serial.print("Status=");
    Serial.println(spi_transfer(0xff));
    delay(20);
    digitalWrite(SLAVESELECT,HIGH); //release chip, signal end transfer
    delay(20);
    digitalWrite(SLAVESELECT,LOW); //Выбираем чип
    delay(20);
    spi_transfer(1); //Регистр статуса на запись
    delay(20);
    spi_transfer(0); //Запись в регистр
    delay(20);
    Serial.println(spi_transfer(0xff));
    delay(20);
  digitalWrite(SLAVESELECT,HIGH); //release chip, signal end transfer
   
    break;
  }

 
  Serial.flush();
}

void dump_buffer()
{
  int counter;
 
  for(counter = 0; counter < 256; counter++) {
    Serial.print(buffer[counter] >> 4, HEX);
    Serial.print(buffer[counter] & 0xF, HEX);
  }
  Serial.println();
}

void dump_buffer_crc()
{
  unsigned long crc = crc_buffer();
  Serial.print(crc_buffer(), HEX);
  Serial.println();
}

void load_buffer()
{
  int counter;
  for(counter = 0; counter < 256; counter++) {
    buffer[counter] = read_hex();
  }
}

byte read_nybble()
{
  int nybble;
  while((nybble = Serial.read()) == -1)
    ;
 
  if(nybble >= 'A') {
    // works for lowercase as well (but no range checking of course)
    return 9 + (nybble & 0x0f);
  } else {
    return nybble & 0x0f;
  }
}

byte read_hex()
{
  byte val;
 
  val = (read_nybble() & 0xf) << 4;
  val |= read_nybble();
 
  return val;
}

byte spi_transfer(volatile char data)
{
  SPDR = data;                    // Start the transmission
  while (!(SPSR & (1<<SPIF)))     // Wait for the end of the transmission
  {
  };
  return SPDR;                    // return the received byte
}

void
read_page(byte adr1, byte adr2)
{
  //READ EEPROM
  int counter;
  digitalWrite(SLAVESELECT,LOW);
  spi_transfer(READ);
  spi_transfer(adr1); // bits 23 to 16
  spi_transfer(adr2); // bits 15 to 8
  spi_transfer(0);    // bits 7 to 0
  for(counter = 0; counter < 256; counter++) {
    buffer[counter] = spi_transfer(0xff);
  }
  digitalWrite(SLAVESELECT,HIGH); //release chip, signal end transfer
}

void wait_for_write()
{
  byte statreg = 0x1;
 
  while((statreg & 0x1) == 0x1) {
    // Wait for the chip.
    digitalWrite(SLAVESELECT, LOW);
    spi_transfer(RDSR);
    statreg = spi_transfer(RDSR);
    digitalWrite(SLAVESELECT, HIGH);
  } 
}

void
write_page(byte adr1, byte adr2)
{
  int counter;
 
  digitalWrite(SLAVESELECT,LOW);
  delay(2);
  spi_transfer(WREN); //write enable
  digitalWrite(SLAVESELECT,HIGH);
  delay(2);

  digitalWrite(SLAVESELECT,LOW);
  delay(1);
  spi_transfer(WRITE); //write instruction
  spi_transfer(adr1); // bits 23 to 16
  spi_transfer(adr2); // bits 15 to 8
  spi_transfer(0);    // bits 7 to 0

  for (counter = 0; counter < 256; counter++)
  {
    spi_transfer(buffer[counter]);
    //  delay(1);
  }
   delay(2);
  digitalWrite(SLAVESELECT,HIGH);
  delay(5);
 
  wait_for_write();
}

void
erase_all()
{
  int counter;
 
  digitalWrite(SLAVESELECT,LOW);
  spi_transfer(WREN); //write enable
  digitalWrite(SLAVESELECT,HIGH);
  delay(10);

  digitalWrite(SLAVESELECT,LOW);
  Serial.println(" e : erase chip start");
  spi_transfer(CHIP_ERASE);
  delay(1000);
  digitalWrite(SLAVESELECT,HIGH);
  delay(1);
 
  wait_for_write();
  Serial.println(" e : erase chip end");
}

void
erase_sector(byte addr1, byte addr2)
{
  digitalWrite(SLAVESELECT,LOW);
  delay(12);
  spi_transfer(WREN);
  delay(12);
  digitalWrite(SLAVESELECT,HIGH);
  delay(12);
 
  digitalWrite(SLAVESELECT,LOW);
  spi_transfer(SECTOR_ERASE);
  spi_transfer(addr1);
  spi_transfer(addr2);
  spi_transfer(0);
  delay(82);
  digitalWrite(SLAVESELECT,HIGH);
  delay(62);
}

А то китаец прислал чипы, но в них было прошито что-то, похожее на фирмварь электронной книги. И часть флешки - запрещена на запись. Пришлось курить мануал.
А флешки новые, непаяные. С завода упер, что-ли?
Заодно чуть подправил питоновский скрипт прошивочный.

spi_flash_programmer_client.py
Код: Выделить всёРазвернуть
import time
import serial
import argparse
import binascii
import sys

MAX_SIZE = 16 * 1024 * 1024
SECTOR_SIZE = 4096

class NoResponse(Exception):
   pass

def decodeHex(hexBytes):
   return binascii.unhexlify(hexBytes)

def encodeHex(data):
   return binascii.hexlify(data)

class SerialChatChat:
   def __init__(self, filename):
      self.sock = serial.Serial(filename, 115200, timeout=1)
      # Wait for the Arduino bootloader
      time.sleep(2)
   
   def _readCRC(self):
      crc = b''
      self.sock.flushInput()
      self.sock.write(b'c')
      while not crc.endswith(b'\r\n'):
         crc += self.sock.read(1)

      return int(crc, 16)

   def _readPageOnce(self, page):
      # Reads page, returns CRC
      cmd = 'r%02x%02x' % ((page & 0xff00) >> 8, (page & 0xff))
      self.sock.write(cmd.encode('iso-8859-1'))
      self.sock.flush()
      return self._readCRC()

   def _readPageMultiple(self, page):
      # Keep reading until we get two pages reads the same.
      crc = [self._readPageOnce(page), self._readPageOnce(page)]
      count = 0
      while crc[0] != crc[1] and count < 3:
         print("Retrying read of page %d" % (page))
         crc.pop(0)
         crc.append(self._readPageOnce(page))
         count += 1

      if crc[0] != crc[1]:
         #raise Exception()
         print("CRC if error")
      
      return crc[1]

   def readPage(self, page):
      self._readPageMultiple(page)
   
      # Dump the buffer.
      self.sock.write(b'd')

      result = []
      amt_read = 0
      while amt_read < 512:
         fromChip = self.sock.read(512 - amt_read)
         amt_read += len(fromChip)
         result.append(fromChip)

      result = b''.join(result)
      assert len(result) == 512, len(result)
      return decodeHex(result)

   def writePage(self, page, data):
      # Write the page and verify that it was written correctly.
      expectedCRC = binascii.crc32(data)

      data = encodeHex(data)
      assert len(data) == 512, (len(data), data)

      self.sock.write(b'l' + data)
      self.waitReady()

      # This shouldn't fail if we're using a reliable connection.
      if self._readCRC() != expectedCRC:
         print("CRC error")
         raise Exception()

      # Write it, read it back, fail if we can't read what we wrote.
      cmd = 'w%02x%02x' % ((page & 0xff00) >> 8, (page & 0xff))
      self.sock.write(cmd.encode('iso-8859-1'))
      self.sock.flush()
      self.waitReady()

      writtenCRC = self._readPageMultiple(page)
      if writtenCRC != expectedCRC:
         print("CRC error verify")
         ###print("written CRC", writtenCRC, "expected CRC", expectedCRC, page, data)
         print("written CRC", writtenCRC, "expected CRC", expectedCRC, page)
      
      return writtenCRC == expectedCRC
      #return 1

   def waitReady(self, seconds_to_wait=5):
      self.sock.flushInput()
      self.sock.write(b'>')
      self.sock.flush()

      for retry in range(seconds_to_wait):
         data = self.sock.read(1)
         if data == b'>':
            break
         elif data:
            print('unexpected', data)
      else:
         raise NoResponse()
   
   def verify(self, filename, flashStartByte=0, fileStartByte=0):
      assert flashStartByte % 256 == 0
      assert fileStartByte % 256 == 0
      idx = flashStartByte
      print("Verifying %s with flash start %d and file start %d" % (filename, flashStartByte, fileStartByte))
      with open(filename, 'rb') as h:
         h.seek(fileStartByte)
         while True:
            sys.stdout.write('\r%d' % (idx))
            sys.stdout.flush()

            fromFile = h.read(256)
            if fromFile == b'':
               break
            assert len(fromFile) == 256, len(fromFile)
            fileCRC = binascii.crc32(fromFile)

            for retry in range(3):
               deviceCRC = self._readPageOnce(idx // 256)
               if deviceCRC != fileCRC:
                  print("Mismatch %x != %x, retrying" % (deviceCRC, fileCRC))
               else:
                  break
            else:
               raise Exception("Mismatch")

            idx += 256

   def eraseSector(self, sectorNumber):
      cmd = 's%03x' % (sectorNumber)
      self.sock.write(cmd.encode('iso-8859-1'))
      self.waitReady()

   def _writeSectorOnce(self, byteOffset, sectorData):
      assert byteOffset % SECTOR_SIZE == 0
      assert len(sectorData) == SECTOR_SIZE
      pageData = []
      for idx in range(0, SECTOR_SIZE, 256):
         pageData.append(sectorData[idx:idx+256])

      pageOffset = byteOffset // 256
      
      expectedCRCs = [binascii.crc32(page) for page in pageData]
      actualCRCs   = [self._readPageMultiple(pageOffset + idx) for idx in range(SECTOR_SIZE // 256)]

      if expectedCRCs != actualCRCs:
         self.eraseSector(byteOffset // SECTOR_SIZE)

      for idx, page in enumerate(pageData):
         if not self.writePage(pageOffset + idx, page):
            return False

      return True

   def writeFile(self, filename, offset=0):
      with open(filename, 'rb') as h:
         data = h.read(MAX_SIZE)

      print('Writing', filename, 'at', offset)

      for idx in range(0, len(data), SECTOR_SIZE):
         sys.stdout.write('\r%d of %d' % (idx, len(data)))
         sys.stdout.flush()

         pageData = data[idx:idx + SECTOR_SIZE]
         assert len(pageData) == SECTOR_SIZE

         for retry in range(144):
            if self._writeSectorOnce(offset + idx, pageData):
               break
            else:
               print("Retrying")
         else:
            print("Error control of write")
            #raise Exception()

   def readToFile(self, filename, size, flashStartByte):
      assert size % 256 == 0

      assert flashStartByte % 256 == 0
      flashStartPage = flashStartByte // 256

      with open(filename, 'wb') as handle:
         for idx in range(0, size, 256):
            sys.stdout.write('\r%d of %d' % (idx, size))
            sys.stdout.flush()

            page = idx // 256

            pageData = self.readPage(page + flashStartPage)
            handle.write(pageData)
   
def main():
   parser = argparse.ArgumentParser(description="Interface with an Arduino-based SPI flash programmer")
   parser.add_argument('-f', dest='filename')
   parser.add_argument('-d', dest='device', default='/dev/tty.usbserial-A700ekGi')
   parser.add_argument('-s', dest='size', default='4096', help="size in KB")
   parser.add_argument('--flash-offset', dest='flash_offset', default='0', help='offset for flash read/write in bytes')
   parser.add_argument('--file-offset', dest='file_offset', default='0', help='offset for file read/write in bytes')
   parser.add_argument('command', choices=('write', 'read', 'verify'))
   args = parser.parse_args()

   chat = SerialChatChat(args.device)
   if args.command=='write':
      chat.writeFile(args.filename, int(args.flash_offset))
   elif args.command=='read':
      chat.readToFile(args.filename, int(args.size) * 1024, int(args.flash_offset))
   elif args.command=='verify':
      chat.verify(args.filename, int(args.flash_offset), int(args.file_offset))
   else:
      raise NotImplementedError()

if __name__ == '__main__':
   main()


Фирмварь к регистратору из скачанных с инета подошла первая ж. Дольше искал - куда ж я батарейку от него сунул, когда разбирал.
Дым, идущий из всех устройств в помещении предвещает появление электрика.
RootAdmin
 
Сообщения: 1725
Зарегистрирован: 07 авг 2010, 21:29
Откуда: КМВ
прог. языки: C
ФИО: Андрей

Re: RootAdmin - заметки

Сообщение RootAdmin » 11 июн 2015, 15:50

Кто б знал что из phpvirtualbox при создании машины "по шаблону" в конфиге ставится <IOAPIC enabled="true"/>
А при создании командой без указания шаблона <IOAPIC enabled="false"/>
Дым, идущий из всех устройств в помещении предвещает появление электрика.
RootAdmin
 
Сообщения: 1725
Зарегистрирован: 07 авг 2010, 21:29
Откуда: КМВ
прог. языки: C
ФИО: Андрей

Re: RootAdmin - заметки

Сообщение RootAdmin » 09 май 2018, 19:20

Эх, когда ж я научусь красивый код писать, без костылей.
Код: Выделить всёРазвернуть
void flash_str_toip(uint8_t *srcstr, uint8_t *outstr) //на входе строка разделенная точками ("192.168.100.25"), на выходе - массив 4 байта
{
   //Идея в чем? Берем указатель на "." (точку) в строке.
   uint8_t *ptr0=srcstr; // указатель на строку
   for (uint8_t i=0;i<4;i++)
   {
   outstr[i]=atoi(ptr0);
   ptr0=strstr(ptr0,"."); //Возвращает указатель на следующий символ "." в строке
   *ptr0++;
   }
   outstr[4]=0; //вообще так как мы знаем что это то можно и не ограничивать массив (строку)
}
Дым, идущий из всех устройств в помещении предвещает появление электрика.
RootAdmin
 
Сообщения: 1725
Зарегистрирован: 07 авг 2010, 21:29
Откуда: КМВ
прог. языки: C
ФИО: Андрей

Пред.

Вернуться в Блоги

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 10