Andruhass » 09 дек 2011, 02:04
Я получаю через uart данные которые требуются записать на sd карту(простой регистратор).
Есть 2 массива по 64кБ в которые DMA записывает принимаемые данные и функция которая записывает, переданный ей массив, на карточку. DMA работает с массивами поочередно, тоесть пока оно заполняет один, другой в это время записывается на карту.
Проблема заключается в следующем:
Сначала DMA заполняет первый массив (mass_1);
Назначаю DMA второй массив (mass_2), записываю mass_1 на флешку;
И вот теперь, когда я назначаю DMA mass_1, оно записывает в mass_1 новые данные, но при этом пропускает в некоторых местах последовательности из 32 байтов(тоесть там остаются данные с предыдущего заполнения).
Так же и с mass_2. Если же я переключаюсь между тремя массивами, то такие дырки есть, но реже.
Такое ощущение что, что-то блокирует эти 32 байтовые последовательности для доступа из DMA.
Помогите понять причину
С уважением
Андрей
boez » 09 дек 2011, 12:08
Телепаты ушли работать в ЦРУ и Газпром. Проц какой? Код инициализации DMA и самого обмена выложить можно?
Andruhass » 09 дек 2011, 12:20
Забыл написать что работаю с ARM9 Samsung S3C2440 c MMU.
ОК, сегодня прийду домой, и выложу код инициализации
UPD: вот и код:
Записываю я на флешку в формате FAT32 с помощью функций из сторонней библиотеки.
Надеюсь нормально оформил- Код: Выделить всё • Развернуть
// Переменные
unsigned char Rx_buffer1[65536];
unsigned char Rx_buffer2[65536]; // Массивы 64кБ
volatile int mass_1 = 1, mass_2 = 0, mass_3 = 0; // Переменные для определения состояния массивов: 0 - не записывается и не
// готово для записи на флеш, 1 - в процессе заполнения DMA, 2 -
// заполнено и готово для записи на флеш
int co = 50; // Количество записываемых массивов
// Кусок кода отвечающий за запись
file = fl_fopen("/file.txt", "c"); // открываем файл для записи
if (file)
{
pISR_DMA0=(unsigned)DMA_end; // сохраняем адрес функции обработчика прерывания dma в таблицу прерываний (код
// обработчика внизу)
rINTMSK &= ~(BIT_DMA0); // Разрешаем прерывание
// DMA configuration
rDISRC0=(U32)(URXH0); // Источник данных для DMA = Rx регистр UARTа
rDISRCC0=(1<<1)+(1<<0); // DMA initial source control reg.: [0] - address increment(1=fixed);
// [1] - location of source (1=peripheral bus (APB))
if(mass_1 == 1)
{
rDIDST0=(U32)(&Rx_buffer1); // DMA destination адрес = 1й 64кБ массив
}
else if(mass_2 == 1)
{
rDIDST0=(U32)(&Rx_buffer2); // DMA destination адрес = 2й 64кБ массив
}
rDIDSTC0=(0<<1)+(0<<0); // DMA destination control reg.: [0] - address increment(1=increment);
// [1] - location of source (1=system bus (AHB))
rDCON0=(1<<31)+(0<<30)+(1<<29)+(0<<28)+(0<<27)+(1<<24)+(1<<23)+(1<<22)+(0<<20)+65536; // DMA config. reg.
// [31] Demand or handshake mode; [30] Dreq synchronization; [29] Enable interrupt
// [28] size of an atomic transfer; [27] service mode; [26:24]DMA request souce(001= uart0);
// [22] reload on/off; [19:0] initial transfer count
rDMASKTRIG0=(0<<2)+(1<<1)+0; // [2] STOP; [1] ON_OFF; [0] SW_TRIG;
//no-stop, DMA0 channel on, no-sw trigger
while(co>0)
{
if(mass_1 == 2) // Массив1 готов к записи
{
if (fl_fwrite(&Rx_buffer1, 1, sizeof(Rx_buffer1), file) != sizeof(Rx_buffer1)) //Записываем готовый массив на флешку
Uart_Printf("ERROR: Write file failed\n");
for(i=0;i<65535;i++) //Чистим rx buffer1
Rx_buffer1[i] = 0;
mass_1 = 0; // Массив 1 отключен
mass_2 = 1; // Массив 2 - заполняется DMA
co--;
}
if(mass_2 == 2)
{
if (fl_fwrite(&Rx_buffer2, 1, sizeof(Rx_buffer2), file) != sizeof(Rx_buffer2)) //Записываем массив на флешку
Uart_Printf("ERROR: Write file failed\n");
for(i=0;i<65535;i++) //Чистим rx buffer2
Rx_buffer2[i] = 0;
mass_2 = 0; // Массив 1 отключен
mass_1 = 1; // Массив 2 - заполняется DMA
co--;
}
rINTMSK |= (BIT_DMA0); // Выключаем прерывания от DMA
rDMASKTRIG0=(1<<2); //DMA0 stop
}
fl_fclose(file); // Закрываем файл
// Обработчик прерывания DMA
void __irq DMA_end(void)
{
ClearPending(BIT_DMA0);
if(mass_1 == 1)
{
mass_1 = 2; // Массив 1 заполнен и готов к записи на флешку
rDIDST0=(U32)(&Rx_buffer2); // Подставляем массив 2
}
else if(mass_2 == 1)
{
mass_2 = 2; // Массив 2 заполнен и готов к записи на флешку
rDIDST0=(U32)(&Rx_buffer1); // Подставляем массив 1
}
}