| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320 |
- #include <string.h>
- #include "spi.h"
- #include "cs1180.h"
- #include "clock.h"
- #include "libs/shark_types.h"
- #include "libs/logger.h"
- #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 = 60;
- 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 uint8_t cs1180_dumy_read(int gain){
- uint8_t *data = _cali_gain_regs + 16 * gain;
- while (IS_CS1180_NOT_READY());
- cs1180_cs(0);
- cs_delay();
- spi_read_reg(0x0, data, 16);
- cs_delay();
- cs1180_cs(1);
- return data[0];
- }
- /* 对芯片的偏移误差和增益误差进行纠正 */
- static void cs1180_self_calibrate(void)
- {
- cs1180_cs(0);
- cs_delay();
- cs1180_send_cmd(CS1180_CALSELF);
- cs_delay();
- cs1180_cs(1);
- delay_us(50);
- /* wait calibrate finished */
- while (IS_CS1180_NOT_READY());
- while (!IS_CS1180_NOT_READY());
- delay_us(50 * 1000);
- while (IS_CS1180_NOT_READY()); //drop first data
- }
- /* 对芯片的偏移误差进行纠正 */
- __attribute__((unused)) static void cs1180_self_offset_calibrate(void)
- {
- cs1180_cs(0);
- cs1180_send_cmd(CS1180_OCALSELF);
- cs1180_cs(1);
- delay_us(50);
- /* wait calibrate finished */
- while (IS_CS1180_NOT_READY());
- while (!IS_CS1180_NOT_READY());
- }
- /* 对芯片的增益误差进行纠正 */
- __attribute__((unused)) static void cs1180_self_gain_calibrate(void)
- {
- cs1180_cs(0);
- cs1180_send_cmd(CS1180_SLFGCAL);
- cs1180_cs(1);
- delay_us(50);
- /* wait calibrate finished */
- while (IS_CS1180_NOT_READY());
- while (!IS_CS1180_NOT_READY());
- }
- /* 对系统的失调误差(偏移误差)进行纠正, 必须要求输入为差分电压为0,
- */
- void cs1180_sys_offset_calibrate(void)
- {
- cs1180_cs(0);
- cs_delay();
- cs1180_send_cmd(CS1180_OCALSYS);
- delay_us(50);
- cs1180_cs(1);
- delay_us(50);
- /* wait calibrate finished */
- while (IS_CS1180_NOT_READY());
- while (!IS_CS1180_NOT_READY());
- delay_us(10 * 1000);
- while (IS_CS1180_NOT_READY()); //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);
- delay_us(50);
- /* wait calibrate finished */
- while (IS_CS1180_NOT_READY());
- while (!IS_CS1180_NOT_READY());
- }
- 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);
- cs_delay();
- spi_write_reg(0x00, data, 3);
- cs_delay();
- cs1180_cs(1);
- _cs1180_gain = 1 << gain;
- cs1180_self_calibrate();
- cs1180_dumy_read(gain);
- }
- int cs1180_adc_set_gain_cali(int gain){
- int count = 0;
- do {
- cs1180_reset();
- delay_us(10);
-
- _cs1180_adc_set_gain(gain);
- delay_us(10);
- if (cs1180_dumy_read(gain) == gain){
- break;
- }
- count ++;
- }while(count <= 20);
- if (count >= 20) {
- if (cs1180_dumy_read(gain) != gain){
- return -1;
- }
- }
- delay_us(10*1000);
- cs1180_sys_offset_calibrate();
- cs1180_dumy_read(gain);
- return 0;
- }
- 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){
- _cs1180_ready = 0;
- CS1180_PWR_ENABLE(0);
- delay_us(100 * 1000);
- CS1180_PWR_ENABLE(1);
- delay_us(200 * 1000);
- spi1_init();
- delay_us(10);
- cs1180_adc_set_gain_cali(CS1180_GAIN_1X);
- cs1180_adc_set_gain_cali(CS1180_GAIN_8X);
- cs1180_adc_set_gain_cali(CS1180_GAIN_32X);
- cs1180_adc_set_gain_cali(CS1180_GAIN_128X);
- _cs1180_ready = _cali_gain_regs[16 * CS1180_NOW_GAIN] == CS1180_NOW_GAIN;
- }
- int _cs1180_read_gain(void){
- uint8_t data[] = {0xff, 0xff, 0xff};
- cs1180_cs(0);
- cs_delay();
- spi_read_reg(0x0, data, 3);
- cs1180_cs(1);
-
- return data[0];
- }
- int cs1180_adc_set_gain_online(int gain){
- int count = 0;
- if (_cali_gain_regs[16 * CS1180_NOW_GAIN] == gain){
- return 0;
- }
- sys_debug("change gain to %d\n", gain);
- do {
- cs1180_reset();
- delay_us(10);
- cs1180_cs(0);
- cs_delay();
- spi_write_reg(0x0, _cali_gain_regs + 16 * gain, 16);
- cs1180_cs(1);
- delay_us(10);
- if (_cs1180_read_gain() == gain){
- break;
- }
- count ++;
- }while(count <= 5);
- if (count >= 5) {
- if (_cs1180_read_gain() != gain){
- sys_error("change gain error!!!\n");
- return -1;
- }
- }
- CS1180_NOW_GAIN = gain;
- _cs1180_gain = 1 << gain;
- sys_debug("change gain success!\n");
- return 0;
- }
- int cs1180_change_gain(int current){
- if (abs(current) < 3000){ //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_PWR_ENABLE(0);
- spi1_deinit();
- _cs1180_ready = 0;
- }
- float cs1180_adc_sample(int *valide)
- {
- uint8_t data[3] = {0,0,0};
- int a = 0;
- int retry = 5;
- while (IS_CS1180_NOT_READY()); //当drdy 为高时,不读取数据
- while(retry-- >= 0) {
- cs1180_cs(0);
- cs1180_send_cmd(CS1180_RDATA);
- delay_us(100);
- 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 (a != 0xFFFFF){//spi 上拉,所以如果读到的数据全F,说明可能cs1180没有数据输出,通过判断ready来确定是否要重读
- break;
- }
- delay_us(100);
- if (IS_CS1180_NOT_READY()){
- break;
- }
- sys_warning("cs1180 read adc retry!!!!\n");
- }
- if ((a == 0xFFFFF) && !IS_CS1180_NOT_READY() && (valide != NULL)){
- sys_error("cs1180 adc is not valide\n");
- *valide = 0;
- }
- if (a & 0x80000) {
- a = ~a;
- a = - (a&0x7FFFF);
- }else {
- a = a&0x7FFFF;
- }
- return (int)(((float)a / _cs1180_gain) * 0.9f);
- }
- 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;
- }
|