前言
上篇主要針對AMS TOF TMF8801初始化與FactoryCalib做初步介紹完了這邊介紹他如何獲取量測資訊與流程
下圖表流程圖為主要我去彙整TMF8801上篇的流程圖上篇,不清楚的看官可以針對這表格再比對一下
Get sensor distancePeak data and Confidence
unsigned int TMF8801_distancePeak_mm()
{
uint8_t buffer[2];
uint16_t distancePeak=0;
buffer[0]=read_register(0x22);
buffer[1]=read_register(0x23);
//printf("buf[0]=%#x ,buf[1]=%#x nr",buffer[0],buffer[1]);
distancePeak = buffer[1];
distancePeak = distancePeak << 8;
distancePeak += buffer[0];
return distancePeak;
};
unsigned int TMF8801_Confidence()
{
uint8_t cmd_buf[4] ={0,0,0,0},resultInfo=0,resultNumber=0,distancePeak=0;
HAL_I2C_Mem_Read(&hi2c1, Devadress,REGISTER_RESULT_NUMBER, I2C_MEMADD_SIZE_8BIT,cmd_buf,4,100);
resultNumber = cmd_buf[0];
resultInfo = cmd_buf[1];
distancePeak = cmd_buf[3];
distancePeak = distancePeak << 8;
distancePeak += cmd_buf[2];
return resultInfo;
}
在抓取資訊後發現奇怪TMF8801怎只能抓取到最遠660mm!!!
後續花很長時間比對與AMS官網上放的Firmware 發現有些地方不同且網路資訊很多都沒寫到,重點官網上竟然Application Note也沒寫到
是需要做Firmware upload TMF8801才能達到官網規格最遠2.5M
解讀Firmware upload
首先先到官網下載Firmware開啟下圖的文件(用記事本即可)
程式代碼
download_INT_RAM();
tmf8801_write_ram();
remap_rst_RAM();
主要加入這3個步驟把Data一個一個寫入因為STM32的MCU架構與MPU Linux系統不同,無法讀取外部檔案所以這邊是把data解析出來後存到陣列裡
第一步download_INT_RAM()主要先讓TMF8801 RAM全部初始化方便後續把data陸續寫入
void download_INT_RAM()
{
uint8_t cmd_buf[] = {0x14, 0x01, 0x29,0xC1},ready=-1;
//uint8_t checksum=0;
/*
* cmd_buf [0]: Initialization Download HW Command (0x14)
* cmd_buf [1]: Data length (0x01)
* cmd_buf [3]: 1 byte data
* cmd_buf [4]: check bytes
*/
HAL_I2C_Mem_Write(&hi2c1, Devadress, 0x08, I2C_MEMADD_SIZE_8BIT, &cmd_buf,4, 100);
HAL_Delay(20);
//checksum=read_register(0x8B);
//printf("checksum=%#x nr",checksum);
for(int i=0;i<5;i++){
ready=__tmf8801_status_read ();
HAL_Delay(20);
if(ready==TMF8x01_OK)
{printf("download_INT_RAM oknr");
break;}
}
if(ready==TMF8x01_NK)
{for(;;);}
}
第二步寫入Data
void tmf8801_write_ram ()
{
uint8_t cmd_buf[19] = {0};
uint16_t buf_length = 0;
uint16_t buf_line = 0;
uint32_t tick = 0;
int i = 0;
uint16_t j = 0;
uint16_t address_pointer = 0;
// uint8_t data=0x0A;
uint8_t sum=0;
int count=0;
buf_length = sizeof(app_buf) / sizeof(app_buf[0]);
buf_line = buf_length / 16;
cmd_buf[0] = 0x41;
cmd_buf[1] = 0x10;
//printf("total count=%d rn",buf_line);
//tmf8801_set_ram_addr (0x00);
for (i = 0; i <buf_line; i++) {
//data=0x0A;//reset data
sum=0;//reset sum
address_pointer=i*16;
tmf8801_set_ram_addr (address_pointer);
for (j = 0; j < 16; j++) {
cmd_buf[2+j] = app_buf[16 * i + j];
// data=data+j;
// write_register(data,cmd_buf[2+j]);//data0~XXX
}
cmd_buf[18] = 0;
for (j = 0; j < 18; j++) {
sum+= cmd_buf[j];
}
cmd_buf[18] =~(uint8_t)sum;
HAL_I2C_Mem_Write(&hi2c1, Devadress, 0x08, I2C_MEMADD_SIZE_8BIT, cmd_buf,19, 100);
HAL_Delay(5);
/* */
while(1)
{
if (__tmf8801_status_read() == TMF8x01_OK)
{
count++;
if(count%100==0)
printf("Patch download %d(until over 690 will finish) rn",count);
break;
}
tick++;
if (tick >= 10)
{
printf("__tmf8801_write_ram fial!rn");
return ;
}
}
}
// printf("fail address=%#x rn",address_pointer);
return ;
}
第3步相對簡單只是Datasheet要求的你把RAM寫入Data後要做一次復歸動作
void remap_rst_RAM()
{
uint8_t cmd_buf[3]={0x11,0x00,0xEE};
int ready=-1,x=0,y=0;
//write_register(0x02,0x80);
HAL_I2C_Mem_Write(&hi2c1, Devadress, 0x08, I2C_MEMADD_SIZE_8BIT, cmd_buf,3, 100);
HAL_Delay(10);
//printf("reset RAM oknr");
//TMF8801_reset();
while(1){
y++;
if (!waitForCpuReady() && y%10==0)
{
x=read_register(0xE0);
printf("CPU staute= %#x not ready wait~nr",x);
//HAL_Delay(10);
}
else if(y>50)
{ printf("Ram reset failnr",x);
for(;;);}
else if(waitForCpuReady())
{printf("Ram reset oknr");
return;}
}
}
Pingback: AMS and STM32 (proximity )TOF sensor AMS TMF8801 coding on STM32 -1
Pingback: AMS and STM32 AMS Time-of-Flight sensor ( TMF8801 ) -1