LINUX.ORG.RU

Избранные сообщения aspotashev

SPI в libopencm3 под stm32f407

Форум — Development

Дела настолько плохи, что у меня не получается даже передача данных между закороченными MISO и MOSI. в каждом нечётном отправленном байте старший бит почему-то устанавливается в 1 . Кто-нибудь сталкивался с такой проблемой?

Инициализация SPI (пины точно выбраны правильно и не конфликтуют с JTAG):

#define SPI_ID SPI1
#define SPI_RCC RCC_SPI1
#define SPI_NSS GPIO4
#define SPI_SCK GPIO5
#define SPI_MISO GPIO6
#define SPI_MOSI GPIO7
#define SPI_RCC_PORT RCC_GPIOA
#define SPI_PORT GPIOA


rcc_periph_clock_enable(SPI_RCC_PORT);
rcc_periph_clock_enable(SPI_RCC);

gpio_mode_setup(SPI_PORT, GPIO_MODE_AF, GPIO_PUPD_PULLUP,
                          SPI_SCK | SPI_MOSI);
gpio_mode_setup(SPI_PORT, GPIO_MODE_AF, GPIO_PUPD_NONE,
                          SPI_MISO);
gpio_set_af(SPI_PORT, GPIO_AF5,
                      SPI_SCK | SPI_MISO | SPI_MOSI);
gpio_set_output_options(SPI_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_25MHZ,
                                  SPI_SCK | SPI_MOSI);

gpio_set(SPI_PORT, SPI_NSS);
gpio_mode_setup(SPI_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, SPI_NSS);

spi_reset(SPI_ID);

spi_init_master(SPI_ID, SPI_CR1_BAUDRATE_FPCLK_DIV_256, 0,
                        0, SPI_CR1_DFF_8BIT, SPI_CR1_MSBFIRST);
spi_set_full_duplex_mode(SPI_ID);

spi_enable_software_slave_management(SPI_ID);
spi_set_nss_high(SPI_ID);
SPI_CR2(SPI_ID) |= SPI_CR2_FRF;
gpio_set(SPI_PORT, SPI_NSS);
spi_disable_crc(SPI_ID);
spi_enable(SPI_ID);

Тестирование передачи данных:

void mspi_send(uint32_t spi, uint16_t data) {
	SPI_DR(spi) = data;
	while (!(SPI_SR(spi) & SPI_SR_TXE));
}

void test() {
	uint8_t pid = 0;
	uint8_t rx_value;
	for (pid = 0; pid < 10; ++pid) {
		mspi_send(SPI_ID, pid);
		rx_value = spi_read(SPI_ID);
		printf("Received: %d - %d\n\r", (int)pid, (int)rx_value);
	}
	for (pid = 10; pid > 0; --pid) {
		mspi_send(SPI_ID, pid);
		rx_value = spi_read(SPI_ID);
		printf("Received: %d - %d\n\r", (int)pid, (int)rx_value);
		mspi_send(SPI_ID, pid);
		rx_value = spi_read(SPI_ID);
		printf("Received: %d - %d\n\r", (int)pid, (int)rx_value);
	}
}

Результаты передачи:

Received: 0 - 128
Received: 1 - 1
Received: 2 - 130
Received: 3 - 3
Received: 4 - 132
Received: 5 - 5
Received: 6 - 134
Received: 7 - 7
Received: 8 - 136
Received: 9 - 9
Received: 10 - 138
Received: 10 - 10
Received: 9 - 9
Received: 9 - 137
Received: 8 - 136
Received: 8 - 8
Received: 7 - 7
Received: 7 - 135
Received: 6 - 134
Received: 6 - 6
Received: 5 - 5
Received: 5 - 133
Received: 4 - 132
Received: 4 - 4
Received: 3 - 3
Received: 3 - 131
Received: 2 - 130
Received: 2 - 2
Received: 1 - 1
Received: 1 - 129

 , ,

Selat
()

API для написания qml плазмоидов

Форум — Development

Не могу найти где нормально описан API по всяким dataSource, etc для кед.

Вот тут есть такой код:

    Kio.KRun {
        id: kRun
    }
....
    MouseArea {
        id: mouseArea
        anchors.fill: parent
        onClicked: {
            kRun.openUrl(apps.data[apps.ksysguardSource].entryPath)
        }
    }
В доке я метода openUrl() не вижу. Где он описан?

 , ,

Crow
()

STM32F4 и USB

Форум — Science & Engineering

С низкоуровневой работой с USB на STM32F103 я разобрался, теперь очередь USB OTG, который присутствует на более жирных МК (например, STM32F407, который я и использую для всех тестов). Для начала мне вполне хватит device-only mode.

Инициализирую USB я так:

usb->globalRegs->GINTSTS = 0xFFFFFFFF;
usb->globalRegs->GUSBCFG |= OTG_FS_GLOBAL_FS_GUSBCFG_PHYSEL;
usb->globalRegs->GCCFG |= OTG_FS_GLOBAL_FS_GCCFG_PWRDWN | OTG_FS_GLOBAL_FS_GCCFG_VBUSBSEN;
while ((usb->globalRegs->GRSTCTL & OTG_FS_GLOBAL_FS_GRSTCTL_AHBIDL) == 0);
usb->globalRegs->GRSTCTL |= OTG_FS_GLOBAL_FS_GRSTCTL_CSRST;
while (usb->globalRegs->GRSTCTL & OTG_FS_GLOBAL_FS_GRSTCTL_CSRST);
uint32_t ahbFreq = stm32_rccAHBFrequency();
uint32_t trdt;
if (ahbFreq <= 15000000) {
	trdt = 0xF;
} else if (ahbFreq <= 16000000) {
	trdt = 0xE;
} else if (ahbFreq <= 17200000) {
	trdt = 0xD;
} else if (ahbFreq <= 18500000) {
	trdt = 0xC;
} else if (ahbFreq <= 20000000) {
	trdt = 0xB;
} else if (ahbFreq <= 21800000) {
	trdt = 0xA;
} else if (ahbFreq <= 24000000) {
	trdt = 0x9;
} else if (ahbFreq <= 27500000) {
	trdt = 0x8;
} else if (ahbFreq <= 32000000) {
	trdt = 0x7;
} else {
	trdt = 0x6;
}
usb->globalRegs->GUSBCFG = (usb->globalRegs->GUSBCFG & ~OTG_FS_GLOBAL_FS_GUSBCFG_TRDT_MASK) | OTG_FS_GLOBAL_FS_GUSBCFG_FDMOD |
	(trdt << OTG_FS_GLOBAL_FS_GUSBCFG_TRDT_OFFSET);
usb->deviceRegs->DCFG |= 3 << OTG_FS_DEVICE_FS_DCFG_DSPD_OFFSET;
usb->powerRegs->PCGCCTL = 0;
usb->globalRegs->GAHBCFG |= OTG_FS_GLOBAL_FS_GAHBCFG_GINT;
usb->globalRegs->GINTMSK = OTG_FS_GLOBAL_FS_GINTMSK_ENUMDNEM;
nvicEnableIRQ(OTG_FS_IRQ);
nvicEnableIRQ(OTG_FS_WKUP_IRQ);

Жду прерывание окончания энумерации. Оно приходит при втыкании кабеля USB. При приходе прерывания делаю вот такие вещи:

static void STM32USBDriverClass_resetFIFO(STM32USBDriverClass *usb) {
	usb->fifoTop = 0;
}

static uint16_t STM32USBDriverClass_allocFIFO(STM32USBDriverClass *usb, uint16_t count) {
	uint16_t r = usb->fifoTop;
	usb->fifoTop += count;
	return r;
}
...
int i;
for (i = 0; i < STM32USB_MAX_EP_COUNT; i++) {
	usb->deviceRegs->DIEP[i].CTL = OTG_FS_DEVICE_FS_DIEPCTL0_SNAK;
	usb->deviceRegs->DOEP[i].CTL = OTG_FS_DEVICE_DOEPCTL0_SNAK;
	usb->deviceRegs->DIEP[i].INT = 0xFF;
	usb->deviceRegs->DOEP[i].INT = 0xFF;
	usb->epInfo[i].inCallback = NULL;
	usb->epInfo[i].outCallback = NULL;
}
usb->deviceRegs->DAINT = 0xFFFFFFFF;
usb->deviceRegs->DAINTMSK = 0;
usb->globalRegs->GINTSTS = 0xFFFFFFFF;
STM32USBDriverClass_resetFIFO(usb);
STM32USBDriverClass_allocFIFO(usb, 128);
usb->globalRegs->GRXFSIZ = 128;
usb->globalRegs->GINTMSK = OTG_FS_GLOBAL_FS_GINTMSK_ENUMDNEM | OTG_FS_GLOBAL_FS_GINTMSK_RXFLVLM | OTG_FS_GLOBAL_FS_GINTMSK_IEPINT |
	OTG_FS_GLOBAL_FS_GINTMSK_OEPINT | OTG_FS_GLOBAL_FS_GINTMSK_USBSUSPM;
usb->deviceRegs->DIEPMSK = OTG_FS_DEVICE_FS_DIEPMSK_XFRCM;
usb->deviceRegs->DOEPMSK = OTG_FS_DEVICE_FS_DOEPMSK_XFRCM | OTG_FS_DEVICE_FS_DOEPMSK_STUPM;
usb->deviceRegs->DCFG = (usb->deviceRegs->DCFG & ~OTG_FS_DEVICE_FS_DCFG_DAD_MASK) | (0 << OTG_FS_DEVICE_FS_DCFG_DAD_OFFSET);
...
// bufSize == 64
bufSize = (bufSize + 3) & ~3;
uint32_t mpsiz;
if (bufSize >= 64) {
	mpsiz = 0;
} else if (bufSize >= 32) {
	mpsiz = 1;
} else if (bufSize >= 16) {
	mpsiz = 2;
} else {
	mpsiz = 3;
}
usb->deviceRegs->DOEP[0].SIZE = 0;
usb->deviceRegs->DOEP[0].CTL = mpsiz << OTG_FS_DEVICE_DOEPCTL0_MPSIZ_OFFSET;
usb->deviceRegs->DIEP[0].SIZE = 0;
usb->deviceRegs->DIEP[0].CTL = (mpsiz << OTG_FS_DEVICE_FS_DIEPCTL0_MPSIZ_OFFSET) | (0 << OTG_FS_DEVICE_FS_DIEPCTL0_TXFNUM_OFFSET);
usb->globalRegs->HPTXFSIZ = (STM32USBDriverClass_allocFIFO(usb, bufSize / 4) << OTG_FS_GLOBAL_FS_HPTXFSIZ_PTXSA_OFFSET) |
	((bufSize / 4) << OTG_FS_GLOBAL_FS_HPTXFSIZ_PTXFSIZ_OFFSET);
usb->epInfo[ep].rxBufSize = (3 << OTG_FS_DEVICE_DOEPTSIZ0_STUPCNT_OFFSET) | OTG_FS_DEVICE_DOEPTSIZ0_PKTCNT | bufSize;
usb->epInfo[ep].txBufSize = bufSize;
usb->epInfo[ep].outCallback = callback;
usb->epInfo[ep].outCallbackArg = arg;
usb->epInfo[ep].inCallback = callback;
usb->epInfo[ep].inCallbackArg = arg;
usb->deviceRegs->DAINTMSK |= (1 << OTG_FS_DEVICE_FS_DAINTMSK_IEPM_OFFSET) | (1 << OTG_FS_DEVICE_FS_DAINTMSK_OEPINT_OFFSET);
...
// ep == 0, dir == 0
volatile STM32OTGEpRegs *epRegs = (dir ? usb->deviceRegs->DIEP : usb->deviceRegs->DOEP) + ep;
epRegs->SIZE = usb->epInfo[ep].rxBufSize;
epRegs->CTL |= OTG_FS_DEVICE_FS_DIEPCTL0_EPENA | OTG_FS_DEVICE_FS_DIEPCTL0_CNAK;

На этом инициализация оканчивается. Я ожидаю получить прерывание по причине RXFLVL, что будет значить приход первого SETUP-пакета, однако ничего не получаю. Через какое-то время приходит SUSPEND, а затем новый RESET. И так повторяется несколько раз, пока хосту не надоест долбить устройство.

Что я делаю не так в настройке EP0, что устройство не получает ни одного пакета (никаких прерываний об ошибках тоже не приходит)? Проверял адреса полей всех своих структур, описывающих регистры USB OTG - с даташитом совпадают.

С частотами вроде всё тоже ок. При настройке коэффициентов PLL использую те же, что и libopencm3 (там USB работает с такими настройками) для случая кварца 8 МГц и выходной частоте 168 МГц.

 , ,

KivApple
()

Синие кеды

Галерея — Скриншоты

Вспомнились утекшие когда-то давно в сеть билды Longhorn. Была там довольно приятная, на мой взгляд, цветовая схема, которую я решил попробовать повторить.

Цвета заголовков долго искать не пришлось, а вот плазму пришлось перекрашивать, что и изображено на скриншоте.

Arch, KDE 4.10.3, QtCurve, перекрашенный Klassik, Conky.

>>> Просмотр (1920x1080, 222 Kb)

 ,

keyran
()

Сочувствующий кот

Галерея — Скриншоты
  • ОС: Archlinux x86_64 с последними апдейтами
  • DE: KDE 4.10
  • Оформление окон: Zukitwo
  • Тема рабочего стола: Hellium (ещё Fushigi подходит идеально)
  • Иконки: FS icons ubuntu Sky
  • Цветовая схема: какая-то подпиленная дефолтная
  • Dropbox. Copy. по дефолту дают 15 гигабайт, по моему рефералу - 20. Только по почте активируйте письмо. https://copy.com?r=rEt7cq Если модерам плохо, удаляйте линк. Под тег юрл не берётся.

Про ШГ не орать - в курсе.

Всё это на ноуте Asus X53S, у которого полная лажа с аккумулятором и разбит дисплей, поэтому использую как стационар. Так же владелец грёбаного оптимуса.

При обновлении был в другом городе и интернет был дико медленный, поэтому кот как бы понимает, что 500 метров - это долго :(

>>> Просмотр (2560x1024, 1056 Kb)

 ,

Wulf
()

Здесь есть локализаторы KDE?

Форум — Desktop

Интересно, кто из вас придумал, что локализация - это перевод слово в слово? Для вас сюрприз, что в русском языке слова и предложения в среднем длиннее, чем в английском, поэтому тупо переводить в лоб будет некрасиво? Или вас совершенно не напрягают километровые в ширину меню?

1) Скажите, зачем здесь нужны слова «из буфера обмена»?

2) Объясните, зачем тут во вложенном меню вы продублировали слово «Распаковать»? Чем плохи варианты: «Распаковать во вложенную папку» -> «В папку», «Распаковать в...» -> «Указать», «Распаковать в эту папку» -> «Сюда»?

3) Вот это мне вообще понравилось. «Служба напоминаний органайзера KDE» и в скобочках, для верняка, ещё и название процесса добавили, лол. А родословную мантейнера почему не присобачили? Чем варианты «Напоминания органайзера» или «Служба напоминаний» или «Напоминания KDE» плохи? Сравните длину.

4) В этом же меню: «Индексирование файлов поисковой системы». ЗАЧЕМ столько слов? Идиоту понятно, что индексирование файлов относится к поисковой системе! Оставьте просто «Индексирование файлов», вас поймут!

5) Ещё. «Настроить виджет „Рабочий стол по умолчанию“». Не судьба было оставить оставить одно слово «Настроить»? Даже не совсем развитому умственно человеку ясно, что настраивание это относится к рабочему столу, а не к мышке или групповым политикам.

6) Там же: «Разблокировать изменение виджетов». Конечно, додуматься, что слово «изменение» здесь лишнее - очень тяжело. «Разблокировать виджеты», видимо, выглядит абсолютно непонятно, да.

7) Напоследок, мой «любимый» диалог в KDE: запрос пароля root. Вы только посмотрите на эту инструкцию в диалоге. Впрочем, ладно, может, кто-то не догадается что именно нужно тут делать и ему эта портянка позарез необходима, тем более, что окошко выглядит более-менее нормально. Но посмотрите, что будет, если ввести неправильный пароль! Что это за, блин, сочинение? Может, ещё мануал сюда процитируете? Надписи «Неверный пароль или недостаточно прав» вам недостаточно? А вот ещё: если повторно ввести неправильный пароль, диалог, скукожившись, примет ещё более оригинальный вид. FACEPALM.MKV. Я понимаю, что в данном конкретном случае не одних локализаторов вина, но вы хотя бы могли сгладить это безобразие лаконичной локализацией, блин.

И это - всего за десять минут использования русской локализации. Жутко подумать сколько недочётов я бы накопал за пару дней. Я понимаю, это всё мелочи, но из-за таких вот мелочей портится впечатление о продукте. Я понимаю, вы делаете это всё добровольно, но должен же быть хоть какой-то самоконтроль качества, вам не стыдно ставить свои имена под такой работой? Кто же так делает?

cast AX

 , , ,

fragmentor
()