А вы его компилировать пробовали? В ардуино ИДЕ?
Извините, компилируется, мой косяк, криво скопировал/вставил
А вы его компилировать пробовали? В ардуино ИДЕ?
Извините, компилируется, мой косяк, криво скопировал/вставил
Блин, тут просто детская, школьная ошибка в адресной арифметике! Зачем рассказывать про то, что где-то такое работает?
void my_func(uint32_t *para, size_t para_num) {
uint8_t regval;
for(uint8_t i=0; i<para_num; i++) {
regval = *(uint8_t *)para;
Serial.print(regval, HEX);
Serial.println("\r");
para++;
}
В строке #7 Вы увеличиваете на 1 указатель на uint32_t
. На сколько но, по Вашему, численно увеличится? На 4! Вот Вы это и кушаете с маслом.
Сделайте правильно и “забудьте о перхоти”
void my_func(uint32_t *para, size_t para_num) {
const uint8_t * bPara = reinterpret_cast<const uint8_t *>(para);
// можно и как Вы делаете
// const uint8_t * bPara = (const uint8_t *) para;
// но так, как я написал - лучше
for(uint8_t i=0; i<para_num; i++) {
const uint8_t regval = bPara[i];
Serial.println(regval, HEX);
}
}
Он не в обратном порядке выводит, а с шагом в 4 байта. Первое значение, потом пятое, а затем просто по не пойми какой памяти проезжаетесь, и там нули с единицей.
У вас в коде проблемы из-за плохой работы с типами, а из-за нее - с указателями. Я же вам выше написал.
Компилятор вас предупреждает, как может.
Уберите void *, уберите unsigned long *, оставьте везде unsigned char, ну или uint8_t. Вы работаете с байтами, не нужны вам эти кошмарные преобразования типов кругом. С преобразованиями типов впрямую надо быть аккуратным:
void setup() {
Serial.begin(9600);
my_func((uint8_t *)(init_cmd[0].data), init_cmd[0].data_bytes);
}
Кому как. ТСу, похоже, нельзя.
Евгений, спасибо, теперь все работает. Вот окончательный код, вдруг кому пригодится:
typedef struct {
int cmd;
const uint8_t *data;
size_t data_bytes;
unsigned int delay_ms;
} st7701_lcd_init_cmd_t;
static const st7701_lcd_init_cmd_t init_cmd[] = {
{0xFF, (uint8_t []){0x77, 0x01, 0x00, 0x00, 0x13}, 5, 0},
{0xEF, (uint8_t []){0x08}, 1, 0},
{0xFF, (uint8_t []){0x77, 0x01, 0x00, 0x00, 0x10}, 5, 0},
{0xC0, (uint8_t []){0x2c, 0x00}, 2, 0},
{0xC1, (uint8_t []){0x10, 0x0C}, 2, 0},
{0xC2, (uint8_t []){0x21, 0x0A}, 2, 0},
};
void setup() {
Serial.begin(9600);
// Находим размер (количество "командо-строк") структуры данных инита
// Бывают иниты по 400-500 и более команд, поэтому с запасом
uint16_t init_cmd_size = sizeof(init_cmd) / sizeof(st7701_lcd_init_cmd_t);
for(uint16_t i=0; i<init_cmd_size; i++) {
my_func(init_cmd[i].cmd, (uint32_t *)(init_cmd[i].data), init_cmd[i].data_bytes);
}
}
void loop() {
}
void my_func(uint8_t cmds, uint32_t *para, size_t para_num) {
const uint8_t * bPara = reinterpret_cast<const uint8_t *>(para);
// сюда вставляем отправку команды cmds
for(uint8_t i=0; i<para_num; i++) {
const uint8_t regval = bPara[i];
// Сюда вставляем отправку байтов инита regval в устройство по нужному интерфейсу
Serial.println(regval, HEX);
}
}
Если вдруг кому-то непонятно, зачем головная боль с этими структурами и массивами переменной длины, вот так выглядит фрагмент найденного в сети кода инициализации дисплея “в лоб”:
GP_COMMAD_PA(20);
SPI_WriteData(0x53);
SPI_WriteData(0x1F);
SPI_WriteData(0x19);
SPI_WriteData(0x15);
SPI_WriteData(0x11);
SPI_WriteData(0x11);
SPI_WriteData(0x11);
SPI_WriteData(0x12);
SPI_WriteData(0x14);
SPI_WriteData(0x15);
SPI_WriteData(0x11);
SPI_WriteData(0x0D);
SPI_WriteData(0x0B);
SPI_WriteData(0x0B);
SPI_WriteData(0x0D);
SPI_WriteData(0x0C);
SPI_WriteData(0x0C);
SPI_WriteData(0x08);
SPI_WriteData(0x04);
SPI_WriteData(0x00);
GP_COMMAD_PA(20);
SPI_WriteData(0x54);
SPI_WriteData(0x1F);
SPI_WriteData(0x19);
SPI_WriteData(0x15);
SPI_WriteData(0x11);
SPI_WriteData(0x11);
SPI_WriteData(0x11);
SPI_WriteData(0x13);
SPI_WriteData(0x15);
SPI_WriteData(0x16);
SPI_WriteData(0x11);
SPI_WriteData(0x0D);
SPI_WriteData(0x0C);
SPI_WriteData(0x0C);
SPI_WriteData(0x0E);
SPI_WriteData(0x0C);
SPI_WriteData(0x0C);
SPI_WriteData(0x08);
SPI_WriteData(0x04);
SPI_WriteData(0x00);
В общей сложности более 500 строк. Не, я уж лучше день потрачу на ковыряние в структурах, зато потом будет красивый и удобный многоразовый шаблон.
По уму надо такой указатель на массив делать последним полем структуры.
Пуркуа? Следом опять идет такой же элемент структуры. Если начнется беспредел, то порубит его.
У нас тут принято, не себе любимому галку ставить “Вопрос решен”, а все таки человеку, чей пост помог вам решить проблему.
Исправил.
Мне другое непонятно - если вам уже показали вашу ошибку с типами данных, почему опять в функции my_func
указатель на дата у вас имеет тип uimt32*?
Нахрена использовать неверный тип, а потом делать каст?
Решение “в лоб” через пятьсот строк имеет преимущество что оно простое и понятное.
Лобовое решение можно было бы улучшить, записав 500 значений в массив в Прогмем и читая его в цикле. Этого было бы вполне достаточно.
А когда подобный вам новичок начинает придумывать " удобные шаблоны", при этом путая элементарные типы данных, получается никому не нужная заумь.
Потому что а) я копировал начальное решение из другого источника, где так было, б) в сообщении #24 мне так было указано, дословно: Сделайте правильно и “забудьте о перхоти”. И далее именно этот фрагмент кода с кастом. Согласен, отвечавший пропустил этот момент (и не обязан), я тоже не обратил внимание в радости, что заработало. Бывает. Собственно, вся эта тема результат моего бездумного дерганья кода из косячных источников, в надежде слепить по-быстрому.
Я портирую куски чужого кода с другой платформы, там нет прогмем. Зато есть необъяснимые ляпы, как оказалось. Но предлагать новичку сознательно примитизировать решения вместо того, чтобы спотыкаться, набивать шишки и нарабатывать свою базу кода - неправильно, по-моему.
Для того что бы на куче одним куском выделить место под структуру с заранее не известным размером буфера…
С какого это бодуна я его пропустил? Отлично видел. Просто решал проблему минимальным воздействием на код. Всё, что можно не трогать - не трогал. Откуда мне знать, что там у Вас ещё в коде, может Вам зачем-нибудь реально нужен такой тип (вполне могу себе представить реальные причины для этого).
Более того, это далеко не единственная “странность” в Вашем коде, которую я “пропустил”. Вы, похоже, вообще большой любитель собственноручно раскладывать грабли а потом пытаться их обойти по тонкому льду. Но Вы не просили такого анализа, я и не лезу с ним.
А это вообще бред. У вас размер каждой команды разный и не равен размеру структуры.
Как результат, в последующем цикле вы почти наверняка вылезаете за границы массива.
Ей богу, тупые 500 строк явно были лучше, чем ваша оптимизация с кучей грубейших ошибок.
Не понял о чём Вы. Размер структуры st7701_lcd_init_cmd_t
всегда 8 байтов. Массив data
живёт совершенно отдельно (в структуре только указатель на его нулевой элемент). В чём проблема, чтобы перебрать массив структур таким образом?
“по-быстрому”, говорите.
Да, ошибся.