Перейти к содержанию
    

McASP на передачу данных в L138 в TDM режиме

Всем привет!

Никак у меня не получается добиться от L138 чтобы он нормально выдавал данные на ARX15 ногу в TDM режиме.

На прием все работает. А вот передать данные никак не получается. На ножке вообще ничего нет... Тишина да и только.

 

Использую внешний клок для на AHCLKX ноге. FSYNC формирую уже внутри.

Так вот, клок на ACLKX пине есть, на FSYNC тоже есть. Это я сделал. Но вот данные никак не выходят. При этом с приемом все в порядке. :)

 

Есть ли у кого пример, как запрограммировать McASP в TDM? Формат не важен. Нужно чтобы что-нибуть в TDM выдавалось. :)

 

Спасибо. :)

Изменено пользователем Russky

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Сериализаторы-то настроили?

 

PS: Я конечно могу выложить сюда свою функцию конфигурящую McASP, но боюсь что Вы не разберётесь в ней :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Сериализаторы-то настроили?

Да. Вот вчера даже данные удалось получить. Но тут другие грабли всплыли. Сейчас опишу проблему. :)

 

В общем проблема была с форматом. Если приемник имеет отличный от передатчика формат (регистры XFMT и RFMT), то если мы решаем работать в TDM режиме в отдельных слотах (XTDM регистр), то передатчик просто сходит с ума и нифига не выдает нифига.

Поэтому, надо либо разрешать слоты на всю длину фрейма, либо надо устанавливать формат приемника таким-же как и передатчика. :)

 

В общем как-то так. :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Естественно frame sync должен быть одинаковым. Хотя расположение данных внутри него может быть разным.

У меня в проекте 3 сериализатора McASP принимают пакеты с сэмплами от 3 SPI-ADC (8 канальные, по 9 24-битных слов в пакете), а один сериализатор - выдаёт

кадры на I2S-кодек (левый и правый каналы). И всё это работает одновременно.

Хотя делал это давно и детали уже вспоминаются с трудом.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Приветствую.

Возникли вопросы с настройкой и работой McASP при приёме TDM сигнала (пробую настраивать 32 слота по 8 бит или 16 слотов по 16 бит). Процессор AM1808, схема на рисунке.

Инициализация:

void McAsp::Init()
{
unsigned int reg_data;
unsigned int mask;

// 1. Reset McASP to default values
HWREG(base_addr + MCASP_GBLCTL) = 0;

// 2. Configure McASP Audio FIFO
HWREG(fifoctrl_base_addr + MCASP_FIFO_WFIFOCTL) = 0;
HWREG(fifoctrl_base_addr + MCASP_FIFO_RFIFOCTL) = 0;

// 3.
// 3.1 XMT
HWREG(base_addr + MCASP_XMASK) = 0xFFFFFFFF;

HWREG(base_addr + MCASP_XFMT) = ((MCASP_XFMT_XROT_NONE << MCASP_XFMT_XROT_SHIFT) |
								(1 << MCASP_XFMT_XBUSEL_SHIFT) |
								(MCASP_XFMT_XSSZ_16BITS << MCASP_XFMT_XSSZ_SHIFT) |
								(0 << MCASP_XFMT_XPBIT_SHIFT) |
								(0 << MCASP_XFMT_XPAD_SHIFT) |
								(1 << MCASP_XFMT_XRVRS_SHIFT) |
								(MCASP_XFMT_XDATDLY_0BIT << MCASP_XFMT_XDATDLY_SHIFT));

HWREG(base_addr + MCASP_AFSXCTL) = ((1 << MCASP_AFSXCTL_FSXP_SHIFT) |
									(0 << MCASP_AFSXCTL_FSXM_SHIFT) |
									(0 << MCASP_AFSXCTL_FXWID_SHIFT) |
									(16 << MCASP_AFSXCTL_XMOD_SHIFT));

HWREG(base_addr + MCASP_ACLKXCTL) = ((1 << MCASP_ACLKXCTL_CLKXDIV_SHIFT) |
									(1 << MCASP_ACLKXCTL_CLKXM_SHIFT) |
									(0 << MCASP_ACLKXCTL_ASYNC_SHIFT) |
									(0 << MCASP_ACLKXCTL_CLKXP_SHIFT));

HWREG(base_addr + MCASP_AHCLKXCTL) = ((0 << MCASP_AHCLKXCTL_HCLKXM_SHIFT) |
									(1 << MCASP_AHCLKXCTL_HCLKXP_SHIFT));

HWREG(base_addr + MCASP_XTDM) = (1 << MCASP_XTDM_XTDMS1_SHIFT);

HWREG(base_addr + MCASP_XINTCTL) = 0;

HWREG(base_addr + MCASP_XCLKCHK) = ((MCASP_XCLKCHK_XPS_DIVBY32 << MCASP_XCLKCHK_XPS_SHIFT) |
									(0 << MCASP_XCLKCHK_XMIN_SHIFT) |
									(255 << MCASP_XCLKCHK_XMAX_SHIFT));

// 3.2 RCV
HWREG(base_addr + MCASP_RMASK) = 0xFFFFFFFF;

HWREG(base_addr + MCASP_RFMT) = ((MCASP_RFMT_RROT_NONE << MCASP_RFMT_RROT_SHIFT) |
								(1 << MCASP_RFMT_RBUSEL_SHIFT) |
								(MCASP_RFMT_RSSZ_16BITS << MCASP_RFMT_RSSZ_SHIFT) |
								(0 << MCASP_RFMT_RPBIT_SHIFT) |
								(0 << MCASP_RFMT_RPAD_SHIFT) |
								(1 << MCASP_RFMT_RRVRS_SHIFT) |
								(MCASP_RFMT_RDATDLY_0BIT << MCASP_RFMT_RDATDLY_SHIFT));

HWREG(base_addr + MCASP_AFSRCTL) = ((1 << MCASP_AFSRCTL_FSRP_SHIFT) |
									(16 << MCASP_AFSRCTL_RMOD_SHIFT));

HWREG(base_addr + MCASP_ACLKRCTL) = 0;

HWREG(base_addr + MCASP_AHCLKRCTL) = 0;

HWREG(base_addr + MCASP_RTDM) = (1 << MCASP_RTDM_RTDMS1_SHIFT);

HWREG(base_addr + MCASP_RINTCTL) = 0xFF;//(1 << MCASP_RINTCTL_RSTAFRM_SHIFT);

HWREG(base_addr + MCASP_RCLKCHK) = ((MCASP_RCLKCHK_RPS_DIVBY32 << MCASP_RCLKCHK_RPS_SHIFT) |
									(0 << MCASP_RCLKCHK_RMIN_SHIFT) |
									(255 << MCASP_RCLKCHK_RMAX_SHIFT));

HWREG(base_addr + MCASP_SRCTL(13)) = ((MCASP_SRCTL13_SRMOD_XMT << MCASP_SRCTL13_SRMOD_SHIFT) |
									(MCASP_SRCTL13_DISMOD_HIGH << MCASP_SRCTL13_DISMOD_SHIFT));

HWREG(base_addr + MCASP_SRCTL(14)) = ((MCASP_SRCTL14_SRMOD_RCV << MCASP_SRCTL14_SRMOD_SHIFT) |
									(MCASP_SRCTL14_DISMOD_3STATE << MCASP_SRCTL13_DISMOD_SHIFT));

HWREG(base_addr + MCASP_PFUNC) = 0;

HWREG(base_addr + MCASP_PDIR) = (1 << MCASP_PDIR_AXR13_SHIFT);

HWREG(base_addr + MCASP_DITCTL) = 0;

HWREG(base_addr + MCASP_DLBCTL) = 0;

HWREG(base_addr + MCASP_AMUTE) = 0;

// 4.
mask = ((1 << MCASP_GBLCTL_XHCLKRST_SHIFT) | (1 << MCASP_GBLCTL_RHCLKRST_SHIFT));
reg_data = HWREG(base_addr + MCASP_XGBLCTL);

do
{
	reg_data |= mask;
	HWREG(base_addr + MCASP_GBLCTL) = reg_data;
	reg_data = HWREG(base_addr + MCASP_XGBLCTL);
}
while((!(reg_data & MCASP_GBLCTL_XHCLKRST)) || (!(reg_data & MCASP_GBLCTL_RHCLKRST)));

// 5.
mask = ((1 << MCASP_GBLCTL_XCLKRST_SHIFT) | (1 << MCASP_GBLCTL_RCLKRST_SHIFT));
reg_data = HWREG(base_addr + MCASP_XGBLCTL);

do
{
	reg_data |= mask;
	HWREG(base_addr + MCASP_GBLCTL) = reg_data;
	reg_data = HWREG(base_addr + MCASP_XGBLCTL);
}
while((!(reg_data & MCASP_GBLCTL_XCLKRST)) || (!(reg_data & MCASP_GBLCTL_RCLKRST)));

// 6.

// 7.
HWREG(base_addr + MCASP_XSTAT) = 0xFFFF;
HWREG(base_addr + MCASP_RSTAT) = 0xFFFF;

mask = ((1 << MCASP_GBLCTL_XSRCLR_SHIFT) | (1 << MCASP_GBLCTL_RSRCLR_SHIFT));
reg_data = HWREG(base_addr + MCASP_XGBLCTL);
do
{
	reg_data |= mask;
	HWREG(base_addr + MCASP_GBLCTL) = reg_data;
	reg_data = HWREG(base_addr + MCASP_XGBLCTL);
}
while((!(reg_data & MCASP_GBLCTL_XSRCLR)) || (!(reg_data & MCASP_GBLCTL_RSRCLR)));

// 9.
mask = ((1 << MCASP_GBLCTL_XSMRST_SHIFT) | (1 << MCASP_GBLCTL_RSMRST_SHIFT));
reg_data = HWREG(base_addr + MCASP_XGBLCTL);
do
{
	reg_data |= mask;
	HWREG(base_addr + MCASP_GBLCTL) = reg_data;
	reg_data = HWREG(base_addr + MCASP_XGBLCTL);
}
while((!(reg_data & MCASP_GBLCTL_XSMRST)) || (!(reg_data & MCASP_GBLCTL_RSMRST)));

// 10.
mask = ((1 << MCASP_GBLCTL_XFRST_SHIFT) | (1 << MCASP_GBLCTL_RFRST_SHIFT));
reg_data = HWREG(base_addr + MCASP_XGBLCTL);
do
{
	reg_data |= mask;
	HWREG(base_addr + MCASP_GBLCTL) = reg_data;
	reg_data = HWREG(base_addr + MCASP_XGBLCTL);
}
while((!(reg_data & MCASP_GBLCTL_XFRST)) || (!(reg_data & MCASP_GBLCTL_RFRST)));

}

При разрешении всех возможных прерываний от приёмника и настройке обработчика прерывания, в данный обработчик не попадаем. При попытке передачи данных сбрасывается бит XRDY и при ожидании его установки - висит в цикле. Отправку данных делаю так:

void McAsp::Send(unsigned char *data)
{
    unsigned int reg_data;

    reg_data = HWREG(base_addr + MCASP_SRCTL(13));

    if(reg_data & MCASP_SRCTL13_XRDY)
    {
        HWREG(base_addr + MCASP_XBUF(13)) = *data;
        reg_data = ~(MCASP_SRCTL13_XRDY);
        while(!(reg_data & MCASP_SRCTL13_XRDY))
        {
            reg_data = HWREG(base_addr + MCASP_SRCTL(13));
        }
    }
}

В начале происходит настройка pinmux для McASP, вроде, всё верно настраиваю:

#define PINMUX0_AHCLKX_ENABLE    (SYSCFG_PINMUX0_PINMUX0_23_20_AHCLKX0 << SYSCFG_PINMUX0_PINMUX0_23_20_SHIFT)
#define PINMUX0_AFSX_ENABLE        (SYSCFG_PINMUX0_PINMUX0_15_12_AFSX0 << SYSCFG_PINMUX0_PINMUX0_15_12_SHIFT)
#define PINMUX1_AXR13_ENABLE    (SYSCFG_PINMUX1_PINMUX1_11_8_AXR0_13 << SYSCFG_PINMUX1_PINMUX1_11_8_SHIFT)
#define PINMUX1_AXR14_ENABLE    (SYSCFG_PINMUX1_PINMUX1_7_4_AXR0_14 << SYSCFG_PINMUX1_PINMUX1_7_4_SHIFT)

void PinMux::McAspMux()
{
    unsigned int savePinmux;

    savePinmux = ( HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(0)) & ~(SYSCFG_PINMUX0_PINMUX0_23_20 | SYSCFG_PINMUX0_PINMUX0_15_12) );
    HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(0)) = (PINMUX0_AHCLKX_ENABLE | PINMUX0_AFSX_ENABLE | savePinmux);

    savePinmux = ( HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(1)) & ~(SYSCFG_PINMUX1_PINMUX1_11_8 | SYSCFG_PINMUX1_PINMUX1_7_4) );
    HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(1)) = (PINMUX1_AXR13_ENABLE | PINMUX1_AXR14_ENABLE | savePinmux);
}

есть включение модуля McASP в начале программы:

PSCModuleControl(SOC_PSC_1_REGS, HW_PSC_MCASP0, PSC_POWERDOMAIN_ALWAYS_ON, PSC_MDCTL_NEXT_ENABLE);

Всё, вроде как, настраиваю правильно, но не работает.

 

Замечено странное поведение: состояние регистра GBLCTL после инициализации McASP отличается от регистров XGBLCTL и RGBLCTL, запись в бит 0 для GBLCTL отображается в регистрах XGBLCTL и RGBLCTL, а в нём самом НЕТ.

post-63539-1407310515_thumb.jpg

post-63539-1407311836_thumb.jpg

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Немного поправил настройки McASP, счас могу принимать правильные данные от модема.

void McAsp::Init()
{
unsigned int reg_data;
unsigned int mask;

// 1. Reset McASP to default values
HWREG(base_addr + MCASP_GBLCTL) = 0;

// 2. Configure McASP Audio FIFO
HWREG(fifoctrl_base_addr + MCASP_FIFO_WFIFOCTL) = 0;
HWREG(fifoctrl_base_addr + MCASP_FIFO_RFIFOCTL) = 0;

// 3.
// 3.1 XMT
HWREG(base_addr + MCASP_XMASK) = 0xFF;

HWREG(base_addr + MCASP_XFMT) = ((MCASP_XFMT_XROT_NONE << MCASP_XFMT_XROT_SHIFT) |
								(1 << MCASP_XFMT_XBUSEL_SHIFT) |
								//(MCASP_XFMT_XSSZ_16BITS << MCASP_XFMT_XSSZ_SHIFT) |
								(MCASP_XFMT_XSSZ_8BITS << MCASP_XFMT_XSSZ_SHIFT) |
								(0 << MCASP_XFMT_XPBIT_SHIFT) |
								(0 << MCASP_XFMT_XPAD_SHIFT) |
								(1 << MCASP_XFMT_XRVRS_SHIFT) |
								(MCASP_XFMT_XDATDLY_1BIT << MCASP_XFMT_XDATDLY_SHIFT));

HWREG(base_addr + MCASP_AFSXCTL) = ((1 << MCASP_AFSXCTL_FSXP_SHIFT) |
									(0 << MCASP_AFSXCTL_FSXM_SHIFT) |
									(0 << MCASP_AFSXCTL_FXWID_SHIFT) |
									(32 << MCASP_AFSXCTL_XMOD_SHIFT));
									//(16 << MCASP_AFSXCTL_XMOD_SHIFT));

HWREG(base_addr + MCASP_ACLKXCTL) = ((1 << MCASP_ACLKXCTL_CLKXDIV_SHIFT) |
									(1 << MCASP_ACLKXCTL_CLKXM_SHIFT) |
									(0 << MCASP_ACLKXCTL_ASYNC_SHIFT) |
									(0 << MCASP_ACLKXCTL_CLKXP_SHIFT));

HWREG(base_addr + MCASP_AHCLKXCTL) = ((0 << MCASP_AHCLKXCTL_HCLKXM_SHIFT) |
									(0 << MCASP_AHCLKXCTL_HCLKXP_SHIFT));

HWREG(base_addr + MCASP_XTDM) = (1 << MCASP_XTDM_XTDMS0_SHIFT);

HWREG(base_addr + MCASP_XINTCTL) = 0;

HWREG(base_addr + MCASP_XCLKCHK) = ((MCASP_XCLKCHK_XPS_DIVBY32 << MCASP_XCLKCHK_XPS_SHIFT) |
									(0 << MCASP_XCLKCHK_XMIN_SHIFT) |
									(255 << MCASP_XCLKCHK_XMAX_SHIFT));

// 3.2 RCV
HWREG(base_addr + MCASP_RMASK) = 0xFF;

HWREG(base_addr + MCASP_RFMT) = ((MCASP_RFMT_RROT_NONE << MCASP_RFMT_RROT_SHIFT) |
								(1 << MCASP_RFMT_RBUSEL_SHIFT) |
								//(MCASP_RFMT_RSSZ_16BITS << MCASP_RFMT_RSSZ_SHIFT) |
								(MCASP_RFMT_RSSZ_8BITS << MCASP_RFMT_RSSZ_SHIFT) |
								(0 << MCASP_RFMT_RPBIT_SHIFT) |
								(0 << MCASP_RFMT_RPAD_SHIFT) |
								(1 << MCASP_RFMT_RRVRS_SHIFT) |
								(MCASP_RFMT_RDATDLY_1BIT << MCASP_RFMT_RDATDLY_SHIFT));

HWREG(base_addr + MCASP_AFSRCTL) = ((1 << MCASP_AFSRCTL_FSRP_SHIFT) |
									//(16 << MCASP_AFSRCTL_RMOD_SHIFT));
									(32 << MCASP_AFSRCTL_RMOD_SHIFT));

HWREG(base_addr + MCASP_ACLKRCTL) = 0;

HWREG(base_addr + MCASP_AHCLKRCTL) = 0;

//HWREG(base_addr + MCASP_RTDM) = (1 << MCASP_RTDM_RTDMS1_SHIFT);
HWREG(base_addr + MCASP_RTDM) = (1 << MCASP_RTDM_RTDMS0_SHIFT);

HWREG(base_addr + MCASP_RINTCTL) = 0xFF;//(1 << MCASP_RINTCTL_RSTAFRM_SHIFT);

HWREG(base_addr + MCASP_RCLKCHK) = ((MCASP_RCLKCHK_RPS_DIVBY32 << MCASP_RCLKCHK_RPS_SHIFT) |
									(0 << MCASP_RCLKCHK_RMIN_SHIFT) |
									(255 << MCASP_RCLKCHK_RMAX_SHIFT));

HWREG(base_addr + MCASP_SRCTL(13)) = ((MCASP_SRCTL13_SRMOD_XMT << MCASP_SRCTL13_SRMOD_SHIFT) |
									(MCASP_SRCTL13_DISMOD_HIGH << MCASP_SRCTL13_DISMOD_SHIFT));

HWREG(base_addr + MCASP_SRCTL(14)) = ((MCASP_SRCTL14_SRMOD_RCV << MCASP_SRCTL14_SRMOD_SHIFT) |
									(MCASP_SRCTL14_DISMOD_3STATE << MCASP_SRCTL13_DISMOD_SHIFT));

HWREG(base_addr + MCASP_PFUNC) = 0;

HWREG(base_addr + MCASP_PDIR) = (1 << MCASP_PDIR_AXR13_SHIFT);

HWREG(base_addr + MCASP_DITCTL) = 0;

HWREG(base_addr + MCASP_DLBCTL) = 0;

HWREG(base_addr + MCASP_AMUTE) = 0;

// 4.
mask = ((1 << MCASP_GBLCTL_XHCLKRST_SHIFT) | (1 << MCASP_GBLCTL_RHCLKRST_SHIFT));
reg_data = HWREG(base_addr + MCASP_XGBLCTL);

do
{
	reg_data |= mask;
	HWREG(base_addr + MCASP_GBLCTL) = reg_data;
	reg_data = HWREG(base_addr + MCASP_XGBLCTL);
}
while((!(reg_data & MCASP_GBLCTL_XHCLKRST)) || (!(reg_data & MCASP_GBLCTL_RHCLKRST)));

// 5.
mask = ((1 << MCASP_GBLCTL_XCLKRST_SHIFT) | (1 << MCASP_GBLCTL_RCLKRST_SHIFT));
reg_data = HWREG(base_addr + MCASP_XGBLCTL);

do
{
	reg_data |= mask;
	HWREG(base_addr + MCASP_GBLCTL) = reg_data;
	reg_data = HWREG(base_addr + MCASP_XGBLCTL);
}
while((!(reg_data & MCASP_GBLCTL_XCLKRST)) || (!(reg_data & MCASP_GBLCTL_RCLKRST)));

// 6.

// 7.
HWREG(base_addr + MCASP_XSTAT) = 0xFFFF;
HWREG(base_addr + MCASP_RSTAT) = 0xFFFF;

mask = ((1 << MCASP_GBLCTL_XSRCLR_SHIFT) | (1 << MCASP_GBLCTL_RSRCLR_SHIFT));
reg_data = HWREG(base_addr + MCASP_XGBLCTL);
do
{
	reg_data |= mask;
	HWREG(base_addr + MCASP_GBLCTL) = reg_data;
	reg_data = HWREG(base_addr + MCASP_XGBLCTL);
}
while((!(reg_data & MCASP_GBLCTL_XSRCLR)) || (!(reg_data & MCASP_GBLCTL_RSRCLR)));

// 9.
mask = ((1 << MCASP_GBLCTL_XSMRST_SHIFT) | (1 << MCASP_GBLCTL_RSMRST_SHIFT));
reg_data = HWREG(base_addr + MCASP_XGBLCTL);
do
{
	reg_data |= mask;
	HWREG(base_addr + MCASP_GBLCTL) = reg_data;
	reg_data = HWREG(base_addr + MCASP_XGBLCTL);
}
while((!(reg_data & MCASP_GBLCTL_XSMRST)) || (!(reg_data & MCASP_GBLCTL_RSMRST)));

// 10.
mask = ((1 << MCASP_GBLCTL_XFRST_SHIFT) | (1 << MCASP_GBLCTL_RFRST_SHIFT));
reg_data = HWREG(base_addr + MCASP_XGBLCTL);
do
{
	reg_data |= mask;
	HWREG(base_addr + MCASP_GBLCTL) = reg_data;
	reg_data = HWREG(base_addr + MCASP_XGBLCTL);
}
while((!(reg_data & MCASP_GBLCTL_XFRST)) || (!(reg_data & MCASP_GBLCTL_RFRST)));

}

Но прерывания так и не работают, для приёма данных приходится опрашивать флаг RRDY. Также есть что-то непонятное с запуском McASP, иногда запускается и приёма нет, необходимо несколько раз включать-выключать устройство, от которого модем принимает данные по аналоговой линии и тогда McASP заводится (сигнал фрэйма и клоки на McASP присутствуют независимо от наличия данных на аналоговом входе модема, при отсутствии полезного сигнала выдаётся рандом и сигналы синхронизации).

Передатчик не работает, один раз происходит запись в XBUF далее XRDY сбрасывается в ноль и таким и остаётся???

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Но прерывания так и не работают, для приёма данных приходится опрашивать флаг RRDY.

А зачем Вам прерывания от него? Я даже и не пытался их использовать - сразу делал с DMA и прерывания уже от DMA.

 

Также есть что-то непонятное с запуском McASP, иногда запускается и приёма нет, необходимо несколько раз включать-выключать устройство, от которого модем принимает данные по аналоговой линии и тогда McASP заводится (сигнал фрэйма и клоки на McASP присутствуют независимо от наличия данных на аналоговом входе модема, при отсутствии полезного сигнала выдаётся рандом и сигналы синхронизации).

Эххх!!! Давно это уже было, всё подзабыл...

Но насколько помню - запускать компоненты McASP нужно было в определённом порядке (регистр GBLCTL).

У меня по-крайней мере так делается:

...
McASP1_GBLCTL(B1 | B9);           //XHCLK,RHCLK on
McASP1_GBLCTL(B1 | B9 | B0 | B8); //XHCLK,RHCLK,XCLK,RCLK on
McASP1_GBLCTL(B1 | B9 | B0 | B8 | B2 | B10);
McASP1_GBLCTL(B1 | B9 | B0 | B8 | B2 | B10 | B3 | B11);
McASP1_GBLCTL(B1 | B9 | B0 | B8 | B2 | B10 | B3 | B11 | B4 | B12);
...

Здесь между строками включения отдельных модулей McASP ещё конечно идут записи в соотв. регистры конфигурации McASP.

static void McASP1_GBLCTL(u32 val)
{
  for (MCASP[1].GBLCTL = val; MCASP[1].GBLCTL != val; );
}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А зачем Вам прерывания от него? Я даже и не пытался их использовать - сразу делал с DMA и прерывания уже от DMA.

Просто хочется быстрее проверить приём данных, такой же модем висит на McBSP и сходу настроить фифо как-то не получилось, а с чтением данных из DRR по прерыванию всё нормально работает, вот и решил тут пока поступить также.

 

 

Эххх!!! Давно это уже было, всё подзабыл...

Но насколько помню - запускать компоненты McASP нужно было в определённом порядке (регистр GBLCTL).

У меня по-крайней мере так делается:

...
McASP1_GBLCTL(B1 | B9);           //XHCLK,RHCLK on
McASP1_GBLCTL(B1 | B9 | B0 | B8); //XHCLK,RHCLK,XCLK,RCLK on
McASP1_GBLCTL(B1 | B9 | B0 | B8 | B2 | B10);
McASP1_GBLCTL(B1 | B9 | B0 | B8 | B2 | B10 | B3 | B11);
McASP1_GBLCTL(B1 | B9 | B0 | B8 | B2 | B10 | B3 | B11 | B4 | B12);
...

Делал по даташиту, счас перепроверил - моя последовательность настройки GBLCTL совпадает с Вашей, выше можно увидеть. Я ещё добавил чтение для проверки установки соответствующего бита (тож в даташите про это писали), только читаю не GBLCTL, а - XGBLCTL, т.к. в GBLCTL 0-й бит почему-то не устанавливается (выше скриншот приводил), а в XGBLCTL и RGBLCTL при записи в GBLCTL - устанавливается.

 

 

Сразу не заметил - у Вас там тоже чтение идёт после записи. Вот если у меня такую процедуру делать, то всё повиснет в цикле выполнения

McASP1_GBLCTL(B1 | B9 | B0 | B8);

: нулевой бит никогда не установится в 1, хотя в XGBLCTL и RGBLCTL отобразится правильно 1.

 

Здесь между строками включения отдельных модулей McASP ещё конечно идут записи в соотв. регистры конфигурации McASP.

У меня, согласно даташиту, вся конфигурация (почти вся) идёт в начале инициализации, а запись в GBLCTL идёт последней. Можно увидеть всю Вашу последовательность настройки McASP?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

У меня, согласно даташиту, вся конфигурация (почти вся) идёт в начале инициализации, а запись в GBLCTL идёт последней. Можно увидеть всю Вашу последовательность настройки McASP?

Это трудно, так как конфигурение McASP у меня не находится в одной функции.

Где-то в начале:

WiresSet();  //установка PDOUT,PDIR,PFUNC
McASP1_GBLCTL(0);
MCASP[1].FIFO.WFIFOCTL = MCASP[1].FIFO.RFIFOCTL = 0;
MCASP[1].XINTCTL = MCASP[1].RINTCTL = 0;
MCASP[1].AMUTE = MCASP[1].DLBCTL = MCASP[1].DITCTL = 0;
MCASP[1].RMASK = MCASP[1].XMASK = ~0;
MCASP[1].AHCLKRCTL = AUXCLK / ADC_CLK - 1 | B15;
MCASP[1].ACLKRCTL = B5;
MCASP[1].AHCLKXCTL = AUXCLK / ADC_SCLK - 1 | B15;
MCASP[1].ACLKXCTL = B5 | B7;
McASP1_GBLCTL(B1 | B9);           //!<XHCLK,RHCLK on
McASP1_GBLCTL(B1 | B9 | B0 | B8); //!<XHCLK,RHCLK,XCLK,RCLK on

Далее, непосредственно перед стартом передачи:

static void StartStream()
{
  ...
  if (CmdFrameADC(StartADC) >= 0) {
    streamFaza = SFAZA_STREAM_ADC_NOSYNC;
    return;
  }
  McASP1_GBLCTL(B1 | B9 | B0 | B8);
  MCASP[1].AFSXCTL = MCASP[1].AFSRCTL = B1 | B4 | nSlots << 7;
  MCASP[1].RFMT = MCASP[1].XFMT = 15 << 4 | B15 | 1 << 16;
  MCASP[1].RTDM = (1 << nSlots) - 1 ^ 1;
  MCASP[1].XTDM = B1 | B0;
  while (MCASP[1].RSTAT & B5) { u32 dummy = MCASP[1].DATA.DATA_PORT; }

  ... //инит EDMA

  u32 i, j = 2 << E_DI * 2 | 2 << PM1_DI * 2 | 2 << PM2_DI * 2 | 1 << AUDIO_DO * 2;
  i = ncell(MCASP[1].SRCTL) - 1;
  do {
    MCASP[1].SRCTL[i] = j >> 30 | 2 << 2;
    j <<= 2;
  } while ((s32)--i >= 0);

  MCASP[1].XSTAT = MCASP[1].RSTAT = 255;
  McASP1_GBLCTL(B1 | B9 | B0 | B8 | B2 | B10);
  McASP1_GBLCTL(B1 | B9 | B0 | B8 | B2 | B10 | B3 | B11);

  MCASP[1].PDOUT = 0;
  DelayMcs(1160 * 1000 / ADC_CLK + 5);
  ENTR_CRT_SECTION();
  if (timeCriticalActive) timeCriticalReq = 1;
  else StartStreamSync();
  EXIT_CRT_SECTION();
}

void StartStreamSync()
{
  enum {TOUT_DRDY = 1000000 / ADC_FS * 11 / 10 + 4}; //!<timeout for search of sync pulse DRDY (~ DRDY period increased by 10%) [mcs]
  u32 j = 0, i = GetMcsTimer();
  do {
      while ((MCASP[1].PDIN ^ j) & (1 << E_DI | 1 << PM1_DI | 1 << PM2_DI)) if (istoutMcs(i, TOUT_DRDY)) {
      streamFaza = SFAZA_STREAM_ADC_NOSYNC;
      return;
    }
  } while (!(--j + 1));
  DelayMcs((256 - 12) * 1000 / ADC_CLK);
  MCASP[1].PFUNC = 0;
  McASP1_GBLCTL(B1 | B9 | B0 | B8 | B2 | B10 | B3 | B11 | B4 | B12);
  ptrAdcDmaComplete = AdcDmaCompleteStream;
  streamFaza = SFAZA_STREAM_ADC_BEGIN;
}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Если еще актуально...

Возможные причины не возникновения прерываний от MCASP

0) -не разрешены прерывания глобально и неразрешен вектор NMI

1) -не разрешен соответствующий вектор в ядре (IER)

2) -не смапированы прерывания от MCASP в соответтствующий вектор - (смотреть в настройках контроллера прерываний)

3) -не разрешены источники прерываний MCASP (RINTCTL/XINTCTL)

4) - все флаги в RSTAT/XSTAT должны быть сброшены при запуске MCASP записью единиц в соответствуюшие биты

5) - в обработчике прерывания все флаги в RSTAT/XSTAT нужно сбрасывать руками записью единиц в соответствуюшие биты

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Если еще актуально...

Возможные причины не возникновения прерываний от MCASP

0) -не разрешены прерывания глобально и неразрешен вектор NMI

1) -не разрешен соответствующий вектор в ядре (IER)

2) -не смапированы прерывания от MCASP в соответтствующий вектор - (смотреть в настройках контроллера прерываний)

Настройка прерываний аналогична настройке для остальных устройств, но там всё работает (пока McBSP, EMAC), а тут нет.

3) -не разрешены источники прерываний MCASP (RINTCTL/XINTCTL)

Разрешаю все прерывания от приёмника.

4) - все флаги в RSTAT/XSTAT должны быть сброшены при запуске MCASP записью единиц в соответствуюшие биты

5) - в обработчике прерывания все флаги в RSTAT/XSTAT нужно сбрасывать руками записью единиц в соответствуюшие биты

Флаги сбрасываю.

 

 

Спасибо, смотрю, что же существенно отличается от моей настройки.

 

UP

Можете пояснить эту строчку:

while (MCASP[1].RSTAT & B5) { u32 dummy = MCASP[1].DATA.DATA_PORT; }

 

Я читаю RBUF(x), пишу (пробую писать) XBUF(x) напрямую, правильно ли это??? И проверка идёт не RSTAT, а - SRCTL(x)???

int McAsp::Read(unsigned int *data)
{
    unsigned int reg_data;

    reg_data = HWREG(SOC_MCASP_0_CTRL_REGS + MCASP_SRCTL(14));

    if(MCASP_SRCTL14_RRDY & reg_data)
    {
        *data = HWREG(SOC_MCASP_0_CTRL_REGS + MCASP_RBUF(14));
        return 1;
    }

    return 0;
}

 

 

 

Ещё не понимаю, каким образом связаны регистры RSTAT, XSTAT и множество RBUF, XBUF? Если у меня несколько каналов используются, то что отражает RSTAT.RDATA? Для каждого канала - свой сериалайзер, для сериалайзера - свой SRCTL(x).RRDY, который отображает наличие приёма в данном канале, а каким образом к статусу приёма для данного канала относится RSTAT.RDATA?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ещё не понимаю, каким образом связаны регистры RSTAT, XSTAT и множество RBUF, XBUF? Если у меня несколько каналов используются, то что отражает RSTAT.RDATA? Для каждого канала - свой сериалайзер, для сериалайзера - свой SRCTL(x).RRDY, который отображает наличие приёма в данном канале, а каким образом к статусу приёма для данного канала относится RSTAT.RDATA?

RSTAT.RDATA - говорит что данные готовы для ВСЕХ активных RX сериалайзеров, т.к. все они:

1) - сидят на одной синхронизации и соответственно параллельно получают данные со входов RX входов;

2) - имеют ОДИНАКОВЫЙ формат кадра.

Для передающей половины все аналогично.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

RSTAT.RDATA - говорит что данные готовы для ВСЕХ активных RX сериалайзеров, т.к. все они:

1) - сидят на одной синхронизации и соответственно параллельно получают данные со входов RX входов;

2) - имеют ОДИНАКОВЫЙ формат кадра.

Для передающей половины все аналогично.

Хорошо, если у меня используются два канала, режим TDM (8 бит на 32 слота), один RBUF(x) получает данные раньше, второй RBUF(x+16) - позже, в регистрах SRCTL(x) и SRCTL(x+16) флаг RRDY установится в момент приёма данных в соответствующем регистре, а что будет с флагом RDATA в регистре RSTAT???

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Можете пояснить эту строчку:

while (MCASP[1].RSTAT & B5) { u32 dummy = MCASP[1].DATA.DATA_PORT; }

Очевидно что здесь я вычищаю приёмный буфер McASP если предыдущая передача закончилась нештатно и в нём могли остаться какие-то данные

(чтобы не было потом сдвижки DMA-кадра на случайное кол-во байт).

 

Я читаю RBUF(x), пишу (пробую писать) XBUF(x) напрямую, правильно ли это??? И проверка идёт не RSTAT, а - SRCTL(x)???

Я писал это уже давно - пару лет назад и опять лезть в даташиты и читать их мне лень, так что могу сказать только то что помню по памяти.

Помню что DATA.DATA_PORT удобно использовать для DMA, так как через него доступны данные всех сериализаторов как единый массив в определённом порядке.

А для программного io можно использовать отдельные XBUF/RBUF.

Так же помню что для написания и запуска этого кода я пользовался только даташитами на McASP, EDMA3 и общим на периферию/SOC.

Никаких примеров и библиотек не использовал и не смотрел. И всё заработало быстро.

Т.е. - этих даташитов вполне достаточно. Наверное надо вам их ещё раз перечитать.

Если-бы по свежей памяти, то думаю я бы смог лучше вам подсказать.

 

В этой моей конфигурации настраивается 3 сериализатора на приём (из 3-х одинаковых источников с одинаковым форматом) и 1 сериализатор на передачу

(формат у него другой, но для McASP это тот-же формат с тем-же размером фрейма и разрядностью).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Спасибо за участие. Какая-то тупиковая ситуация получается, уже много раз всё перепроверил, но не пойму - в чём дело. Инициализацию McASP ещё раз сверил с даташитом, всё соответствует пожеланиям TI.

Счас могу принимать данные от модема (принять, передать по ethernet, записать в файл, послушать музычку), т.е. вижу, что возложенную функцию McASP выполнять может, но добиться сработки прерывания от приёмника так и не получается.

С передатчиком вообще какая-то ерунда, записываю данные в XBUF(x), McASP сбрасывает флаги XDATA и XRDY и они больше не поднимаются. Не могу понять что же может быть причиной такой работы?

Приёмная часть тактируется в моём случае от передающей, т.е. раз там есть возможность правильного приёма, то тут передача должна работать.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...