Здравствуйте!
Сюда я пришел из соседней ветки
viewtopic.php?f=57&t=148469В общем аврка никак не справлялась и я решил попробовать STM32А100RBT6 на отладочной плате STM VL Discovery
Итак - проц от встроенного гены умножитель 6. разгона пока не касаемся.
использую CubeMX для инициализации и HAL для работы с периферией. удалось подключить 44780 spi sdcard TLC5940. все работает и летает. Файлы читаются спи шуршит через ДМА, экранчик пляшет
Но есть несколько проблем:
1) очень долго искал драйвер spi dscard под fatfs - нашел какой-то шилд адафрут и к нему исходник.
В общем в процедуре
Код:
static void SPIx_WriteReadData(const uint8_t *DataIn, uint8_t *DataOut, uint16_t DataLegnth)
идет обращение к флешке через вот такой кусок кода
Спойлер
Код:
static void SPIx_WriteReadData(const uint8_t *DataIn, uint8_t *DataOut, uint16_t DataLegnth)
{
HAL_StatusTypeDef status = HAL_OK;
/* Check the communication status */
status = HAL_SPI_TransmitReceive(&hspi1, (uint8_t*) DataIn, DataOut, DataLegnth, SpixTimeout);
if (status != HAL_OK)
{
/* Execute user timeout callback */
SPIx_Error();
}
}
логично предположить что читать 512 байтные буферы и писать их же - будет быстрее через дма? ок не вопрос - настраиваю кубом так же как на spi2 делал - DMA только там был один канал на передачу а тут поднял оба канала на прием и передачу, сгенерил под них прерывания и обработчики прерывания а процедуру обмена переписал вот так
Спойлер
Код:
static void SPIx_WriteReadData(const uint8_t *DataIn, uint8_t *DataOut, uint16_t DataLegnth)
{
HAL_StatusTypeDef status = HAL_OK;
if(DataLegnth<65)
{
status = HAL_SPI_TransmitReceive(&hspi1, (uint8_t*) DataIn, DataOut, DataLegnth, SpixTimeout);
if (status != HAL_OK)
{
/* Execute user timeout callback */
SPIx_Error();
}
}
else
{
status = HAL_SPI_TransmitReceive_DMA(&hspi1, (uint8_t*) DataIn, DataOut, DataLegnth);
if (status != HAL_OK)
{
/* Execute user timeout callback */
SPIx_Error();
}
while(HAL_DMA_GetState(&hdma_spi1_tx) != HAL_DMA_STATE_READY);
}
}
Тоесть сделал сначала только на дма. потом понял что 1-3-5 байт кидать через дма некомильфо - сделал вот таким образом то так то сяк. В общем оно-то работает но 29 мегабайт читаются без дма за 19 секунд а с дма - 110 секунд. минимум что добивался - 90 секунд!!! как так-то? при этом больше ничем проц не занимался! что я делал тут не так?
Дальше второй вопрос - библиотека адафрутовая иногда в непонятных местах зависала на чтении файлов. просто ни с того ни с сего то на 512 байте считанном тормозило то ещё где. жутко долго искал где и что но в итоге нашел команду:
файл adafruit_sd
Спойлер
Код:
/**
* @brief Reads block(s) from a specified address in the SD card, in polling mode.
* @param pData: Pointer to the buffer that will contain the data to transmit
* @param ReadAddr: Address from where data is to be read
* @param BlockSize: SD card data block size, that should be 512
* @param NumOfBlocks: Number of SD blocks to read
* @retval SD status
*/
uint8_t BSP_SD_ReadBlocks(uint32_t* pData, uint32_t ReadAddr, uint16_t BlockSize, uint32_t NumberOfBlocks)
{
uint32_t offset = 0;
uint8_t retr = BSP_SD_ERROR;
uint8_t *ptr = NULL;
SD_CmdAnswer_typedef response;
uint8_t block[BlockSize];
/* Send CMD16 (SD_CMD_SET_BLOCKLEN) to set the size of the block and
Check if the SD acknowledged the set block length command: R1 response (0x00: no errors) */
response = SD_SendCmd(SD_CMD_SET_BLOCKLEN, BlockSize, 0xFF, SD_ANSWER_R1_EXPECTED);
SD_IO_CSState(1);
SD_IO_WriteByte(SD_DUMMY_BYTE);
if (response.r1 != SD_R1_NO_ERROR)
{
goto error;
}
/* это я закоментил
//ptr = malloc(sizeof(uint8_t) * BlockSize);
ptr = (uint8_t *) █
// if (ptr == NULL)
// {
// goto error;
// }
// visnet tut
memset(ptr, SD_DUMMY_BYTE, sizeof(uint8_t) * BlockSize);
*/
ptr = (uint8_t *) █
//memset(ptr, SD_DUMMY_BYTE, BlockSize);
/* Data transfer */
while (NumberOfBlocks--)
{
/* Send CMD17 (SD_CMD_READ_SINGLE_BLOCK) to read one block */
/* Check if the SD acknowledged the read block command: R1 response (0x00: no errors) */
response = SD_SendCmd(SD_CMD_READ_SINGLE_BLOCK, (ReadAddr + offset) / (flag_SDHC == 1 ? BlockSize : 1), 0xFF,
SD_ANSWER_R1_EXPECTED);
if (response.r1 != SD_R1_NO_ERROR)
{
goto error;
}
/* Now look for the data token to signify the start of the data */
if (SD_WaitData(SD_TOKEN_START_DATA_SINGLE_BLOCK_READ) == BSP_SD_OK)
{
/* Read the SD block data : read NumByteToRead data */
SD_IO_WriteReadData(ptr, (uint8_t*) pData + offset, BlockSize);
/* Set next read address*/
offset += BlockSize;
/* get CRC bytes (not really needed by us, but required by SD) */
SD_IO_WriteByte(SD_DUMMY_BYTE);
SD_IO_WriteByte(SD_DUMMY_BYTE);
}
else
{
goto error;
}
/* End the command data read cycle */
SD_IO_CSState(1);
SD_IO_WriteByte(SD_DUMMY_BYTE);
}
// if (ptr != NULL)
// free(ptr);
retr = BSP_SD_OK;
error:
/* Send dummy byte: 8 Clock pulses of delay */
SD_IO_CSState(1);
SD_IO_WriteByte(SD_DUMMY_BYTE);
// if (ptr != NULL)
// free(ptr);
/* Return the reponse */
return retr;
}
в этой процедурке зависало на строке
Код:
memset(ptr, SD_DUMMY_BYTE, sizeof(uint8_t) * BlockSize);
заремил её и вроде как все полетело и без проблем! а что не так с этит мемсетом? это ж просто очистка буффера!? что тут я сделал не так?
Дальше ещё интереснее. Ок разобрался с флешкой и спи - как-то работает.
подключил я на макетке проводками микруху статической памяти из кеша 386-го компьютера(или 486 - не уверен)
Микруха называется MAGIC MG12512-15K/ Никакого внятного шита на неё я не нашел потому просто расключил как обычную срам 512 киловую.
D0-D7 - на порт А0-А7 проца один-в-один
ну а адреса младшие 16 - на PORTC0-15 16 17 и 18 бит адреса завел на PORTD.0 PORTD.1 и PORTB.6 - естественно ноги на выход макс скорость и т.д.
ну и написал процедурку установки собственно адреса
Спойлер
Код:
void Ram_SetAddr(uint32_t addr)
{
GPIOC->ODR = addr&0xFFFF;
if(addr&(1<<16))
{
HAL_GPIO_WritePin(RamA16_GPIO_Port, RamA16_Pin, GPIO_PIN_SET);
}
else
{
HAL_GPIO_WritePin(RamA16_GPIO_Port, RamA16_Pin, GPIO_PIN_RESET);
}
if(addr&(1<<17))
{
HAL_GPIO_WritePin(RamA17_GPIO_Port, RamA17_Pin, GPIO_PIN_SET);
}
else
{
HAL_GPIO_WritePin(RamA17_GPIO_Port, RamA17_Pin, GPIO_PIN_RESET);
}
if(addr&(1<<18))
{
HAL_GPIO_WritePin(RamA18_GPIO_Port, RamA18_Pin, GPIO_PIN_SET);
}
else
{
HAL_GPIO_WritePin(RamA18_GPIO_Port, RamA18_Pin, GPIO_PIN_RESET);
}
}
Она вроде как работает - если записать нуль - все ноги падают в ноль. мерял тестером на микрухе. если записать 524287 - все ноги поднимаются на +
Да микруху питал и 3.3 вольтами и 5-ю. вроде арм мой толерантен?
Так вот. Дальше написал процедурку чтения и записи в эту память
Спойлер
Код:
void RamDelay()
{
uint16_t a=0;
for(a=0;a<20;a++)
{
}
}
void Ram_Write(char* buf, uint32_t addr, uint32_t length)
{
uint32_t EndAddr = addr + length;
char data=0;
uint32_t ClrA = 0xFF << 16;
GPIO_InitTypeDef GPIO_InitStruct;
//HAL_GPIO_WritePin(RamCE_GPIO_Port, RamCE_Pin, GPIO_PIN_SET);
Ram_CE_1
Ram_OE_1
/*
GPIO_InitStruct.Pin = RamA14_Pin|RamA15_Pin|RamA16_Pin|RamA0_Pin
|RamA1_Pin|RamA2_Pin|RamA3_Pin|RamA4_Pin
|RamA5_Pin|RamA6_Pin|RamA7_Pin|RamA8_Pin
|RamA9_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
*/
GPIO_InitStruct.Pin = RamD0_Pin|RamD1_Pin|RamD2_Pin|RamD3_Pin
|RamD4_Pin|RamD5_Pin|RamD6_Pin|RamD7_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIOA->BSRR = ClrA;
do
{
Ram_CE_1
Ram_SetAddr(addr);
data = *buf;
GPIOA->BSRR = data&0xFF;
RamDelay();
Ram_CE_0
Ram_WE_0
RamDelay();
Ram_WE_1
buf++;
GPIOA->BSRR = ClrA;
addr++;
}while(addr<EndAddr);
GPIOA->BSRR = ClrA;
GPIOC->BSRR = (uint32_t)(0xFFFF)<<16;
}
void Ram_Read(char* buf, uint32_t addr, uint32_t length)
{
uint32_t EndAddr = addr + length;
uint32_t ClrA = 0xFF;
uint32_t ClrC = 0xFFFF;
GPIO_InitTypeDef GPIO_InitStruct;
ClrA = ClrA<<16;
ClrC = ClrC<<16;
//HAL_GPIO_WritePin(RamCE_GPIO_Port, RamCE_Pin, GPIO_PIN_SET);
Ram_CE_1
Ram_OE_1
GPIO_InitStruct.Pin = RamD0_Pin|RamD1_Pin|RamD2_Pin|RamD3_Pin
|RamD4_Pin|RamD5_Pin|RamD6_Pin|RamD7_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
//GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIOA->BSRR = ClrA;
do
{
Ram_CE_1
Ram_SetAddr(addr);
//GPIOA->BSRR = data&0xFF;
Ram_CE_0
Ram_OE_0
RamDelay();
*buf = GPIOA->IDR&0xFF;
Ram_CE_1
Ram_OE_1
buf++;
addr++;
}while(addr<EndAddr);
*buf = 0;
GPIOA->BSRR = ClrA;
GPIOC->BSRR = ClrC;
}
Намудрил конечно много но то уже в попытках выискать глюка. короче оно вроде как работает но не так как хотелось. сначала я подключил её по адресам абы-как и по данным абы-как - для оперативки то разницы нет - что и куда запишем то оттуда потом и прочитаем! Но получились странные глюки
https://www.dropbox.com/sh/85fzdvaxd7eq ... Hty0a?dl=0 ramin - то что я читал с флешки(я его и на экран выводил так что там читалось красиво и в отладчике на шине данных осцилом и логанализером байты смотрел - все как и положено).
а вот то что записывалось на карту в качестве считываемых данных с памяти - полный швах! сказать что там чтото не так? ну вроде ниногда куски текста проскакивают. но иногда какие-то крякозяблы причем таким образом как вроде там нет атких адресов.
Ок психанул и переконектил макетку один-в-один PORTA.0 на А0 рамы и атк далее - один-в-один битик к битику..макетка стала конечно ёжиком но картина кряков изменилась!
стало вот так
https://www.dropbox.com/sh/71p745dutnai ... JCJxa?dl=0нуок думаю мож дохлая рама? пошел наковырял ещё одну.
картина немного поменялась но кардинально не улучшилось!
https://www.dropbox.com/sh/ihx5vlfk6kn6 ... 8McTa?dl=0Какие могут у кого быть идеи что я делаю не так?
Весь исходник под CubeMX и Keil uVision тут
https://www.dropbox.com/s/vzl5drljh0so1dw/2.rar?dl=0С этой пролемой долюлюсь второй день - ничего на ум не приходит. рамы где-то взять ну хз где именно срамки взять да ещё на такой обьем. Есть в наличии всего одна
https://media.digikey.com/pdf/Data%20Sh ... Q4015(Y,LY)_Rev_Apr_2014.pdf вот такая микруха но в ней внутри батарейка и она типа не забывает содержимое при отключении но батарейка подключается при первой подаче питания и это неоратимо - тоесть по сути попробовав я её убью т.к. она мне пока не нужна в том виде что она есть. а батарейку внутреннюю не поменяеш ведь.