示例#1
0
/* Configure I2S for Audio Format input */
Status Chip_I2S_TxConfig(LPC_I2S_T *pI2S, I2S_AUDIO_FORMAT_T *format)
{
    uint32_t temp;
    uint16_t xDiv, yDiv;
    uint32_t N;

    if (getClkDiv(pI2S, format, &xDiv, &yDiv, &N) == ERROR) {
        return ERROR;
    }

    temp = pI2S->DAO & (~(I2S_DAO_WORDWIDTH_MASK | I2S_DAO_MONO | I2S_DAO_SLAVE | I2S_DAO_WS_HALFPERIOD_MASK));
    if (format->WordWidth <= 8) {
        temp |= I2S_WORDWIDTH_8;
    }
    else if (format->WordWidth <= 16) {
        temp |= I2S_WORDWIDTH_16;
    }
    else {
        temp |= I2S_WORDWIDTH_32;
    }

    temp |= (format->ChannelNumber) == 1 ? I2S_MONO : I2S_STEREO;
    temp |= I2S_MASTER_MODE;
    temp |= I2S_DAO_WS_HALFPERIOD(format->WordWidth - 1);
    pI2S->DAO = temp;
    pI2S->TXMODE = I2S_TXMODE_CLKSEL(0);
    pI2S->TXBITRATE = N - 1;
    pI2S->TXRATE = yDiv | (xDiv << 8);
    return SUCCESS;
}
示例#2
0
/* Configure I2S for Audio Format input */
Status Chip_I2S_Config(LPC_I2S_T *pI2S, uint8_t TRMode, Chip_I2S_Audio_Format_T *audio_format)
{
	uint32_t pClk;
	uint32_t x, y;
	uint64_t divider;
	uint16_t dif;
	uint16_t x_divide = 0, y_divide = 0;
	uint32_t N;
	uint16_t err, ErrorOptimal = 0xFFFF;

	Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_I2S);
#if defined(CHIP_LPC175X_6X)
	pClk = Chip_Clock_GetPeripheralClockRate(SYSCTL_PCLK_I2S);
#else
	pClk = Chip_Clock_GetPeripheralClockRate();
#endif

	/* divider is a fixed point number with 16 fractional bits */
	divider = (((uint64_t) (audio_format->SampleRate) * 2 * (audio_format->WordWidth) * 2) << 16) / pClk;
	/* find N that make x/y <= 1 -> divider <= 2^16 */
	for (N = 64; N > 0; N--) {
		if ((divider * N) < (1 << 16)) {
			break;
		}
	}
	if (N == 0) {
		return ERROR;
	}
	divider *= N;
	for (y = 255; y > 0; y--) {
		x = y * divider;
		if (x & (0xFF000000)) {
			continue;
		}
		dif = x & 0xFFFF;
		if (dif > 0x8000) {
			err = 0x10000 - dif;
		}
		else {
			err = dif;
		}
		if (err == 0) {
			y_divide = y;
			break;
		}
		else if (err < ErrorOptimal) {
			ErrorOptimal = err;
			y_divide = y;
		}
	}
	x_divide = ((uint64_t) y_divide * (audio_format->SampleRate) * 2 * (audio_format->WordWidth) * N * 2) / pClk;
	if (x_divide >= 256) {
		x_divide = 0xFF;
	}
	if (x_divide == 0) {
		x_divide = 1;
	}
	if (audio_format->WordWidth <= 8) {
		IP_I2S_SetWordWidth(pI2S, TRMode, I2S_WORDWIDTH_8);
	}
	else if (audio_format->WordWidth <= 16) {
		IP_I2S_SetWordWidth(pI2S, TRMode, I2S_WORDWIDTH_16);
	}
	else {
		IP_I2S_SetWordWidth(pI2S, TRMode, I2S_WORDWIDTH_32);
	}
	IP_I2S_SetMono(pI2S, TRMode, (audio_format->ChannelNumber) == 1 ? I2S_MONO : I2S_STEREO);
	IP_I2S_SetMasterSlaveMode(pI2S, TRMode, I2S_MASTER_MODE);
	IP_I2S_SetWS_Halfperiod(pI2S, TRMode, audio_format->WordWidth - 1);
	IP_I2S_ModeConfig(pI2S, TRMode, I2S_TXMODE_CLKSEL(0), !I2S_TXMODE_4PIN_ENABLE, !I2S_TXMODE_MCENA);
	IP_I2S_SetBitRate(pI2S, TRMode, N - 1);
	IP_I2S_SetXYDivider(pI2S, TRMode, x_divide, y_divide);
	return SUCCESS;
}