123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302 |
- /* ---------------------------------------------
- //ad0x0 mpu6050
- * ----------------------------------------------
- */
- //#include "stm8s_conf.h"
- //#include "stm8s_delay.h"
- //#include "i2c_master_poll.h"
- #include "../i2c/ad0x0_i2c2.h"
- #include "../i2c/ad0x0_i2c_ext.h"
- #include <string.h>
- #include "mpu6050.h"
- #include "mpu6050_r.h"
- #include "../admisc/ad0x0_timman.h"
- volatile u8 mpu6050_adq_byte=0;
- static ad0x0_gyrodata_s gdata14,gdata_be,gdata_le;//be==BigEndian
- static bool g_gyro_tick=false;
- static volatile uint32_t last_update_tick=0;
- static uint8_t zavis=0;
- /*#define MPU6050_POWER_Pin GPIO_PIN_1
- #define MPU6050_POWER_GPIO_Port GPIOB*/
- void mpu6050_writebits(uint8_t _reg, uint8_t _or_bits, uint8_t _and_mask);
- /*
- было дело, лечил зависания методом выключить\включить...
- void power_set(bool _isOn){
- #ifdef MPU6050_POWER_GPIO_Port
- HAL_GPIO_WritePin(MPU6050_POWER_GPIO_Port,MPU6050_POWER_Pin,_isOn ? GPIO_PIN_SET : GPIO_PIN_RESET);
- #endif
- }*/
- static uint32_t get_per_ms(uint32_t _tick_start){
- uint32_t t=(HAL_GetTick()<_tick_start)
- ?((uint64_t)HAL_GetTick()+UINT32_MAX-_tick_start)
- :(HAL_GetTick()-_tick_start);
- return t;
- }
- uint8_t mpu6050_wakeup(){
- if(get_per_ms(last_update_tick)>300){
- zavis=true;
- return 1;//выпилиться
- }
- return 0;//не выпиливаться из менеджера тиков
- }
- void mpu6050_stop(void){
- ad0x0_timman_remove(mpu6050_wakeup);
- g_gyro_tick=false;
- zavis=false;
- }
- ad0x0_gyrodata_s *mpu6050_get_gyrodata_s(void){
- return &gdata_be;
- }
- //ad0x0_gyrodata_s *mpu6050_get_gyrodata_s_le(void){ return &gdata_le;}
- enum{
- xMPU6050_P_OFF,
- xMPU6050_P_ON,
- xMPU6050_START
- };
- void cb_mpu5060_power_set(uint8_t _sf_id,ad0x0_i2c_desc_s *pdi2c,void *p_i2c_ext_t){
- // ad0x0_i2c_ext_t *p_ext=(ad0x0_i2c_ext_t*)p_i2c_ext_t;
- switch(_sf_id){
- /*case xMPU6050_P_OFF:
- power_set(0);
- break;
- case xMPU6050_P_ON:
- power_set(1);
- break;*/
- case xMPU6050_START:
- g_gyro_tick=true;
- zavis=false;
- last_update_tick=HAL_GetTick();
- //ad0x0_timman_add(10,mpu6050_wakeup);перенес в инит, виснет при инициализации сука
- break;
- }
- }
- void mpu6050_start(void){
- ad0x0_i2c2_push_ext_setfunc(xMPU6050_START,cb_mpu5060_power_set);
- }
- void mpu6050_on_i2c_err(void){
- mpu6050_stop();
- }
- void mpu6050_on_i2c_restart(void){
- mpu6050_init();
- mpu6050_start();
- }
- void mpu6050_init(void){
- /*power_set(false);
- HAL_Delay(200);
- power_set(true);
- HAL_Delay(100);*/
- ad0x0_i2c2_set_restart_func(mpu6050_on_i2c_err,mpu6050_on_i2c_restart);
- ad0x0_timman_add(10,mpu6050_wakeup);
- // ad0x0_i2c2_push_ext_setfunc(xMPU6050_P_OFF, cb_mpu5060_power_set);
- // ad0x0_i2c2_push(ADQ_DELAY_MS,250);
- // ad0x0_i2c2_push_ext_setfunc(xMPU6050_P_ON, cb_mpu5060_power_set);
- // ad0x0_i2c2_push(ADQ_DELAY_MS,250);
-
- mpu6050_writebits(MPU6050_RA_PWR_MGMT_1,0,~(1<<MPU6050_PWR1_SLEEP_BIT));
- //memset(&gdata,0,sizeof(gdata)); затрет посчитанные данные, пусть остается то шо было
- // mpu6050_writebit(MPU6050_RA_PWR_MGMT_1,MPU6050_PWR1_SLEEP_BIT,0);
- ad0x0_i2c2_push(ADQ_DELAY_MS,100);
- //тут блин ппц
- if(1){
- mpu6050_writebyte(25,16);//sample rate div=8 (8/24)=0.333 kHz
- mpu6050_writebyte(26,0);//filter
- }else{
- mpu6050_writebyte(25,1);//sample rate div
- mpu6050_writebyte(26,6);//filter
- }
- //
- mpu6050_writebyte(0x38,0x9);//прерывания
- //mpu6050_readbyte(MPU6050_RA_WHO_AM_I);
-
- //mpu6050_readbytes(MPU6050_RA_ACCEL_XOUT_H,(u8*)&gdata,14);
- ad0x0_i2c2_push(ADQ_DELAY_MS,1);
- }
- //*********************************************************
- static void cb_write_register_bit2(uint8_t _sf_id,ad0x0_i2c_desc_s *pi2c,void *p_i2c_ext_t);
- static void cb_write_register_bit(uint8_t _sf_id,ad0x0_i2c_desc_s *pi2c,void *p_i2c_ext_t){
- ad0x0_i2c_ext_t *p_ext=(ad0x0_i2c_ext_t*)p_i2c_ext_t;
- p_ext->_p_post_cb_func = cb_write_register_bit2;
- }
- static void cb_write_register_bit2(uint8_t _sf_id,ad0x0_i2c_desc_s *pi2c,void *p_i2c_ext_t){
- ad0x0_i2c_ext_t *p_ext=(ad0x0_i2c_ext_t*)p_i2c_ext_t;
- /*пост процесс команды чтения*/
- uint8_t value = (uint8_t)(p_ext->user_data1 & 0xFF);//прочитанный байт
- uint8_t reg = p_ext->user_data0 & 0xFF;
- value &= (uint8_t)(p_ext->user_data0>>24);//_and_mask
- value |= (uint8_t)(p_ext->user_data0>>16);//_or_bits
- //модифицируем ячейку под следующую команду
- p_ext->user_data0 = (uint32_t)value<<8 | (uint32_t)reg;
- p_ext->pbuf_count=2;//уже 2 байта пишим: рег, знач.
- p_ext->_p_post_cb_func = NULL;
- }
- void mpu6050_writebits(uint8_t _reg, uint8_t _or_bits, uint8_t _and_mask){
- /*ad0x0_i2c2_push(ADQ_START_ADDR,MPU6050_ADDRESS_W);
- ad0x0_i2c2_push(ADQ_TX,_reg);
- ad0x0_i2c2_push(ADQ_START_ADDR,MPU6050_ADDRESS_R);*/
-
- uint8_t h_ext;
- ad0x0_i2c_ext_t *p_ext_t=NULL;
- ad0x0_i2c2_get_ext_async2(&h_ext,(void**)&p_ext_t);//получить ячейку, ассоциированную с командой в очереди
- //дальше полный изврат
-
- p_ext_t->addr_w=MPU6050_ADDRESS_W;
- p_ext_t->addr_r=MPU6050_ADDRESS_R;
- p_ext_t->user_data0=_reg | (uint32_t)0xFF00 | (uint32_t)_or_bits<<16 | (uint32_t)_and_mask<<24;
- p_ext_t->_p_post_cb_func = cb_write_register_bit;
-
- p_ext_t->pbuf_count=1;
- p_ext_t->pbuf_tx=(uint8_t*)&p_ext_t->user_data0;//TX!!!!!!!
- p_ext_t->pbuf_rx=(uint8_t*)&p_ext_t->user_data1;//RX!!!
- p_ext_t->p_pre_SetTXRXBuf=EXT_SetTXRXBuf_i2c;
- p_ext_t->reference_count=2;//после 3й команды высвободится... вроде... механизм тупой, но хоть что-то
- ad0x0_i2c2_push(ADQ_HAL_ADDR_TX_BUF_SEQ_FIRST_EXT,h_ext);
- ad0x0_i2c2_push(ADQ_HAL_ADDR_RX_BUF_SEQ_LAST_EXT,h_ext);
- ad0x0_i2c2_push(ADQ_HAL_ADDR_TX_BUF_STOP_EXT,h_ext);
- }
- void mpu6050_writebyte(u8 _reg,u8 _byte){
- /* ad0x0_i2c2_push(ADQ_START_ADDR,MPU6050_ADDRESS_W);
- ad0x0_i2c2_push(ADQ_TX,_reg);
- ad0x0_i2c2_push(ADQ_TX_STOP,_byte); */
- uint8_t h_ext;
- ad0x0_i2c_ext_t *p_ext_t=NULL;
- ad0x0_i2c2_get_ext_async2(&h_ext,(void**)&p_ext_t);//получить ячейку, ассоциированную с командой в очереди
-
- p_ext_t->addr_w=MPU6050_ADDRESS_W;
- p_ext_t->user_data0=_reg | (uint32_t)(_byte<<8);
- p_ext_t->pbuf_count=2;
- p_ext_t->pbuf_tx=(uint8_t*)&p_ext_t->user_data0;//TX!!!!!!!
- p_ext_t->p_pre_SetTXRXBuf=EXT_SetTXRXBuf_i2c;
- ad0x0_i2c2_push(ADQ_HAL_ADDR_TX_BUF_STOP_EXT,h_ext);
- }
- /*void mpu6050_readbyte(u8 _reg){
- ad0x0_i2c2_push(ADQ_START_ADDR,MPU6050_ADDRESS_W);
- ad0x0_i2c2_push(ADQ_TX,_reg);
- ad0x0_i2c2_push(ADQ_START_ADDR,MPU6050_ADDRESS_R);
- ad0x0_i2c2_push(ADQ_RX_STOP,(u8)mpu6050_adq_byte);
- }*/
- static void cb_mpu6050_readbytes2(uint8_t _sf_id,ad0x0_i2c_desc_s *pi2c,void *p_i2c_ext_t);
- static void cb_mpu6050_readbytes(uint8_t _sf_id,ad0x0_i2c_desc_s *pi2c,void *p_i2c_ext_t){
- ad0x0_i2c_ext_t *p_ext=(ad0x0_i2c_ext_t*)p_i2c_ext_t;
- p_ext->pbuf_count=p_ext->user_data1;
- p_ext->_p_post_cb_func = cb_mpu6050_readbytes2;
- //refcount больше тут не инкрементируем чтобы все релизилось правильно
- }
- static void cb_mpu6050_readbytes2(uint8_t _sf_id,ad0x0_i2c_desc_s *pi2c,void *p_i2c_ext_t){
- //ad0x0_i2c_ext_t *p_ext=(ad0x0_i2c_ext_t*)p_i2c_ext_t;
- //раз мы тут, то все прочиталось, иначе бы была перезагрузка матр.. очереди
- #define AD0X0_6050_LE_SWAP(X,Y) X = ((uint16_t)Y >> 8)|((uint16_t)Y << 8);
- memcpy(&gdata_le,&gdata14,sizeof(ad0x0_gyrodata_s));
- //memcpy(&gdata_be,&gdata,sizeof(ad0x0_gyrodata_s));
- AD0X0_6050_LE_SWAP(gdata_be.ax,gdata_le.ax);
- AD0X0_6050_LE_SWAP(gdata_be.ay,gdata_le.ay);
- AD0X0_6050_LE_SWAP(gdata_be.az,gdata_le.az);
- AD0X0_6050_LE_SWAP(gdata_be.gx,gdata_le.gx);
- AD0X0_6050_LE_SWAP(gdata_be.gy,gdata_le.gy);
- AD0X0_6050_LE_SWAP(gdata_be.gz,gdata_le.gz);
- }
- //void mpu6050_readbytes(u8 _reg,u8 *_pbuf,u8 _count){//ломаем универсальность.. см. ниже
- /*расклад такой, эта скотина иногда зависает и мы ее перезагружаем. Это
- не мешает начитать в буфер всякой херни, по этому делаем вот что:
- читаем 1) в gdata14 то, что идет с шины, 2) __если__ все прочиталось нормально, то
- согласно моему плану, вызовется cb_mpu6050_readbytes2. И там уже переворачиваем байты
- для big endian представления*/
- void mpu6050_read14(void){
- uint8_t h_ext;
- ad0x0_i2c_ext_t *p_ext_t=NULL;
- ad0x0_i2c2_get_ext_async2(&h_ext,(void**)&p_ext_t);//получить ячейку, ассоциированную с командой в очереди
-
- p_ext_t->addr_w=MPU6050_ADDRESS_W;
- p_ext_t->addr_r=MPU6050_ADDRESS_R;
- p_ext_t->user_data0=MPU6050_RA_ACCEL_XOUT_H;
- p_ext_t->user_data1=14;//_count;
- p_ext_t->_p_post_cb_func = cb_mpu6050_readbytes;
-
- p_ext_t->pbuf_count=1;//1 - это адрес регистра, кол-во байт чтения выставим в колбэке
- p_ext_t->pbuf_tx=(uint8_t*)&p_ext_t->user_data0;//TX!!!!!!!
- p_ext_t->pbuf_rx=(uint8_t*)&gdata14;//RX!!!
- p_ext_t->p_pre_SetTXRXBuf=EXT_SetTXRXBuf_i2c;
- p_ext_t->reference_count=1;
- ad0x0_i2c2_push(ADQ_HAL_ADDR_TX_BUF_SEQ_FIRST_EXT,h_ext);
- ad0x0_i2c2_push(ADQ_HAL_ADDR_RX_BUF_SEQ_LAST_EXT,h_ext);
- /* ad0x0_i2c2_push(ADQ_START_ADDR,MPU6050_ADDRESS_W);
- ad0x0_i2c2_push(ADQ_TX,_reg);
- ad0x0_i2c2_push(ADQ_START_ADDR,MPU6050_ADDRESS_R);
- ad0x0_i2c2_push_rx_pbuf_stop_ext(NULL,_pbuf,_count);*/
-
- }
- /*#define AD0X0_6050_LE_SWAP(X,Y) X = ((uint16_t)Y >> 8)|((uint16_t)Y << 8);
- static void mpu6050_damn_lendian(void){
- //gdata.ax=(gdata.ax >> 8)|(gdata.ax << 8);
- memcpy(&gdata_le,&gdata,sizeof(ad0x0_gyrodata_s));
- //memcpy(&gdata_be,&gdata,sizeof(ad0x0_gyrodata_s));
- AD0X0_6050_LE_SWAP(gdata_be.ax,gdata_le.ax);
- AD0X0_6050_LE_SWAP(gdata_be.ay,gdata_le.ay);
- AD0X0_6050_LE_SWAP(gdata_be.az,gdata_le.az);
- AD0X0_6050_LE_SWAP(gdata_be.gx,gdata_le.gx);
- AD0X0_6050_LE_SWAP(gdata_be.gy,gdata_le.gy);
- AD0X0_6050_LE_SWAP(gdata_be.gz,gdata_le.gz);
- //memcpy(&gdata_be,&gdata,sizeof(ad0x0_gyrodata_s));
- }*/
- void cb_mpu5060_upd_data(uint8_t _sf_id,ad0x0_i2c_desc_s *pdi2c,void *p_i2c_ext_t){
- //mpu6050_damn_lendian(); перенес в mpu6050_read14.cb_mpu6050_readbytes2
- extern void ad0x0_gyro_datareaded_cb(void);
- ad0x0_gyro_datareaded_cb();
- }
- void update_gdata(void){
- if(ad0x0_i2c2_is_queue_ready()){
- mpu6050_read14();
- ad0x0_i2c2_push_ext_setfunc(0,cb_mpu5060_upd_data);
- last_update_tick=HAL_GetTick();
- }else{
- /*ошибка периода следования: это когда мы считываем текущие значения,
- и приходит очередное прерывание*/
- __ASM("nop");
- }
- }
- uint32_t mpu6050_get_last_update_tick(void){
- return last_update_tick;
- }
- uint8_t mpu6050_zavis(void){
- zavis=get_per_ms(last_update_tick)>300;
- return zavis;
- }
- #define AD_GYRO_EVMAX 2;
- //int g_gyro_evmax=10;
- void mpu6050_pin_irq(void){
- if(g_gyro_tick){
- update_gdata();
- }
- }
|