Я пытаюсь получить более быстрое AD C, чем стандартное Arduino analogRead(A0)
на ESP8266.
Для этого я предполагаю, что мне нужно будет использовать функции низкого уровня.
И я обнаружил внутри примера кода из ESP8266 SDK есть код драйвера (https://github.com/esp8266/esp8266-wiki/tree/master/sdk) (examples \ IoT_Demo \ driver \ ad c. c)
uint16 ICACHE_FLASH_ATTR adc_read(void)
{
uint8 i;
uint16 sar_dout, tout, sardata[8];
i2c_writeReg_Mask_def(i2c_saradc, i2c_saradc_en_test, 1); //select test mux
//PWDET_CAL_EN=0, PKDET_CAL_EN=0
SET_PERI_REG_MASK(0x60000D5C, 0x200000);
while (GET_PERI_REG_BITS(0x60000D50, 26, 24) > 0); //wait r_state == 0
sar_dout = 0;
CLEAR_PERI_REG_MASK(0x60000D50, 0x02); //force_en=0
SET_PERI_REG_MASK(0x60000D50, 0x02); //force_en=1
os_delay_us(2);
while (GET_PERI_REG_BITS(0x60000D50, 26, 24) > 0); //wait r_state == 0
read_sar_dout(sardata);
for (i = 0; i < 8; i++) {
sar_dout += sardata[i];
ADC_DBG("%d, ", sardata[i]);
}
tout = (sar_dout + 8) >> 4; //tout is 10 bits fraction
i2c_writeReg_Mask_def(i2c_saradc, i2c_saradc_en_test, 1); //select test mux
while (GET_PERI_REG_BITS(0x60000D50, 26, 24) > 0); //wait r_state == 0
CLEAR_PERI_REG_MASK(0x60000D5C, 0x200000);
SET_PERI_REG_MASK(0x60000D60, 0x1); //force_en=1
CLEAR_PERI_REG_MASK(0x60000D60, 0x1); //force_en=1
return tout; //tout is 10 bits fraction
}
Я обнаружил, что у других есть похожие идеи:
https://github.com/esp8266/Arduino/commit/09bb75874deb95c22b4c09e63b842fc1f89eebc3
https://github.com/esp8266/Arduino/issues/696
Что привело меня к
https://github.com/cnlohr/colorchord/blob/master/embedded8266/user/adc.c
Соответствующий код
void ICACHE_FLASH_ATTR hs_adc_start(void)
{
i2c_writeReg_Mask_def(i2c_saradc, i2c_saradc_en_test, 1); //select test mux
//PWDET_CAL_EN=0, PKDET_CAL_EN=0
SET_PERI_REG_MASK(0x60000D5C, 0x200000);
while (GET_PERI_REG_BITS(0x60000D50, 26, 24) > 0); //wait r_state == 0
CLEAR_PERI_REG_MASK(0x60000D50, 0x02); //force_en=0
SET_PERI_REG_MASK(0x60000D50, 0x02); //force_en=1
}
uint16 hs_adc_read(void)
{
uint8 i;
uint16 sardata[8];
uint16_t sar_dout = 0;
while (GET_PERI_REG_BITS(0x60000D50, 26, 24) > 0); //wait r_state == 0
read_sar_dout(sardata);
for (i = 0; i < 8; i++) {
sar_dout += sardata[i];
}
#ifdef OLDWAY_NEEDS_RESTART
//tout = (sar_dout + 8) >> 4; //tout is 10 bits fraction
// ??? Why does this exist ??? It didn't start commented out, but now that I did comment it, it still seems happy.
// i2c_writeReg_Mask_def(i2c_saradc, i2c_saradc_en_test, 1); //select test mux
// while (GET_PERI_REG_BITS(0x60000D50, 26, 24) > 0); //wait r_state == 0
// CLEAR_PERI_REG_MASK(0x60000D5C, 0x200000);
// SET_PERI_REG_MASK(0x60000D60, 0x1); //force_en=1
// CLEAR_PERI_REG_MASK(0x60000D60, 0x1); //force_en=1
#else
//Start reading a new sample.
CLEAR_PERI_REG_MASK(0x60000D50, 0x02); //force_en=0
SET_PERI_REG_MASK(0x60000D50, 0x02); //force_en=1
#endif
return sar_dout; //tout is 10 bits fraction
}
, но когда я пытаюсь скомпилировать
#define ETS_UNCACHED_ADDR(addr) (addr)
#define ETS_CACHED_ADDR(addr) (addr)
#define READ_PERI_REG(addr) (*((volatile uint32_t *)ETS_UNCACHED_ADDR(addr)))
#define WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)ETS_UNCACHED_ADDR(addr))) = (uint32_t)(val)
#define CLEAR_PERI_REG_MASK(reg, mask) WRITE_PERI_REG((reg), (READ_PERI_REG(reg)&(~(mask))))
#define SET_PERI_REG_MASK(reg, mask) WRITE_PERI_REG((reg), (READ_PERI_REG(reg)|(mask)))
#define GET_PERI_REG_BITS(reg, hipos,lowpos) ((READ_PERI_REG(reg)>>(lowpos))&((1<<((hipos)-(lowpos)+1))-1))
#define SET_PERI_REG_BITS(reg,bit_map,value,shift) (WRITE_PERI_REG((reg),(READ_PERI_REG(reg)&(~((bit_map)<<(shift))))|((value)<<(shift)) ))
void ICACHE_FLASH_ATTR hs_adc_start(void)
{
//PWDET_CAL_EN=0, PKDET_CAL_EN=0
SET_PERI_REG_MASK(0x60000D5C, 0x200000);
while (GET_PERI_REG_BITS(0x60000D50, 26, 24) > 0); //wait r_state == 0
CLEAR_PERI_REG_MASK(0x60000D50, 0x02); //force_en=0
SET_PERI_REG_MASK(0x60000D50, 0x02); //force_en=1
}
//extern void read_sar_dout(uint16_t*);
uint16 hs_adc_read(void)
{
uint8 i;
uint16 sardata[8];
uint16_t sar_dout = 0;
while (GET_PERI_REG_BITS(0x60000D50, 26, 24) > 0); //wait r_state == 0
read_sar_dout(sardata);
for (i = 0; i < 8; i++) {
sar_dout += sardata[i];
}
//Start reading a new sample.
CLEAR_PERI_REG_MASK(0x60000D50, 0x02); //force_en=0
SET_PERI_REG_MASK(0x60000D50, 0x02); //force_en=1
return sar_dout; //tout is 10 bits fraction
}
I get
'read_sar_dout' was not declared in this scope
После многих часов поиска я обнаружил, что 'read_sar_dout'
является частью \esp8266\hardware\esp8266\2.6.3\tools\sdk\lib\NONOSDK3V0\libphy.a:
Поэтому я попытался
extern void read_sar_dout(uint16_t*);
Но я получил
undefined reference to `read_sar_dout(unsigned short*)'
Как получить ссылку на эту функцию или включить или связать файл с моим кодом?