MAX9860 это 24 pin(овый) чип у которого внутри один 16ти битный Sigma Delta ЦАП, и два AЦП с управлением по I2C. Данные загружаются и выгребаются по I2S. Конфигурация по I2C.
У меня уже было текст обзор аудиокодека WM8731: Чип AudioСodec(а) WM8731 (или (ADC/DAC)*2 из iPod(а))
В этом же тексте будет разбор кодека MAX9860.
Внимание!
C аудиокодеками надо работать с особой осторожностью так как при неправильной конфигурации I2C регистров внутри прошивки, микросхема DAC может сильным звуком контузить программиста. Никогда не надевайте наушники, если вы не уверенны в том, что сейчас будет нормальный звук.
Аппаратная часть
В первом приближении блок схема кодека это рис1. По сути любой аудиокодек это чип у поторого на одном чипе АЦП и ЦАП, регистры конфигурирования и ручка чтобы всем этим управлять. В данном случае этой ручкой является интерфейс I2C. В качестве числопровода для DAC выступает шина I2S.
![рис1 рис1](https://habrastorage.org/getpro/habr/upload_files/b38/79b/da9/b3879bda98334dd550285b6343cb52b1.png)
При более внимательном рассмотрении чип выглядит так. Тут видно усиление сигнала на микрофонах, управление громкостью звука. Возможность включать аналоговый LoopBack. Возможность пропускать сигнал через цифровые фильтры (Эллиптический и Баттерворта) на разных частотах дискретизации 8kHz, 16kHz, 48kHz.
![рис 2 рис 2](https://habrastorage.org/getpro/habr/upload_files/14c/78c/589/14c78c589c5b0231923dc0c66e1a4d08.png)
С точки зрения программиста микроконтроллеров MAX9860 выглядит так
![рис 3 рис 3](https://habrastorage.org/getpro/habr/upload_files/504/80b/331/50480b331e6b4d735e5f12b6e7248688.png)
Кто тактирует чип MAX9860ETG?
Как видно из схемотехники к микросхеме не подключен никакой кварцевый резонатор.
Расспиновка MAX9860ETG
из микросхемы торчат 24 провода. Вот их назначение и смысл
![](https://habrastorage.org/getpro/habr/upload_files/c2c/28b/1e4/c2c28b1e43be76246ac9ad798c534d15.png)
https://docs.google.com/spreadsheets/d/1mQK_JenlkW6HhxwL5-TNvM1IrY6razIMxCsXBa6a-o0/edit?pli=1#gid=0
У микросхемы отсутствует pin reset.
Программирование MAX9860ETG+
У чипа MAX9860ETG 17 8ми битных регистров. Это 136 бит чистых конфигов, где каждый бит чего-то да значит. При этом в карте регистров нет регистра с ID чипа или значения ревизии. Данные передаются по I2C старшим битом вперед.
Что надо конфигурить внутри MAX9860ETG?
У чипа MAX9860 целая куча всяческих настроек. Вот перечень того что можно настраивать в аудиокодеке:
Параметр |
Акроним |
Пояснение |
Регистр настройки |
Единица измерений |
ADC Voice Filter |
AVFLT |
Частота и тип цифрового фильтра для ADC |
0x08 |
Hz |
DAC Voice Filter |
DVFLT |
Частота и тип цифрового фильтра для DAC |
0x08 |
Hz |
level of left ADC output mixed into the DAC |
DVST |
Уровень смешивания сигнала с АЦП с входом ЦАП |
0x0B |
dB |
Microphone Preamp Gain |
PAM |
Предварительное грубое аналоговое усиление микрофона |
0x0C |
dB |
ADC Output Level Left |
ADCLL |
Цифровое Усиление левого микрофона |
0x0A |
? |
ADC Output Level Right |
ADCRL |
Цифровое Усиление правого микрофона |
0x0A |
? |
DAC digital audio level |
DVA |
Ослабление громкоговорителя |
0x09 |
? |
dac gain |
DVG |
Усиление ЦАП спикера |
0x0B |
? |
I2S Bus Role |
MAS |
Роль кодека на шине I2S |
0x06 |
Master/Slave |
Left Microphone PGA |
PGAM |
Предварительное точное аналоговое усиление микрофонов |
0x0C |
dB |
В ядре Linux драйвера для чипа MAX9860 нет. Можете сами убедиться в этом на сайте, который индексирует официальные сорцы Linux.
https://elixir.bootlin.com/linux/latest/A/ident/MAX9860
Однако есть что-то на github
https://github.com/CETIBOX-Base/linux/blob/8058fa542bfee2e19251d90f0c2458d46a14f148/sound/soc/codecs/max9860.c
Как это обычно бывает в электронике, отладочной платы для MAX9860 нет, а сам чип распространяется в микроскопическом и снобском корпусе 24TQFN-EP, который ты в очередной раз видишь впервые.
Поэтому для отладки драйвера чипа надо проектировать плату переходник для банального подключения проводов к микросхеме.
![рис 4 рис 4](https://habrastorage.org/getpro/habr/upload_files/ace/bd2/a48/acebd2a483bd8d3a7bb55af445b164f6.png)
или купить переходник на Aliexpress. Ключевое слово QFN24 Transfer Board 0.5MM. Ждать 5 недель.
![](https://habrastorage.org/getpro/habr/upload_files/4a4/d28/cc2/4a4d28cc2c67fbb451297cb3459fe077.png)
Чип можно конфигурировать по I2C. Базовый адрес равен значению 16=0x10.
address |
address |
address |
|
Addr Type |
dec |
hex |
bin |
write |
32 |
0x20 |
0b0010_0000 |
read |
33 |
0x21 |
0b0010_0001 |
address |
16 |
0x10 |
0b0001_0000 |
Внутри 17 регистров для конфигураций
![](https://habrastorage.org/getpro/habr/upload_files/ba8/f9f/2af/ba8f9f2af8f752c3339cded63b18b30c.png)
Запись I2C регистра выглядит так
![Запись в регистр 7 значения 0x10 Запись в регистр 7 значения 0x10](https://habrastorage.org/getpro/habr/upload_files/d1f/3cf/97d/d1f3cf97d8a67cc2954a1b08cd5ed444.png)
Чтение I2C регистра выглядит так. Тут важно чтобы микроконтроллер генерировал только 1 Stop сигнал в самом конце, даже несмотря та то что в пакете 2 Start сигнала. Команда чтения должна быть монолитная. Иначе из регистра прочитаются нули.
![чтение регистра 0x10 чтение регистра 0x10](https://habrastorage.org/getpro/habr/upload_files/0d0/780/164/0d07801640cd4b01d04391876214fb83.png)
Микросхема отвечает на I2C команды даже если отсутствует тактирование на проводе MCLK. Чтож, до регистров достучались. Научились их читать и писать.
![](https://habrastorage.org/getpro/habr/upload_files/f06/165/9a8/f061659a8ef5d35e3cf165bb2beb6b8d.png)
Как регулировать громкость звука в аудиокодеке MAX9860?
В чипе MAX9860 громкость можно конфигурировать двумя способами:
# |
Register |
Reg Name |
Reg Addr |
Min |
Max |
Step |
Unit |
1 |
DVA |
DAC Attenuation |
0x09 |
-90 |
+3 |
1 |
dB |
2 |
DVG |
DAC Gain |
0x0B |
0 |
+24 |
6 |
dB |
Вот так может выглядеть API для драйвера MAX9860
#ifndef MAX9860_DRV_H
#define MAX9860_DRV_H
#include <stdbool.h>
#include <stdint.h>
#include "i2s_types.h"
#include "max9860_const.h"
#include "max9860_dep.h"
#include "max9860_mic_drv.h"
#include "max9860_speaker_drv.h"
#include "max9860_types.h"
extern const Max9860RegName_t RegNameLUT[];
uint32_t max9860_static_reg_cnt(void);
bool max9860_check(void);
bool max9860_save_mode_set(void);
bool max9860_is_connected(void);
bool max9860_init(void);
bool max9860_reg_set(uint8_t reg_addr, uint8_t reg_val);
bool max9860_reg_set_verify(uint8_t reg_addr, uint8_t reg_val);
bool max9860_reg_get(uint8_t reg_addr, uint8_t* const reg_val);
bool max9860_reg_read_all(void);
bool max9860_proc(void);
bool max9860_bus_role_set(I2sRole_t volume);
bool max9860_write_lazy_reg(uint8_t reg_addr, uint8_t reg_val);
bool max9860_write_reg_by_bitmask(uint8_t reg_addr, char* bit_mask);
bool max9860_reset(void);
bool is_valid_voice_filter(DigitalFilter_t digital_filter);
bool max9860_voice_filter_set(Converter_t converter, DigitalFilter_t digital_filter);
I2sRole_t max9860_bus_role_get(void);
uint32_t max9860_reg_cnt(void);
DigitalFilter_t max9860_voice_filter_get(Converter_t converter);
#endif /* MAX9860_DRV_H */
Часть про DAC
#ifndef MAX9860_SPEAKER_DRV_H
#define MAX9860_SPEAKER_DRV_H
#include <stdbool.h>
#include <stdint.h>
#include "i2s_types.h"
#include "max9860_types.h"
bool max9860_voice_filter_set(Converter_t converter, DigitalFilter_t digital_filter);
bool is_valid_voice_filter(DigitalFilter_t digital_filter);
bool max9860_dac_set(bool on_off);
bool max9860_dac_get(void);
bool max9860_digital_audio_level_set(Gain_t gain);
bool max9860_dac_gain_set(Gain_t gain);
bool max9860_volume_set(uint8_t volume);
DigitalFilter_t max9860_voice_filter_get(Converter_t converter);
Gain_t max9860_digital_audio_level_get(void);
Gain_t max9860_dac_gain_get(void);
Gain_t Code2DvaGain(uint8_t code);
uint8_t DvaGain2Code(Gain_t gain);
uint8_t Gain2DvstCode(Gain_t side_tone_gain);
uint8_t max9860_volume_get(void);
#endif /* MAX9860_SPEAKER_DRV_H */
часть про ADC
#ifndef MAX9860_MIC_DRV_H
#define MAX9860_MIC_DRV_H
#include <stdbool.h>
#include <stdint.h>
#include "i2s_types.h"
#include "max9860_types.h"
bool max9860_sidetone_level_set(SideToneGain_t side_tone_gain);
bool max9860_adc_set(MicChannel_t mic_channel, bool on_off);
bool max9860_adc_get(MicChannel_t mic_channel);
bool max9860_sidetone_set(bool on_off);
bool max9860_digital_audio_level_set(Gain_t gain);
bool max9860_adc_output_level_set(MicChannel_t mic_channel, AdcGain_t adc_gain);
bool is_valid_adc_gain(AdcGain_t adc_gain);
bool max9860_microphone_preamp_set(Gain_t gain);
bool max9860_microphone_programmable_gain_amplifier_set(Gain_t gain);
Gain_t max9860_microphone_programmable_gain_amplifier_get(void);
Gain_t PamCode2Gain(uint8_t pam_code);
AdcGain_t max9860_adc_output_level_get(MicChannel_t mic_channel);
SideToneGain_t max9860_sidetone_level_get(void);
uint8_t Gain2PgamCode(Gain_t gain);
uint8_t Gain2PamCode(Gain_t gain);
uint8_t Gain2DvstCode(Gain_t side_tone_gain);
Gain_t max9860_microphone_preamp_get(void);
SideToneGain_t Code2SideToneGain(uint8_t code);
AdcGain_t AdcCode2Gain(uint8_t code);
Gain_t PgamCode2Gain(uint8_t pgam_code);
uint8_t AdcGain2Code(AdcGain_t adc_gain);
#endif /* MAX9860_MIC_DRV_H */
Достоинства MAX9860
++ I2C регистры можно читать. Это выгодно отличает MAX9860 от WM8731
++ В карте регистров есть регистра с ID чипа ( 0xFF) и значения ревизии. Поэтому получится сделать link тест.
Недостатки MAX9860
1--Только один DAC. Это mono
2--Сравнительно низкая производительность: максимальная частота дискретизации, разрядность.
3--Отсутствие доступных отладочных модулей на основе MAX9860
Как известно, всё познается в сравнении. Вот сравнение MAX9860 с другим распространенным аудио чипом WM8731.
![](https://habrastorage.org/getpro/habr/upload_files/de0/d88/f34/de0d88f3414d3afafd917c203953203d.png)
На фоне WM8731 MAX9860 выглядит более пригодным для ответственных систем. В MAX9860 есть возможность читать регистры, выше мощность сигнала, шире температурный диапазон, ниже частота тактирования, ниже напряжение питания. Однако в MAX9860 меньше производительность. Меньше разрядность, нет stereo, меньше максимальная частота дискретизации.
https://docs.google.com/spreadsheets/d/1r7tuNrQ8PPfIVcM2FeGpwa1eeWjyq41CD0MGq_Q_VV8/edit#gid=0
Можно заметить, что все аудио кодеки по сути это 2 устройства на одном кристалле: DAC и ADC. Если вы используете, например, только DAC, то можно просто не собирать код для ADC. Это упростить ваш проект и увеличит надежность.
Идеи устройств на чипе MAX9860
1-- Караоке
2-- В режиме Sidetone max8960 становится фактически слуховым аппаратом
3-- Звуковой дальномер.
4-- Диктофон.
5-- Плейер *.wav файлов.
6-- Метроном.
7--Громкоговоритель.
8--Осциллограф.
9--(проводная/беспроводная) передача модулированных данных, например FSK модуляцией.
10--Обновление прошивки через звук.
11--Передача бинарных данных по звуку. Интерфейс спикер->микрофон.
12--Датчик шума.
13--Спектро-анализатор.
14--Переносные рации.
Вывод
Это простой чип для воспроизведение и записи звука.
Словарь
Для работы с аудио кодеками надо распознавать следующие акронимы
Акроним |
Расшифровка |
DAC |
Digital-to-analog converter |
GSM |
??? |
PGA |
programmable gain amplifier |
АЦП |
Аналого-цифровой преобразователь |
ЦАП |
Цифро-аналоговый преобразователь |
MCLK |
master clock |
I2C |
Inter-Integrated Circuit |
I2S |
Inter-IC Sound |
PAM |
PreAMp |
24 TQFN-EP |
Exposed pad |
QFN |
Quad Flat No-leads |
TDM |
Time Division Multiplexed |
AGC |
automatic gain control |
MAX |
Maxim Integrated |
PLL |
Phase-locked loop |
ADC |
Analog-to-digital converter |
Links
Купить переходник можно тут.
Чип AudioСodec(а) WM8731 (или (ADC/DAC)*2 из iPod(а))
Вопросы для обсуждения:
С какими микросхемами аудиокодеков работали Вы?
no111u3
https://github.com/torvalds/linux/blob/master/sound/soc/codecs/max9860.c первая же строка в поиске google