Получение ссылки на ESP8266 "read_sar_dout" - PullRequest
0 голосов
/ 10 января 2020

Я пытаюсь получить более быстрое 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*)'

Как получить ссылку на эту функцию или включить или связать файл с моим кодом?

...