diff --git a/firmware/src/air.c b/firmware/src/air.c index 7082880..556317e 100644 --- a/firmware/src/air.c +++ b/firmware/src/air.c @@ -45,8 +45,8 @@ void air_init() tof_model[i] = 0; } if (tof_model[i] == 1) { - vl53l0x_init_tof(true); - vl53l0x_start_continuous(); + vl53l0x_init_tof(i); + vl53l0x_start_continuous(i); } else if (tof_model[i] == 2) { gp2y03_init(I2C_PORT); } @@ -109,7 +109,7 @@ void air_update() for (int i = 0; i < sizeof(TOF_LIST); i++) { i2c_select(I2C_PORT, 1 << TOF_LIST[i]); if (tof_model[i] == 1) { - distances[i] = readRangeContinuousMillimeters() * 10; + distances[i] = readRangeContinuousMillimeters(i) * 10; } else if (tof_model[i] == 2) { distances[i] = gp2y0e_dist16_mm(I2C_PORT) * 10; } diff --git a/firmware/src/config.c b/firmware/src/config.c index ec691e1..da5be3d 100644 --- a/firmware/src/config.c +++ b/firmware/src/config.c @@ -26,8 +26,8 @@ static chu_cfg_t default_cfg = { .level = 127, }, .tof = { - .offset = 100, - .pitch = 28, + .offset = 80, + .pitch = 20, }, .sense = { .filter = 0x10, diff --git a/firmware/src/pn532.c b/firmware/src/pn532.c index 1793cb7..9ada649 100644 --- a/firmware/src/pn532.c +++ b/firmware/src/pn532.c @@ -262,10 +262,18 @@ uint32_t pn532_firmware_ver() return version; } +bool pn532_config_rf() +{ + uint8_t param[] = {0x05, 0xff, 0x01, 0x50}; + pn532_write_command(0x32, param, sizeof(param)); + + return pn532_read_response(0x32, param, sizeof(param)) == 0; +} + bool pn532_config_sam() { uint8_t param[] = {0x01, 0x14, 0x01}; - pn532_write_command(0x14, param, 3); + pn532_write_command(0x14, param, sizeof(param)); return pn532_read_response(0x14, NULL, 0) == 0; } @@ -308,6 +316,36 @@ bool pn532_poll_mifare(uint8_t *uid, int *len) return true; } +bool pn532_poll_14443b(uint8_t *uid, int *len) +{ + uint8_t param[] = {0x01, 0x03, 0x00}; + int ret = pn532_write_command(0x4a, param, sizeof(param)); + if (ret < 0) { + return false; + } + + int result = pn532_read_response(0x4a, readbuf, sizeof(readbuf)); + if (result < 1 || readbuf[0] != 1) { + printf("result: %d\n", result); + return false; + } + + if (result != readbuf[5] + 6) { + printf("result: %d %d\n", result, readbuf[5]); + return false; + } + + if (*len < readbuf[5]) { + printf("result: %d %d\n", result, readbuf[5]); + return false; + } + + memcpy(uid, readbuf + 6, readbuf[5]); + *len = readbuf[5]; + + return true; +} + static struct __attribute__((packed)) { uint8_t idm[8]; uint8_t pmm[8]; diff --git a/firmware/src/pn532.h b/firmware/src/pn532.h index ca10256..a863f9b 100644 --- a/firmware/src/pn532.h +++ b/firmware/src/pn532.h @@ -14,9 +14,12 @@ int pn532_read_response(uint8_t cmd, uint8_t *resp, uint8_t len); uint32_t pn532_firmware_ver(); bool pn532_config_sam(); +bool pn532_config_rf(); + bool pn532_set_rf_field(uint8_t auto_rf, uint8_t on_off); bool pn532_poll_mifare(uint8_t *uid, int *len); +bool pn532_poll_14443b(uint8_t *uid, int *len); bool pn532_poll_felica(uint8_t uid[8], uint8_t pmm[8], uint8_t syscode[2], bool from_cache); bool pn532_mifare_auth(const uint8_t uid[4], uint8_t block_id, uint8_t key_id, const uint8_t *key); diff --git a/firmware/src/vl53l0x.c b/firmware/src/vl53l0x.c index f179a50..5d028af 100644 --- a/firmware/src/vl53l0x.c +++ b/firmware/src/vl53l0x.c @@ -29,9 +29,17 @@ // PLL_period_ps = 1655; macro_period_vclks = 2304 #define calcMacroPeriod(vcsel_period_pclks) ((((uint32_t)2304 * (vcsel_period_pclks) * 1655) + 500) / 1000) -static i2c_inst_t *port; +static i2c_inst_t *port = i2c0; static uint8_t addr = VL53L0X_DEF_ADDR; +static struct { + uint8_t stop_variable; // read by init and used when starting measurement + uint16_t range; + uint32_t timing_budget_us; +} instances[16]; + +#define INSTANCE_NUM (sizeof(instances) / sizeof(instances[0])) + // Write an 8-bit register void write_reg(uint8_t reg, uint8_t value) { @@ -89,13 +97,13 @@ void read_many(uint8_t reg, uint8_t *dst, uint8_t len) } -uint16_t reg_mode1[] = { 4, 0x8800, 0x8001, 0xff01, 0x0000 }; -uint16_t reg_mode2[] = { 3, 0x0001, 0xff00, 0x8000 }; -uint16_t reg_spad0[] = { 4, 0x8001, 0xff01, 0x0000, 0xff06 }; -uint16_t reg_spad1[] = { 5, 0xff07, 0x8101, 0x8001, 0x946b, 0x8300 }; -uint16_t reg_spad2[] = { 4, 0xff01, 0x0001, 0xff00, 0x8000 }; -uint16_t reg_spad[] = { 5, 0xff01, 0x4f00, 0x4e2c, 0xff00, 0xb6b4 }; -uint16_t reg_tuning[] = { 80, +const uint16_t reg_mode1[] = { 4, 0x8800, 0x8001, 0xff01, 0x0000 }; +const uint16_t reg_mode2[] = { 3, 0x0001, 0xff00, 0x8000 }; +const uint16_t reg_spad0[] = { 4, 0x8001, 0xff01, 0x0000, 0xff06 }; +const uint16_t reg_spad1[] = { 5, 0xff07, 0x8101, 0x8001, 0x946b, 0x8300 }; +const uint16_t reg_spad2[] = { 4, 0xff01, 0x0001, 0xff00, 0x8000 }; +const uint16_t reg_spad[] = { 5, 0xff01, 0x4f00, 0x4e2c, 0xff00, 0xb6b4 }; +const uint16_t reg_tuning[] = { 80, 0xff01, 0x0000, 0xff00, 0x0900, 0x1000, 0x1100, 0x2401, 0x25ff, 0x7500, 0xff01, 0x4e2c, 0x4800, 0x3020, 0xff00, 0x3009, 0x5400, 0x3104, 0x3203, 0x4083, 0x4625, 0x6000, 0x2700, 0x5006, 0x5100, @@ -108,10 +116,6 @@ uint16_t reg_tuning[] = { 80, 0xff00, 0x8001, 0x01f8, 0xff01, 0x8e01, 0x0001, 0xff00, 0x8000, }; - -static uint8_t stop_variable; // read by init and used when starting measurement; is StopVariable field of VL53L0X_DevData_t structure in API -static uint32_t measurement_timing_budget_us; - void vl53l0x_init(i2c_inst_t *i2c_port, uint8_t i2c_addr) { port = i2c_port; @@ -125,13 +129,13 @@ bool vl53l0x_is_present() return read_reg(IDENTIFICATION_MODEL_ID) == 0xEE; } -bool vl53l0x_init_tof() +bool vl53l0x_init_tof(int index) { write_reg(VHV_CONFIG_PAD_SCL_SDA__EXTSUP_HV, read_reg(VHV_CONFIG_PAD_SCL_SDA__EXTSUP_HV) | 0x01); write_reg_list(reg_mode1); - stop_variable = read_reg(0x91); + instances[index].stop_variable = read_reg(0x91); write_reg_list(reg_mode2); // disable SIGNAL_RATE_MSRC (bit 1) and SIGNAL_RATE_PRE_RANGE (bit 4) limit checks @@ -145,6 +149,7 @@ bool vl53l0x_init_tof() uint8_t spad_count; bool is_aperture; if (!getSpadInfo(&spad_count, &is_aperture)) { + printf("%d\n", __LINE__); return false; } @@ -176,17 +181,19 @@ bool vl53l0x_init_tof() write_reg(GPIO_HV_MUX_ACTIVE_HIGH, read_reg(GPIO_HV_MUX_ACTIVE_HIGH) & ~0x10); // active low write_reg(SYSTEM_INTERRUPT_CLEAR, 0x01); - measurement_timing_budget_us = getMeasurementTimingBudget(); + instances[index].timing_budget_us = getMeasurementTimingBudget(index); write_reg(SYSTEM_SEQUENCE_CONFIG, 0xE8); - setMeasurementTimingBudget(measurement_timing_budget_us); + setMeasurementTimingBudget(index, instances[index].timing_budget_us); write_reg(SYSTEM_SEQUENCE_CONFIG, 0x01); if (!performSingleRefCalibration(0x40)) { + printf("%d\n", __LINE__); return false; } write_reg(SYSTEM_SEQUENCE_CONFIG, 0x02); if (!performSingleRefCalibration(0x00)) { + printf("%d\n", __LINE__); return false; } @@ -259,7 +266,7 @@ uint32_t timeoutMicrosecondsToMclks(uint32_t timeout_period_us, uint8_t vcsel_pe // factor of N decreases the range measurement standard deviation by a factor of // sqrt(N). Defaults to about 33 milliseconds; the minimum is 20 ms. // based on VL53L0X_set_measurement_timing_budget_micro_seconds() -bool setMeasurementTimingBudget(uint32_t budget_us) +bool setMeasurementTimingBudget(int index, uint32_t budget_us) { SequenceStepEnables enables; SequenceStepTimeouts timeouts; @@ -335,7 +342,7 @@ bool setMeasurementTimingBudget(uint32_t budget_us) // set_sequence_step_timeout() end - measurement_timing_budget_us = budget_us; // store for internal reuse + instances[index].timing_budget_us = budget_us; // store for internal reuse } return true; } @@ -343,7 +350,7 @@ bool setMeasurementTimingBudget(uint32_t budget_us) // Get the measurement timing budget in microseconds // based on VL53L0X_get_measurement_timing_budget_micro_seconds() // in us -uint32_t getMeasurementTimingBudget() +uint32_t getMeasurementTimingBudget(int index) { SequenceStepEnables enables; SequenceStepTimeouts timeouts; @@ -380,7 +387,7 @@ uint32_t getMeasurementTimingBudget() budget_us += (timeouts.final_range_us + FinalRangeOverhead); } - measurement_timing_budget_us = budget_us; // cache for reuse + instances[index].timing_budget_us = budget_us; // cache for reuse return budget_us; } @@ -391,7 +398,7 @@ uint32_t getMeasurementTimingBudget() // pre: 12 to 18 (initialized default: 14) // final: 8 to 14 (initialized default: 10) // based on VL53L0X_set_vcsel_pulse_period() -bool setVcselPulsePeriod(vcselPeriodType type, uint8_t period_pclks) +bool setVcselPulsePeriod(int index, vcselPeriodType type, uint8_t period_pclks) { uint8_t vcsel_period_reg = encodeVcselPeriod(period_pclks); @@ -544,7 +551,7 @@ bool setVcselPulsePeriod(vcselPeriodType type, uint8_t period_pclks) // "Finally, the timing budget must be re-applied" - setMeasurementTimingBudget(measurement_timing_budget_us); + setMeasurementTimingBudget(index, instances[index].timing_budget_us); // "Perform the phase calibration. This is needed after changing on vcsel period." // VL53L0X_perform_phase_calibration() begin @@ -576,12 +583,16 @@ uint8_t getVcselPulsePeriod(vcselPeriodType type) // Start continuous ranging measurements. // based on VL53L0X_StartMeasurement() -void vl53l0x_start_continuous() +void vl53l0x_start_continuous(int index) { + if (index >= INSTANCE_NUM) { + return; + } + write_reg(0x80, 0x01); write_reg(0xFF, 0x01); write_reg(0x00, 0x00); - write_reg(0x91, stop_variable); + write_reg(0x91, instances[index].stop_variable); write_reg(0x00, 0x01); write_reg(0xFF, 0x00); write_reg(0x80, 0x00); @@ -591,7 +602,7 @@ void vl53l0x_start_continuous() // Stop continuous measurements // based on VL53L0X_StopMeasurement() -void vl53l0x_stop_continuous() +void vl53l0x_stop_continuous(int index) { write_reg(SYSRANGE_START, 0x01); // VL53L0X_REG_SYSRANGE_MODE_SINGLESHOT @@ -605,26 +616,30 @@ void vl53l0x_stop_continuous() // Returns a range reading in millimeters when continuous mode is active // (readRangeSingleMillimeters() also calls this function after starting a // single-shot range measurement) -uint16_t readRangeContinuousMillimeters() +uint16_t readRangeContinuousMillimeters(int index) { - static uint16_t range = 65535; + if (index >= INSTANCE_NUM) { + return 65535; + } + if ((read_reg(RESULT_INTERRUPT_STATUS) & 0x07) == 0) { - return range; // use last result + return instances[index].range; // use last result } // assumptions: Linearity Corrective Gain is 1000 (default); // fractional ranging is not enabled - range = read_reg16(RESULT_RANGE_STATUS + 10); + instances[index].range = read_reg16(RESULT_RANGE_STATUS + 10); write_reg(SYSTEM_INTERRUPT_CLEAR, 0x01); - return range; + return instances[index].range; } +#if 0 // Performs a single-shot range measurement and returns the reading in // millimeters // based on VL53L0X_PerformSingleRangingMeasurement() -uint16_t readRangeSingleMillimeters() +uint16_t readRangeSingleMillimeters(int index) { static uint16_t range = 65535; static bool reading = false; @@ -637,14 +652,14 @@ uint16_t readRangeSingleMillimeters() if (reading) { if ((read_reg(SYSRANGE_START) & 0x01) == 0) { - range = readRangeContinuousMillimeters(); + range = readRangeContinuousMillimeters(index); reading = false; } } else { write_reg(0x80, 0x01); write_reg(0xFF, 0x01); write_reg(0x00, 0x00); - write_reg(0x91, stop_variable); + write_reg(0x91, instances[index].stop_variable); write_reg(0x00, 0x01); write_reg(0xFF, 0x00); write_reg(0x80, 0x00); @@ -655,6 +670,7 @@ uint16_t readRangeSingleMillimeters() } return range; } +#endif // Private Methods ///////////////////////////////////////////////////////////// diff --git a/firmware/src/vl53l0x.h b/firmware/src/vl53l0x.h index ed16773..c842b60 100644 --- a/firmware/src/vl53l0x.h +++ b/firmware/src/vl53l0x.h @@ -105,22 +105,22 @@ typedef enum { void vl53l0x_init(i2c_inst_t *i2c_port, uint8_t i2c_addr); bool vl53l0x_is_present(); -bool vl53l0x_init_tof(); +bool vl53l0x_init_tof(int index); bool setSignalRateLimit(float limit_Mcps); float getSignalRateLimit(); -bool setMeasurementTimingBudget(uint32_t budget_us); -uint32_t getMeasurementTimingBudget(); +bool setMeasurementTimingBudget(int index, uint32_t budget_us); +uint32_t getMeasurementTimingBudget(int index); -bool setVcselPulsePeriod(vcselPeriodType type, uint8_t period_pclks); +bool setVcselPulsePeriod(int index, vcselPeriodType type, uint8_t period_pclks); uint8_t getVcselPulsePeriod(vcselPeriodType type); -void vl53l0x_start_continuous(); -void vl53l0x_stop_continuous(); +void vl53l0x_start_continuous(int index); +void vl53l0x_stop_continuous(int index); -uint16_t readRangeContinuousMillimeters(); -uint16_t readRangeSingleMillimeters(); +uint16_t readRangeContinuousMillimeters(int index); +uint16_t readRangeSingleMillimeters(int index); // TCC: Target CentreCheck // MSRC: Minimum Signal Rate Check