| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420 |
- #include <string.h>
- #include "spi.h"
- #include "cs1180.h"
- #include "clock.h"
- #include "libs/shark_types.h"
- #include "libs/shark_task.h"
- #include "libs/logger.h"
- /*
- 注意:cs1 -> cs0 需要delay 一段时间,目前测试20us可以
- */
- #define CS1180_RDATA 0X01
- #define CS1180_RDATAC 0X03
- #define CS1180_STOPC 0x0f
- #define CS1180_RREG 0x10
- #define CS1180_WREG 0x50
- #define CS1180_CALSELF 0xf0
- #define CS1180_OCALSELF 0xf1
- #define CS1180_SLFGCAL 0xf2
- #define CS1180_OCALSYS 0xf3
- #define CS1180_GCALSYS 0xf4
- #define CS1180_WAKEUP 0xfb
- #define CS1180_SYNC 0xfc
- #define CS1180_SLEEP 0xfd
- #define CS1180_RESET 0xfe
- static float _cs1180_gain = 1.0f;
- static int CS1180_NOW_GAIN = CS1180_GAIN_128X;
- static uint8_t _cali_gain_regs[16 * 8];
- static int cs1180_send_cmd(uint8_t data);
- static uint8_t cs1180_read_data(uint8_t data);
- static void cs1180_reset(void);
- void cs_delay(void)
- {
- uint32_t count = 1;
- while(count--);
- }
- static int _cs1180_ready = 0;
- int cs1180_is_ready(void){
- return _cs1180_ready;
- }
- static void spi_write_reg(uint8_t reg, uint8_t *data, uint8_t len){
- cs1180_send_cmd(CS1180_WREG|reg);
- cs1180_send_cmd(len - 1);
- while(len -- > 0){
- cs1180_send_cmd(*data);
- data++;
- }
- }
- static void spi_read_reg(uint8_t reg, uint8_t *data, uint8_t len){
- cs1180_send_cmd(CS1180_RREG|reg);
- cs1180_send_cmd(len - 1);
- delay_us(60);
- while(len -- > 0){
- *data = cs1180_read_data(0xFF);
- data++;
- }
- }
- static void cs1180_save_regs(int gain){
- uint8_t *data = _cali_gain_regs + 16 * gain;
- cs1180_cs(0);
- spi_read_reg(0x0, data, 16);
- cs1180_cs(1);
- }
- static void cs1180_dumy_read(){
- uint8_t data[16];
- cs1180_cs(0);
- spi_read_reg(0x0, data, 16);
- cs1180_cs(1);
- }
- static int cs1180_wait_ready(int ms){
- u64 now = shark_get_mseconds();
- while (IS_CS1180_NOT_READY()){
- if (shark_get_mseconds() - now > ms) {
- return 0;
- }
- }
- return 1;
- }
- static int cs1180_wait_not_ready(int ms){
- u64 now = shark_get_mseconds();
- while (!IS_CS1180_NOT_READY()){
- if (shark_get_mseconds() - now > ms) {
- return 0;
- }
- }
- return 1;
- }
- /* 对芯片的偏移误差和增益误差进行纠正 */
- __attribute__((unused)) static void cs1180_self_calibrate(void)
- {
- cs1180_cs(0);
- cs1180_send_cmd(CS1180_CALSELF);
- cs1180_cs(1);
- /* wait calibrate finished */
- cs1180_wait_ready(30);
- cs1180_wait_not_ready(30);
- delay_us(33 * 1000);
- cs1180_wait_ready(30); //drop first data
- }
- /* 对芯片的偏移误差进行纠正 */
- __attribute__((unused)) static void cs1180_self_offset_calibrate(void)
- {
- cs1180_cs(0);
- cs1180_send_cmd(CS1180_OCALSELF);
- cs1180_cs(1);
- /* wait calibrate finished */
- cs1180_wait_ready(30);
- cs1180_wait_not_ready(30);
- delay_us(33 * 1000);
- cs1180_wait_ready(30); //drop first data
- }
- /* 对芯片的增益误差进行纠正 */
- __attribute__((unused)) static void cs1180_self_gain_calibrate(void)
- {
- cs1180_cs(0);
- cs1180_send_cmd(CS1180_SLFGCAL);
- cs1180_cs(1);
- /* wait calibrate finished */
- cs1180_wait_ready(30);
- cs1180_wait_not_ready(30);
- delay_us(33 * 1000);
- cs1180_wait_ready(30); //drop first data
- }
- /* 对系统的失调误差(偏移误差)进行纠正, 必须要求输入为差分电压为0,
- */
- __attribute__((unused)) static void cs1180_sys_offset_calibrate(void)
- {
- cs1180_cs(0);
- cs1180_send_cmd(CS1180_OCALSYS);
- cs1180_cs(1);
- /* wait calibrate finished */
- delay_us(20);
- cs1180_wait_ready(30);
- cs1180_wait_not_ready(30);
- delay_us(33 * 1000);
- cs1180_wait_ready(30); //drop first data
- }
- /* 对系统的增益误差进行纠正,必须输入正满幅度的电压, SP700,SP600未提供满辐电压,故这一项不做 */
- __attribute__((unused)) static void cs1180_sys_gain_calibrate(void)
- {
- cs1180_cs(0);
- cs1180_send_cmd(CS1180_GCALSYS);
- cs1180_cs(1);
- /* wait calibrate finished */
- cs1180_wait_ready(30);
- cs1180_wait_not_ready(30);
- delay_us(33 * 1000);
- cs1180_wait_ready(30); //drop first data
- }
- static void _cs1180_adc_set_gain(int gain){
- /* 输出频率 15hz,参考电压1.235V 输出数据高位在前,
- * 输入缓冲器关闭,采样频率 OSC/128,数据格式双极性
- */
- uint8_t data[] = {0x00, 0x01, 0x00};
- data[0] = 0xF & gain;
- cs1180_cs(0);
- spi_write_reg(0x00, data, 3);
- cs1180_cs(1);
- }
- static int _cs1180_check_gain(int gain){
- uint8_t data[] = {0xFF, 0xFF, 0xFF};
- cs1180_cs(0);
- spi_read_reg(0x00, data, 3);
- cs1180_cs(1);
- if (data[0] == gain && data[1] == 0x01 && data[2] == 0x00){
- return 1;
- }
- return 0;
- }
- static int cs1180_check_cali_offset(void){
- uint32_t offset = 0;
- cs1180_cs(0);
- spi_read_reg(0x07, (uint8_t *)&offset, 3);
- cs1180_cs(1);
- return (offset != 0) && (offset != 0xFFFFFF);
- }
- void cs1180_read_all_regs(void){
- cs1180_save_regs(CS1180_GAIN_128X);
- for (int i = 0; i < 16; i++){
- sys_debug("Reg%d:0x%x\n", i, _cali_gain_regs[16 * CS1180_NOW_GAIN + i]);
- }
- }
- static int save_reg_errors = 0;
- int cs1180_adc_set_gain_cali(int gain){
- int count = 0;
- do {
- cs1180_reset();
- delay_us(10);
-
- _cs1180_adc_set_gain(gain);
-
- if (count ++ > 50) {
- return 0;
- }
- delay_us(20);
- }while(!_cs1180_check_gain(gain));
- delay_us(50);
- cs1180_self_calibrate();
- count = 0;
- do {
- cs1180_sys_offset_calibrate();
- if (cs1180_check_cali_offset()){
- break;
- }
- delay_us(20);
- }while(count++ <= 5);
- if (count > 5){
- return 0;
- }
- _cs1180_gain = 1 << gain;
- count = 0;
- do {
- delay_us(50);
- cs1180_save_regs(gain);
- uint8_t *data = _cali_gain_regs + 16 * gain;
- uint32_t offset = data[9]<<16 | data[8] << 8 | data[7];
- if ((offset != 0) && (offset != 0xffffff)){
- break;
- }
- save_reg_errors ++;
- }while(count ++ >= 5);
- return 1;
- }
- static void cs1180_reset(void){
- cs1180_cs(0);
- cs_delay();
- cs1180_send_cmd(CS1180_RESET);
- cs_delay();
- cs1180_cs(1);
- }
- void cs1180_adc_init(void){
- int count = 0;
- do {
- _cs1180_ready = 0;
- CS1180_PWR_ENABLE(0);
- delay_us(50 * 1000);
- CS1180_PWR_ENABLE(1);
- delay_us(50 * 1000);
- spi1_init();
- delay_us(10);
- _cs1180_ready = cs1180_adc_set_gain_cali(CS1180_GAIN_128X);
- if (_cs1180_ready || (count++ >= 5)) {
- break;
- }
- cs1180_adc_shutdown();
- }while(1);
- sys_debug("cs1180 init retry %d\n", count);
- }
- int _cs1180_check_regs(int gain){
- uint8_t data[13] = {0};
- cs1180_cs(0);
- cs_delay();
- spi_read_reg(0x0, data, 13);
- cs1180_cs(1);
- for (int i = 0; i < 13; i++){
- if (data[i] != _cali_gain_regs[16 * gain + i]){
- return 0;
- }
- }
- return 1;
- }
- static int cs1180_reinit = 0;
- static u32 cs1180_reinit_time = 0;
- //return 1: cs1180 is OK, 0: cs1180 can not work
- int cs1180_adc_set_gain_online(int gain){
- int count = 0;
- uint8_t *data = _cali_gain_regs + 16 * gain;
- if (_cs1180_ready == 1){
- return 1;
- }
- if (data[0] != gain || (data[7] == 0 && data[8] == 0 && data[9] == 0)){
- /*cs1180_adc_init();*/ //没有初始化成功过,或者校准没成功过
- return _cs1180_ready;
- }
- if ((shark_get_seconds() - cs1180_reinit_time) < 10){
- return _cs1180_ready;
- }
- cs1180_reinit_time = shark_get_seconds();
- cs1180_reinit ++;
- delay_us(50 * 1000);
- CS1180_PWR_ENABLE(1);
- delay_us(50 * 1000);
- spi1_init();
- delay_us(10);
- do {
- cs1180_reset();
- delay_us(10);
- cs1180_cs(0);
- spi_write_reg(0x0, _cali_gain_regs + 16 * gain, 13);
- cs1180_cs(1);
- delay_us(10);
- if (_cs1180_check_regs(gain)){
- CS1180_NOW_GAIN = gain;
- _cs1180_gain = 1 << gain;
- _cs1180_ready = 1;
- return 1;
- }
- count ++;
- }while(count <= 5);
- return 0;
- }
- int cs1180_change_gain(int current){
- if (abs(current) < MIN_CURRENT_FOR_CS1180){ //4.5
- return cs1180_adc_set_gain_online(CS1180_GAIN_128X);
- }/*else if (abs(current) < 12 * 1000){ //18
- return cs1180_adc_set_gain_online(CS1180_GAIN_32X);
- }else if (abs(current) < 48 * 1000){ //72
- return cs1180_adc_set_gain_online(CS1180_GAIN_8X);
- }else if (abs(current) < 160 * 1000){
- return cs1180_adc_set_gain_online(CS1180_GAIN_1X);
- }*/
- return -1;
- }
- void cs1180_adc_shutdown(void){
- cs1180_cs(0);
- CS1180_PWR_ENABLE(0);
- spi1_deinit();
- _cs1180_ready = 0;
- }
- static int cs1180_may_error = 0;
- static int cs1180_ready_error = 0;
- void cs1180_log(void){
- sys_error("cs1180 error %d-%d, ready %d, reinit %d\n", cs1180_may_error, save_reg_errors, _cs1180_ready, cs1180_reinit);
- sys_error("cs1180 ready error %d\n", cs1180_ready_error);
- for (int i = 0; i < 16; i++){
- sys_debug("Reg%d:0x%x\n", i, _cali_gain_regs[16 * CS1180_NOW_GAIN + i]);
- }
- }
- float cs1180_adc_sample(int *valide)
- {
- static int cs1180_low_ff_count = 0;
- uint8_t data[3] = {0,0,0};
- int a = 0;
- if (cs1180_wait_ready(40) == 0) { //当drdy 为高时,不读取数据
- *valide = 0;
- cs1180_ready_error ++;
- return 0.0f;
- }
- cs1180_cs(0);
- cs1180_send_cmd(CS1180_RDATA);
- delay_us(60);
- data[0] = cs1180_read_data(0xFF);
- data[1] = cs1180_read_data(0xFF);
- data[2] = cs1180_read_data(0xFF);
- cs1180_cs(1);
- a = (data[0] << 16) | (data[1] << 8) | data[2];
- a >>= 4;
- if (data[2] == 0xFF) {
- if (cs1180_low_ff_count ++ >= 10) {
- cs1180_low_ff_count = 0;
- cs1180_may_error ++;
- delay_us(20);
- cs1180_dumy_read();
- delay_us(20);
- cs1180_dumy_read();
- if (valide) {
- *valide = 0;
- }
- }
- }else {
- cs1180_low_ff_count = 0;
- }
-
- if (a & 0x80000) {
- a = ~a;
- a = - (a&0x7FFFF);
- }else {
- a = a&0x7FFFF;
- }
- return (((float)a / _cs1180_gain));
- }
- static int cs1180_send_cmd(uint8_t cmd){
- return spi1_send_byte(cmd, NULL);
- }
- static uint8_t cs1180_read_data(uint8_t data){
- uint8_t r_data = 0xFF;
- spi1_send_byte(data, &r_data);
- return r_data;
- }
|