void main () { int rc; unsigned long next_wake_utt; unsigned long delta_wake_utt; vBSP430platformInitialize_ni(); (void)iBSP430consoleInitialize(); cprintf("\n\nadc demo, " __DATE__ " " __TIME__ "\n"); delta_wake_utt = 2 * ulBSP430uptimeConversionFrequency_Hz(); rc = initializeADC(); cprintf("%s initialized, returned %d, ADC cal at %p, REF cal at %p\n", #if defined(__MSP430_HAS_ADC10__) "ADC10" #elif defined(__MSP430_HAS_ADC10_A__) "ADC10_A" #elif defined(__MSP430_HAS_ADC10_B__) "ADC10_B" #elif defined(__MSP430_HAS_ADC10_B4__) "ADC10_B (FR4xx)" #elif defined(__MSP430_HAS_ADC12__) "ADC12" #elif defined(__MSP430_HAS_ADC12_B__) "ADC12_B" #elif defined(__MSP430_HAS_ADC12_PLUS__) "ADC12_PLUS" #endif /* ADC */ , rc, cal_adc, cal_ref); #if HAVE_REF if (cal_ref) { cprintf("Reference factors:\n" "\t" REF_1pX_STR "V %u (0x%04x)\n" "\t2.0V %u (0x%04x)\n" "\t2.5V %u (0x%04x)\n", cal_ref->cal_adc_15vref_factor, cal_ref->cal_adc_15vref_factor, cal_ref->cal_adc_20vref_factor, cal_ref->cal_adc_20vref_factor, cal_ref->cal_adc_25vref_factor, cal_ref->cal_adc_25vref_factor); } #endif /* HAVE_REF */ if (cal_adc) { cprintf("ADC gain factor %d (0x%04x), offset %d\n", cal_adc->cal_adc_gain_factor, cal_adc->cal_adc_gain_factor, cal_adc->cal_adc_offset); cprintf("Temperature ranges:\n"); cprintf("\t" REF_1pX_STR "V T30 %u T85 %u\n", cal_adc->cal_adc_15t30, cal_adc->cal_adc_15t85); #if BSP430_TLV_IS_5XX cprintf("\t2.0V T30 %u T85 %u\n", cal_adc->cal_adc_20t30, cal_adc->cal_adc_20t85); #endif /* BSP430_TLV_IS_5XX */ cprintf("\t2.5V T30 %u T85 %u\n", cal_adc->cal_adc_25t30, cal_adc->cal_adc_25t85); } cprintf("Vmid channel %u, Temp channel %u" #ifdef INCH_AUX ", Aux channel %u" #endif /* INCH_AUX */ "\n", INCH_VMID / INCH_BASE, INCH_TEMP / INCH_BASE #ifdef INCH_AUX , INCH_AUX / INCH_BASE #endif /* INCH_AUX */ ); next_wake_utt = ulBSP430uptime_ni(); while (1) { char timestamp[BSP430_UPTIME_AS_TEXT_LENGTH]; static const int refv[] = { REF_1pX, REF_2p0, REF_2p5 }; static const char * const refv_str[] = { REF_1pX_STR, "2.0", "2.5" }; static const int const nrefv = sizeof(refv)/sizeof(*refv); static const int inch[] = { INCH_TEMP, INCH_VMID, #if defined(INCH_AUX) INCH_AUX, #endif /* INCH_AUX */ }; static const int const ninch = sizeof(inch)/sizeof(*inch); int valid = 0; sSample sample[sizeof(refv)/sizeof(*refv)][sizeof(inch)/sizeof(*inch)]; int ri; int ii; #define VALID(_ri,_ii) ((1 << (_ii)) << ((_ri) * nrefv)) #define ANY_VALID(_ri) (((1 << nrefv)-1) << ((_ri) * nrefv)) for (ri = 0; ri < nrefv; ++ri) { if (0 == setReferenceVoltage(refv[ri])) { for (ii = 0; ii < ninch; ++ii) { if (0 == getSample(sample[ri]+ii, refv[ri], inch[ii])) { valid |= VALID(ri, ii); } } } } cprintf("%s: valid %x", xBSP430uptimeAsText(ulBSP430uptime_ni(), timestamp), valid); for (ri = 0; ri < nrefv; ++ri) { if (valid & ANY_VALID(ri)) { cprintf("\n\t%sV: ", refv_str[ri]); for (ii = 0; ii < ninch; ++ii) { if (VALID(ri, ii) & valid) { if (INCH_TEMP == inch[ii]) { displayTemperature(sample[ri] + ii); } else if (INCH_VMID == inch[ii]) { displayVmid(sample[ri] + ii); } else { displayVoltage(sample[ri] + ii); } } } } } cputchar('\n'); next_wake_utt += delta_wake_utt; while (0 < lBSP430uptimeSleepUntil(next_wake_utt, LPM3_bits)) { /* nop */ } } }
void main () { hBSP430halSERIAL i2c; sBSP430bq24210 bq24210; union { sBQ27510 state; uint16_t raw[1]; } u; const int nwords = sizeof(u.state)/sizeof(u.raw[0]); unsigned long resample_interval_utt; unsigned long resample_wake_utt; unsigned int flags; int rc; vBSP430platformInitialize_ni(); (void)iBSP430consoleInitialize(); cprintf("\nbattpack " __DATE__ " " __TIME__ "\n"); bq24210.chg_port = xBSP430hplLookupPORT(APP_CHGn_PORT_PERIPH_HANDLE); bq24210.en_port = xBSP430hplLookupPORT(APP_ENn_PORT_PERIPH_HANDLE); bq24210.pg_port = xBSP430hplLookupPORT(APP_PGn_PORT_PERIPH_HANDLE); bq24210.chg_bit = APP_CHGn_PORT_BIT; bq24210.en_bit = APP_ENn_PORT_BIT; bq24210.pg_bit = APP_PGn_PORT_BIT; cprintf("CHGn on %s.%u\n", xBSP430portName(xBSP430periphFromHPL(bq24210.chg_port)), iBSP430portBitPosition(bq24210.chg_bit)); cprintf("ENn on %s.%u\n", xBSP430portName(xBSP430periphFromHPL(bq24210.en_port)), iBSP430portBitPosition(bq24210.en_bit)); cprintf("PGn on %s.%u\n", xBSP430portName(xBSP430periphFromHPL(bq24210.pg_port)), iBSP430portBitPosition(bq24210.pg_bit)); if (! (bq24210.chg_port && bq24210.en_port && bq24210.pg_port)) { cprintf("One of the ports is missing\n"); return; } /* Charge signal is an input (active low) to the MCU. Configure as * input with internal pull-up. */ bq24210.chg_port->dir &= ~bq24210.chg_bit; bq24210.chg_port->out |= bq24210.chg_bit; bq24210.chg_port->ren |= bq24210.chg_bit; /* Power-good signal is an input (active low) to the MCU. Configure * as input with internal pull-up. */ bq24210.pg_port->dir &= ~bq24210.pg_bit; bq24210.pg_port->out |= bq24210.pg_bit; bq24210.pg_port->ren |= bq24210.pg_bit; /* Enable signal is an output (active low) from the MCU. Start * active. */ bq24210.en_port->out &= ~bq24210.en_bit; bq24210.en_port->dir |= bq24210.en_bit; cprintf("I2C on %s at address 0x%02x\nPins: %s\n", xBSP430serialName(APP_BQ27510_I2C_PERIPH_HANDLE), APP_BQ27510_I2C_ADDRESS, xBSP430platformPeripheralHelp(APP_BQ27510_I2C_PERIPH_HANDLE, BSP430_PERIPHCFG_SERIAL_I2C)); /* NOTE: At default BSP430_SERIAL_I2C_BUS_SPEED_HZ 400kHz this * devices supports only single-byte write operations. Further, * ensure a 66us delay between packets. */ i2c = hBSP430serialOpenI2C(hBSP430serialLookup(APP_BQ27510_I2C_PERIPH_HANDLE), BSP430_SERIAL_ADJUST_CTL0_INITIALIZER(UCMST), 0, 0); if (! i2c) { cprintf("I2C open failed\n"); return; } (void)iBSP430i2cSetAddresses_rh(i2c, -1, APP_BQ27510_I2C_ADDRESS); resample_interval_utt = BSP430_UPTIME_MS_TO_UTT(1000UL * RESAMPLE_INTERVAL_S); resample_wake_utt = ulBSP430uptime_ni(); flags = FLG_DUMP_STATE | FLG_UPDATE_INTERVAL; BSP430_CORE_ENABLE_INTERRUPT(); while (1) { char astext_buf[BSP430_UPTIME_AS_TEXT_LENGTH]; uint16_t temperature_dC; if (FLG_DUMP_STATE & flags) { memset(&u, 0, sizeof(u)); rc = readBQ27510(i2c, 0, nwords, u.raw); cprintf("Device ID %04x rc %d\n", u.state.device_id, rc); cprintf("%.30s = %d\n", "atRate_mA", u.state.atRate_mA); cprintf("%.30s = %u\n", "atRatetimeToEmpty_min", u.state.atRatetimeToEmpty_min); cprintf("%.30s = %u\n", "temperature_dK", u.state.temperature_dK); cprintf("%.30s = %u\n", "voltage_mV", u.state.voltage_mV); cprintf("%.30s = 0x%04x\n", "flags", u.state.flags); cprintf("%.30s = %u\n", "nominalAvailableCapacity_mAh", u.state.nominalAvailableCapacity_mAh); cprintf("%.30s = %u\n", "fullAvailableCapacity_mAh", u.state.fullAvailableCapacity_mAh); cprintf("%.30s = %u\n", "remainingCapacity_mAh", u.state.remainingCapacity_mAh); cprintf("%.30s = %u\n", "fullChargeCapacity_mAh", u.state.fullChargeCapacity_mAh); cprintf("%.30s = %d\n", "averageCurrent_mA", u.state.averageCurrent_mA); cprintf("%.30s = %u\n", "timeToEmpty_min", u.state.timeToEmpty_min); cprintf("%.30s = %d\n", "standbyCurrent_mA", u.state.standbyCurrent_mA); cprintf("%.30s = %u\n", "standbyTimeToEmpty_min", u.state.standbyTimeToEmpty_min); cprintf("%.30s = %u\n", "stateOfHealth_ppcpx", u.state.stateOfHealth_ppcpx); cprintf("%.30s = %u\n", "cycleCount", u.state.cycleCount); cprintf("%.30s = %u\n", "stateOfCharge_ppc", u.state.stateOfCharge_ppc); cprintf("%.30s = %d\n", "instantaneousCurrent_mA", u.state.instantaneousCurrent_mA); cprintf("%.30s = %u\n", "internalTemperature_dK", u.state.internalTemperature_dK); cprintf("%.30s = %u\n", "reistanceScale", u.state.reistanceScale); cprintf("%.30s = %u\n", "operationConfiguration", u.state.operationConfiguration); cprintf("%.30s = %u\n", "designCapacity_mAh", u.state.designCapacity_mAh); cprintf("flags %02x ; ENn state %d\n", flags, (bq24210.en_port->out & bq24210.en_bit)); flags &= ~FLG_DUMP_STATE; } if (FLG_TOGGLE_ENABLE & flags) { bq24210.en_port->out ^= bq24210.en_bit; flags &= ~FLG_TOGGLE_ENABLE; } vBSP430ledSet(BSP430_LED_GREEN, !(bq24210.en_port->out & bq24210.en_bit)); rc = readBQ27510(i2c, 0, nwords, u.raw); temperature_dC = u.state.temperature_dK - 2733; cprintf("%s: %c%c%c % 2d.%dC %4dmV ; SoC %u%% ; Cap %4d / %4d ; %dmA ~ %dmA / %u\n", xBSP430uptimeAsText(ulBSP430uptime(), astext_buf), (bq24210.en_port->out & bq24210.en_bit) ? ' ' : 'E', (bq24210.chg_port->in & bq24210.chg_bit) ? ' ' : 'C', (bq24210.pg_port->in & bq24210.pg_bit) ? ' ' : 'P', (temperature_dC / 10), (temperature_dC % 10), u.state.voltage_mV, u.state.stateOfCharge_ppc, u.state.remainingCapacity_mAh, u.state.fullAvailableCapacity_mAh, u.state.instantaneousCurrent_mA, u.state.averageCurrent_mA, u.state.cycleCount ); if (FLG_UPDATE_INTERVAL & flags) { resample_wake_utt += resample_interval_utt; flags &= ~FLG_UPDATE_INTERVAL; } flags = 0; while (! flags) { iBSP430consoleFlush(); if (0 >= lBSP430uptimeSleepUntil(resample_wake_utt, LPM3_bits)) { flags |= FLG_UPDATE_INTERVAL; } while (0 <= ((rc = cgetchar()))) { if ('!' == rc) { flags |= FLG_TOGGLE_ENABLE; } else if (' ' == rc) { flags |= FLG_DUMP_STATE; } } } } }
void main (void) { unsigned long wake_utt; int rc; long lrc; char as_text[BSP430_UPTIME_AS_TEXT_LENGTH]; uint32_u ntp_addr; uint32_u self_addr; vBSP430platformInitialize_ni(); (void)iBSP430consoleInitialize(); cprintf("\nntp " __DATE__ " " __TIME__ "\n"); /* Initialization can be done with interrupts disabled, since the * function does nothing but store callbacks. We use the same * callback for all three update capabilities. */ rc = iBSP430cc3000spiInitialize(wlan_cb, NULL, NULL, NULL); if (0 > rc) { cprintf("ERR: Initialization failed: %d\n", rc); return; } BSP430_CORE_ENABLE_INTERRUPT(); /* Local addresses use all zeros for inet addr. bind does not * support dynamic assignment of unused port through sin_port=0. */ memset(&local_addr, 0, sizeof(local_addr)); local_addr.sai.sin_family = AF_INET; local_addr.sai.sin_port = htons(60123); /* Remote server will be determined by DNS from the NTP pool once we * start. */ remote_addr = local_addr; remote_addr.sai.sin_port = htons(123); ntp_addr.u32 = 0; self_addr.u32 = 0; cprintf("Remote: %s:%u\n", net_ipv4AsText(&remote_addr.sai.sin_addr), ntohs(remote_addr.sai.sin_port)); rc = sizeof(sBSP430uptimeNTPPacketHeader); if (48 != rc) { cprintf("ERR: NTP header size %d\n", rc); return; } wake_utt = ulBSP430uptime(); (void)rc; while (1) { unsigned long timeout_utt; do { tNetappIpconfigRetArgs ipc; unsigned long start_utt; unsigned long finished_utt; int sfd; int nfds; fd_set rfds; int servers_left; int retries_left; /* Clear everything as we're starting a cycle */ BSP430_CORE_DISABLE_INTERRUPT(); do { event_flags_v = 0; start_utt = ulBSP430uptime_ni(); } while (0); BSP430_CORE_ENABLE_INTERRUPT(); /* Start the WAN process. This is asynchronous; wait up to 2 * seconds for it to complete. */ cprintf("%s: ", xBSP430uptimeAsText(start_utt, as_text)); cputchar('W'); wlan_start(0); vBSP430ledSet(BSP430_LED_RED, 1); (void)wlan_set_event_mask(0UL); lrc = BSP430_UPTIME_MS_TO_UTT(2000); timeout_utt = ulBSP430uptime() + lrc; while ((! (EVENT_FLAG_WLANCONN & event_flags_v)) && (0 < ((lrc = lBSP430uptimeSleepUntil(timeout_utt, LPM0_bits))))) { } if (! (EVENT_FLAG_WLANCONN & event_flags_v)) { cprintf("WLAN start failed\n"); break; } /* Wait for IP connectivity (signalled by a DHCP event). * Continue using the previous timeout. */ cputchar('D'); while ((! (EVENT_FLAG_IPCONN & event_flags_v)) && (0 < ((lrc = lBSP430uptimeSleepUntil(timeout_utt, LPM0_bits))))) { } if (! (EVENT_FLAG_IPCONN & event_flags_v)) { cprintf("IP conn failed\n"); break; } /* Inspect the IP configuration. Sometimes we get the event, * but there's no IP assigned. */ netapp_ipconfig(&ipc); memcpy(self_addr.u8, ipc.aucIP, sizeof(self_addr)); if (! self_addr.u32) { cprintf("IP assignment failed\n"); break; } vBSP430ledSet(BSP430_LED_GREEN, 1); /* Obtain a UDP socket and bind it for local operations. */ cputchar('I'); sfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if (0 > sfd) { cprintf("socket() failed: %d\n", sfd); break; } cputchar('S'); lrc = bind(sfd, &local_addr.sa, sizeof(local_addr.sa)); if (0 > lrc) { cprintf("bind() failed: %ld\n", lrc); break; } cputchar('B'); servers_left = NTP_SERVERS_PER_ATTEMPT; retries_left = NTP_REQUESTS_PER_SERVER; do { sBSP430uptimeNTPPacketHeader ntp0; sBSP430uptimeNTPPacketHeader ntp1; int have_invalid_epoch; struct timeval tv; sockaddr_u src; socklen_t slen = sizeof(src); unsigned long recv_utt; uint64_t recv_ntp; int64_t adjustment_ntp; long adjustment_ms; unsigned long rtt_us; have_invalid_epoch = 0 != iBSP430uptimeCheckEpochValidity(); if (! remote_addr.sai.sin_addr.s_addr) { const char ntp_fqdn[] = "0.pool.ntp.org"; ntp_addr.u32 = 0; rc = gethostbyname((char *)ntp_fqdn, sizeof(ntp_fqdn)-1, &ntp_addr.u32); cputchar('d'); if (-95 == rc) { /* ARP request failed; retry usually works */ rc = gethostbyname((char *)ntp_fqdn, sizeof(ntp_fqdn)-1, &ntp_addr.u32); cputchar('d'); } if (0 == ntp_addr.u32) { cprintf("gethostbyname(%s) failed: %d\n", ntp_fqdn, rc); rc = -1; break; } remote_addr.sai.sin_addr.s_addr = htonl(ntp_addr.u32); cprintf("{%s}", net_ipv4AsText(&remote_addr.sai.sin_addr)); retries_left = NTP_REQUESTS_PER_SERVER; } /* Configure the NTP request and send it */ iBSP430uptimeInitializeNTPRequest(&ntp0); iBSP430uptimeSetNTPXmtField(&ntp0, NULL); BSP430_CORE_DISABLE_INTERRUPT(); do { /* Clear the shutdown bit, so we know when it's ok to shut * down after this send */ event_flags_v &= ~EVENT_FLAG_SHUTDOWN; } while (0); BSP430_CORE_ENABLE_INTERRUPT(); rc = sendto(sfd, &ntp0, sizeof(ntp0), 0, &remote_addr.sa, sizeof(remote_addr.sai)); if (sizeof(ntp0) != rc) { cprintf("sendto %s:%u failed: %d\n", net_ipv4AsText(&remote_addr.sai.sin_addr), ntohs(remote_addr.sai.sin_port), rc); rc = -1; break; } cputchar('s'); /* If we get an answer it should be here in less than 100 * ms, but give it 400 ms just to be kind. */ tv.tv_sec = 0; tv.tv_usec = 400000UL; FD_ZERO(&rfds); FD_SET(sfd, &rfds); nfds = sfd+1; rc = select(nfds, &rfds, NULL, NULL, &tv); if (! FD_ISSET(sfd, &rfds)) { /* We didn't get an answer. If there are any retries left, use them. */ if (0 < retries_left--) { rc = 1; continue; } /* No retries left on this server: forget about it. If * there are any servers left, try another. */ cputchar('!'); remote_addr.sai.sin_addr.s_addr = 0; if (0 < servers_left--) { rc = 1; continue; } /* No retries from all available servers. Fail this attempt */ cprintf("no responsive NTP server found\n"); rc = -1; break; } /* Got a response. Record the time it came in and then read * it (no high-resolution packet RX time available, but we * believe it's here already so set the RX time first). The * message is unacceptable if it isn't an NTP packet. */ recv_utt = ulBSP430uptime(); rc = recvfrom(sfd, &ntp1, sizeof(ntp1), 0, &src.sa, &slen); if (sizeof(ntp1) != rc) { cprintf("recv failed: %d\n", rc); rc = -1; break; } cputchar('r'); /* Convert the RX time to NTP, then process the message to * determine the offset. */ rc = iBSP430uptimeAsNTP(recv_utt, &recv_ntp, have_invalid_epoch); if (0 != rc) { cprintf("NTP decode failed: %d\n", rc); continue; } rc = iBSP430uptimeProcessNTPResponse(&ntp0, &ntp1, recv_ntp, &adjustment_ntp, &adjustment_ms, &rtt_us); if (0 != rc) { cprintf("Process failed: %d\n", rc); continue; } if (have_invalid_epoch) { rc = iBSP430uptimeSetEpochFromNTP(BSP430_UPTIME_BYPASS_EPOCH_NTP + adjustment_ntp); cputchar('E'); if (0 != rc) { cprintf("\nERR: SetEpoch failed: %d\n", rc); } #if (NTP_ADJUST_EACH_ITER - 0) } else { rc = iBSP430uptimeAdjustEpochFromNTP(adjustment_ntp); cputchar('A'); if (0 != rc) { cprintf("\nERR: AdjustEpoch failed: %d\n", rc); } #endif } cprintf("[%s:%u adj %lld ntp = %ld ms, rtt %lu us]", net_ipv4AsText(&remote_addr.sai.sin_addr), ntohs(remote_addr.sai.sin_port), adjustment_ntp, adjustment_ms, rtt_us); } while (0 != rc); if (0 != rc) { cprintf("NTP query failed\n"); break; } #if 0 /* The shutdown OK seems to arrive about 1000 ms after the last * transmit, which is unnecessarily long. As we're not doing * TCP, there's no reason to wait for it. */ lrc = BSP430_UPTIME_MS_TO_UTT(4000); timeout_utt = ulBSP430uptime() + lrc; while ((! (EVENT_FLAG_SHUTDOWN & event_flags_v)) && (0 < ((lrc = lBSP430uptimeSleepUntil(timeout_utt, LPM0_bits))))) { } if (! (EVENT_FLAG_SHUTDOWN & event_flags_v)) { cprintf("SHUTDOWN ok never received\n"); break; } #endif finished_utt = ulBSP430uptime(); cprintf("[%s]\n", xBSP430uptimeAsText(finished_utt - start_utt, as_text)); } while (0); BSP430_CORE_DISABLE_INTERRUPT(); do { event_flags_v = 0; } while (0); BSP430_CORE_ENABLE_INTERRUPT(); wlan_stop(); vBSP430ledSet(BSP430_LED_GREEN, 0); vBSP430ledSet(BSP430_LED_RED, 0); wake_utt += 60 * ulBSP430uptimeConversionFrequency_Hz(); while (0 < lBSP430uptimeSleepUntil(wake_utt, LPM2_bits)) { } } cprintf("Fell off end\n"); }