Test program running on MAX32625MBED. Control through USB Serial commands using a terminal emulator such as teraterm or putty.
Dependencies: MaximTinyTester CmdLine MAX541 USBDevice
MAX11043.cpp
00001 // /******************************************************************************* 00002 // * Copyright (C) 2020 Maxim Integrated Products, Inc., All Rights Reserved. 00003 // * 00004 // * Permission is hereby granted, free of charge, to any person obtaining a 00005 // * copy of this software and associated documentation files (the "Software"), 00006 // * to deal in the Software without restriction, including without limitation 00007 // * the rights to use, copy, modify, merge, publish, distribute, sublicense, 00008 // * and/or sell copies of the Software, and to permit persons to whom the 00009 // * Software is furnished to do so, subject to the following conditions: 00010 // * 00011 // * The above copyright notice and this permission notice shall be included 00012 // * in all copies or substantial portions of the Software. 00013 // * 00014 // * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 00015 // * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 00016 // * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 00017 // * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES 00018 // * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 00019 // * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 00020 // * OTHER DEALINGS IN THE SOFTWARE. 00021 // * 00022 // * Except as contained in this notice, the name of Maxim Integrated 00023 // * Products, Inc. shall not be used except as stated in the Maxim Integrated 00024 // * Products, Inc. Branding Policy. 00025 // * 00026 // * The mere transfer of this software does not imply any licenses 00027 // * of trade secrets, proprietary technology, copyrights, patents, 00028 // * trademarks, maskwork rights, or any other form of intellectual 00029 // * property whatsoever. Maxim Integrated Products, Inc. retains all 00030 // * ownership rights. 00031 // ******************************************************************************* 00032 // */ 00033 // ********************************************************************* 00034 // @file MAX11043.cpp 00035 // ********************************************************************* 00036 // Device Driver file 00037 // DO NOT EDIT; except areas designated "CUSTOMIZE". Automatically generated file. * MANUAL EDITS PRESENT * 00038 // generated by XMLSystemOfDevicesToMBED.py 00039 // System Name = ExampleSystem 00040 // System Description = Device driver example 00041 00042 #include "MAX11043.h" 00043 //-------------------------------------------------- 00044 // MAX11043 ADC Read operations must be synchronized to EOC End Of Conversion 00045 // EOC# asserts low when new data is available. 00046 // Initiate a data read prior to the next rising edge of EOC# or the result is overwritten. 00047 #ifndef MAX11043_EOC_INTERRUPT_POLLING 00048 #define MAX11043_EOC_INTERRUPT_POLLING 1 00049 #endif // MAX11043_EOC_INTERRUPT_POLLING 00050 //-------------------------------------------------- 00051 // SPI is not interrupt-safe, so use EventQueue to defer execution to user context. 00052 #ifndef MAX11043_EOC_INTERRUPT_EVENTQUEUE 00053 #define MAX11043_EOC_INTERRUPT_EVENTQUEUE 0 00054 #endif // MAX11043_EOC_INTERRUPT_EVENTQUEUE 00055 #if MAX11043_EOC_INTERRUPT_EVENTQUEUE 00056 #else // MAX11043_EOC_INTERRUPT_EVENTQUEUE 00057 #endif // MAX11043_EOC_INTERRUPT_EVENTQUEUE 00058 #if MAX11043_EOC_INTERRUPT_EVENTQUEUE 00059 // SPI is not interrupt-safe, so use EventQueue to defer execution to user context. 00060 #include "mbed_events.h" 00061 #define MYONEOCTHREADEVENTFLAG_ENABLE_SPI (1UL << 0) 00062 EventFlags myOnEOCThread_event_flags; 00063 Thread myOnEOCThread; 00064 #if MAX11043_EOC_INTERRUPT_POLLING 00065 // MAX11043 myOnEOCThread_POLLING_handler needs 18.80us, still too slow 00066 extern DigitalInOut digitalInOut2; // m_EOC_pin declared in Test_Main_MAX11043.cpp 00067 extern void myOnEOCThread_POLLING_handler(); 00068 #else // MAX11043_EOC_INTERRUPT_POLLING 00069 extern void myOnEOCThread_EVENTFLAG_ENABLE_SPI_handler(); 00070 #endif // MAX11043_EOC_INTERRUPT_POLLING 00071 #else // MAX11043_EOC_INTERRUPT_EVENTQUEUE 00072 #endif // MAX11043_EOC_INTERRUPT_EVENTQUEUE 00073 //-------------------------------------------------- 00074 // Diagnostic: Use MAX32625MBED pin D5 as DigitalOut EOC#-detected 00075 #ifndef MAX11043_ScopeTrigger_MAX32625MBED_D5 00076 #define MAX11043_ScopeTrigger_MAX32625MBED_D5 1 00077 #endif // MAX11043_ScopeTrigger_MAX32625MBED_D5 00078 #if MAX11043_ScopeTrigger_MAX32625MBED_D5 00079 // Diagnostic: Use MAX32625MBED pin D5 as DigitalOut EOC#-detected 00080 // WIP MAX11043 interrupt EOC echo - moving DigitalOut ScopeTrigger to global scope, it compiles but there is no activity on scope 00081 extern DigitalInOut digitalInOut5; // declared in Test_Main_MAX11043.cpp (D5, PIN_INPUT, PullUp, 1) 00082 const size_t byteCount_onEOCFallingEdge = 1 + (2 * 4); 00083 const uint8_t mosiData_onEOCFallingEdge[9] = { 00084 MAX11043::CMD_0001_1010_d16o8_d16o8_d16o8_d16o8_Rd06_ADCabcd, 00085 0, 0, 0, 0, 0, 0, 0, 0 00086 }; 00087 uint8_t misoData_onEOCFallingEdge[9]; 00088 #endif // MAX11043_ScopeTrigger_MAX32625MBED_D5 00089 00090 // Device Name = MAX11043 00091 // Device Description = 200ksps, Low-Power, Serial SPI 24-Bit, 4-Channel, Differential/Single-Ended Input, Simultaneous-Sampling SD ADC 00092 // Device DeviceBriefDescription = 24-bit 200ksps Delta-Sigma ADC 00093 // Device Manufacturer = Maxim Integrated 00094 // Device PartNumber = MAX11043ATL+ 00095 // Device RegValue_Width = DataWidth16bit_HL 00096 // 00097 // ADC MaxOutputDataRate = 200ksps 00098 // ADC NumChannels = 4 00099 // ADC ResolutionBits = 24 00100 // 00101 // SPI CS = ActiveLow 00102 // SPI FrameStart = CS 00103 // SPI CPOL = 0 00104 // SPI CPHA = 0 00105 // SPI MOSI and MISO Data are both stable on Rising edge of SCLK 00106 // SPI SCLK Idle Low 00107 // SPI SCLKMaxMHz = 40 00108 // SPI SCLKMinMHz = 0 00109 // 00110 // InputPin Name = CONVRUN 00111 // InputPin Description = CONVRUN (digital input). Convert Run. Drive high to start continuous conversions on all 4 channels. The device is idle when 00112 // CONVRUN is low. 00113 // InputPin Function = Configuration 00114 // 00115 // InputPin Name = SHDN 00116 // InputPin Description = Shutdown (digital input). Active-High Shutdown Input. Drive high to shut down the MAX11043. 00117 // InputPin Function = Configuration 00118 // 00119 // InputPin Name = DACSTEP 00120 // InputPin Description = DACSTEP (digital input). DAC Step Input. Drive high to move the DAC output in the direction of UP/DWN on the next rising 00121 // edge of the system clock. 00122 // InputPin Function = Configuration 00123 // 00124 // InputPin Name = UP/DWN# 00125 // InputPin Description = UP/DWN# (digital input). DAC Step Direction Select. Drive high to step up, drive low to step down when DACSTEP is toggled. 00126 // InputPin Function = Configuration 00127 // 00128 // OutputPin Name = EOC 00129 // OutputPin Description = End of Conversion Output. Active-Low End-of-Conversion Indicator. EOC asserts low to indicate that new data is ready. 00130 // OutputPin Function = Event 00131 // 00132 // SupplyPin Name = AVDD 00133 // SupplyPin Description = Analog Power-Supply Input. Bypass each AVDD with a nominal 1uF capacitor to AGND. 00134 // SupplyPin VinMax = 3.60 00135 // SupplyPin VinMin = 3.00 00136 // SupplyPin Function = Analog 00137 // 00138 // SupplyPin Name = AGND 00139 // SupplyPin Description = Analog Ground. Connect all AGND inputs together. 00140 // SupplyPin VinMax = 0 00141 // SupplyPin VinMin = 0 00142 // SupplyPin Function = Analog 00143 // 00144 // SupplyPin Name = DGND 00145 // SupplyPin Description = Digital Ground. Connect all DGND inputs together. 00146 // SupplyPin VinMax = 0 00147 // SupplyPin VinMin = 0 00148 // SupplyPin Function = Digital 00149 // 00150 // SupplyPin Name = DVDD 00151 // SupplyPin Description = Digital Power-Supply Input. Bypass each DVDD with a nominal 1uF capacitor to DGND. 00152 // SupplyPin VinMax = 3.60 00153 // SupplyPin VinMin = 3.00 00154 // SupplyPin Function = Digital 00155 // 00156 // SupplyPin Name = DVREG 00157 // SupplyPin Description = Regulated Digital Core Supply (from internal +2.5V regulator). Bypass DVREG to DGND with a 10uF capacitor. 00158 // SupplyPin VinMax = 2.50 00159 // SupplyPin VinMin = 2.50 00160 // SupplyPin Function = Digital 00161 // 00162 00163 // CODE GENERATOR: class constructor definition 00164 MAX11043::MAX11043(SPI &spi, DigitalOut &cs_pin, // SPI interface 00165 // CODE GENERATOR: class constructor definition gpio InputPin pins 00166 DigitalOut &CONVRUN_pin, // Digital Configuration Input to MAX11043 device 00167 DigitalOut &SHDN_pin, // Digital Configuration Input to MAX11043 device 00168 DigitalOut &DACSTEP_pin, // Digital Configuration Input to MAX11043 device 00169 DigitalOut &UP_slash_DWNb_pin, // Digital Configuration Input to MAX11043 device 00170 // CODE GENERATOR: class constructor definition gpio OutputPin pins 00171 // MAX11043 ADC Read operations must be synchronized to EOC End Of Conversion 00172 #if MAX11043_EOC_INTERRUPT_POLLING 00173 // MAX11043 EOC End Of Conversion input should be InterruptIn(PinName:EOC_pin).fall(onEOCFallingEdge); 00174 // Workaround using DigitalIn(PinName:EOC_pin) polled to sync with EOC falling edge for ADC reads 00175 // TODO: onEOCFallingEdge: replace DigitalIn &EOC_pin with PinName EOC_pin, so that I can create an InterruptIn(PinName:EOC_pin) 00176 DigitalIn &EOC_pin, // Digital Event Output from MAX11043 device 00177 #else // MAX11043_EOC_INTERRUPT_POLLING 00178 // MAX11043 EOC End Of Conversion input is InterruptIn(PinName:EOC_pin).fall(onEOCFallingEdge); 00179 // TODO: onEOCFallingEdge: replace DigitalIn &EOC_pin with PinName EOC_pin, so that I can create an InterruptIn(PinName:EOC_pin) 00180 InterruptIn &EOC_pin, // Digital Event Output from MAX11043 device 00181 #endif // MAX11043_EOC_INTERRUPT_POLLING 00182 // CODE GENERATOR: class constructor definition ic_variant 00183 MAX11043_ic_t ic_variant) 00184 // CODE GENERATOR: class constructor initializer list 00185 : m_spi(spi), m_cs_pin(cs_pin), // SPI interface 00186 // CODE GENERATOR: class constructor initializer list gpio InputPin pins 00187 m_CONVRUN_pin(CONVRUN_pin), // Digital Configuration Input to MAX11043 device 00188 m_SHDN_pin(SHDN_pin), // Digital Configuration Input to MAX11043 device 00189 m_DACSTEP_pin(DACSTEP_pin), // Digital Configuration Input to MAX11043 device 00190 m_UP_slash_DWNb_pin(UP_slash_DWNb_pin), // Digital Configuration Input to MAX11043 device 00191 // CODE GENERATOR: class constructor initializer list gpio OutputPin pins 00192 // MAX11043 ADC Read operations must be synchronized to EOC End Of Conversion 00193 #if MAX11043_EOC_INTERRUPT_POLLING 00194 // MAX11043 EOC End Of Conversion input should be InterruptIn(PinName:EOC_pin).fall(onEOCFallingEdge); 00195 // Workaround using DigitalIn(PinName:EOC_pin) polled to sync with EOC falling edge for ADC reads 00196 m_EOC_pin(EOC_pin), // Digital Event Output from MAX11043 device 00197 #else // MAX11043_EOC_INTERRUPT_POLLING 00198 // MAX11043 EOC End Of Conversion input is InterruptIn(PinName:EOC_pin).fall(onEOCFallingEdge); 00199 m_EOC_pin(EOC_pin), // Digital Event Output from MAX11043 device 00200 #endif // MAX11043_EOC_INTERRUPT_POLLING 00201 // CODE GENERATOR: class constructor initializer list ic_variant 00202 m_ic_variant(ic_variant) 00203 { 00204 // CODE GENERATOR: class constructor definition SPI interface initialization 00205 // 00206 // SPI CS = ActiveLow 00207 // SPI FrameStart = CS 00208 m_SPI_cs_state = 1; 00209 if (m_cs_pin.is_connected()) { // avoid mbed runtime error if pin is NC not connected 00210 m_cs_pin = m_SPI_cs_state; 00211 } 00212 00213 // SPI CPOL = 0 00214 // SPI CPHA = 0 00215 // SPI MOSI and MISO Data are both stable on Rising edge of SCLK 00216 // SPI SCLK Idle Low 00217 m_SPI_dataMode = 0; //SPI_MODE0; // CPOL=0,CPHA=0: Rising Edge stable; SCLK idle Low 00218 m_spi.format(8,m_SPI_dataMode); // int bits_must_be_8, int mode=0_3 CPOL=0,CPHA=0 00219 00220 // SPI SCLKMaxMHz = 40 00221 // SPI SCLKMinMHz = 0 00222 //#define SPI_SCLK_Hz 48000000 // 48MHz 00223 //#define SPI_SCLK_Hz 24000000 // 24MHz 00224 //#define SPI_SCLK_Hz 12000000 // 12MHz 00225 //#define SPI_SCLK_Hz 6000000 // 6MHz 00226 //#define SPI_SCLK_Hz 4000000 // 4MHz 00227 //#define SPI_SCLK_Hz 2000000 // 2MHz 00228 //#define SPI_SCLK_Hz 1000000 // 1MHz 00229 m_SPI_SCLK_Hz = 24000000; // platform limit 24MHz; MAX11043 limit is 40MHz 00230 m_spi.frequency(m_SPI_SCLK_Hz); 00231 00232 // 00233 // CODE GENERATOR: class constructor definition gpio InputPin (Input to device) initialization 00234 // 00235 // CONVRUN Configuration Input to MAX11043 device 00236 m_CONVRUN_pin = 1; // output logic high -- initial value in constructor 00237 // 00238 // SHDN Configuration Input to MAX11043 device 00239 m_SHDN_pin = 1; // output logic high -- initial value in constructor 00240 // 00241 // DACSTEP Configuration Input to MAX11043 device 00242 m_DACSTEP_pin = 1; // output logic high -- initial value in constructor 00243 // 00244 // UP_slash_DWNb Configuration Input to MAX11043 device 00245 m_UP_slash_DWNb_pin = 1; // output logic high -- initial value in constructor 00246 // 00247 // CODE GENERATOR: class constructor definition gpio OutputPin (Output from MAX11043 device) initialization 00248 // 00249 // EOC Event Output from device 00250 // MAX11043 ADC Read operations must be synchronized to EOC End Of Conversion 00251 #if MAX11043_ScopeTrigger_MAX32625MBED_D5 00252 digitalInOut5.output(); // ScopeTrigger 00253 #endif // MAX11043_ScopeTrigger_MAX32625MBED_D5 00254 #if MAX11043_EOC_INTERRUPT_EVENTQUEUE 00255 // SPI is not interrupt-safe, so use EventQueue to defer execution to user context. 00256 #if MAX11043_EOC_INTERRUPT_POLLING 00257 myOnEOCThread.start(myOnEOCThread_POLLING_handler); 00258 #else // MAX11043_EOC_INTERRUPT_POLLING 00259 myOnEOCThread.start(myOnEOCThread_EVENTFLAG_ENABLE_SPI_handler); 00260 #endif // MAX11043_EOC_INTERRUPT_POLLING 00261 #else // MAX11043_EOC_INTERRUPT_EVENTQUEUE 00262 #endif // MAX11043_EOC_INTERRUPT_EVENTQUEUE 00263 // MAX11043 ADC Read operations must be synchronized to EOC End Of Conversion 00264 #if MAX11043_EOC_INTERRUPT_POLLING 00265 // MAX11043 EOC End Of Conversion input should be InterruptIn(PinName:EOC_pin).fall(onEOCFallingEdge); 00266 // Workaround using DigitalIn(PinName:EOC_pin) polled to sync with EOC falling edge for ADC reads 00267 #else // MAX11043_EOC_INTERRUPT_POLLING 00268 // MAX11043 EOC End Of Conversion input is InterruptIn(PinName:EOC_pin).fall(onEOCFallingEdge); 00269 // TODO: onEOCFallingEdge: interrupt handler requires global object extern MAX11043 g_MAX11043_device 00270 // InterruptIn interruptEOC(EOC_pin); // InterruptIn constructor requires PinName, not DigitalIn -- Error: No instance of constructor "mbed::InterruptIn::InterruptIn" matches the argument list in "MAX11043/MAX11043.cpp", Line: 187, Col: 31 00271 // TODO: onEOCFallingEdge: replace DigitalIn &EOC_pin with PinName EOC_pin, so that I can create an InterruptIn(PinName:EOC_pin) 00272 extern void onEOCFallingEdge(void); 00273 // interruptEOC.fall(&onEOCFallingEdge); 00274 EOC_pin.fall(&onEOCFallingEdge); 00275 #endif // MAX11043_EOC_INTERRUPT_POLLING 00276 } 00277 00278 // MAX11043 ADC Read operations must be synchronized to EOC End Of Conversion 00279 // SPI is not interrupt-safe, so use EventQueue to defer execution to user context. 00280 #if MAX11043_EOC_INTERRUPT_EVENTQUEUE 00281 #if MAX11043_EOC_INTERRUPT_POLLING 00282 void myOnEOCThread_POLLING_handler() 00283 { 00284 while (true) { 00285 // MAX11043 EOC End Of Conversion input should be InterruptIn(PinName:EOC_pin).fall(onEOCFallingEdge); 00286 // Workaround using DigitalIn(PinName:EOC_pin) polled to sync with EOC falling edge for ADC reads 00287 // poll m_EOC_pin if CONVRUN is high 00288 //if (m_CONVRUN_pin) 00289 //{ 00290 //#warning "myOnEOCThread_handler() Potential infinite loop if EOC pin not connected" 00291 // possible infinite loop; need a timeout or futility countdown to escape 00292 #if MAX11043_ScopeTrigger_MAX32625MBED_D5 00293 // Diagnostic: Use MAX32625MBED pin D5 as DigitalOut EOC#-detected 00294 //~ digitalInOut5.write(0); // ScopeTrigger low -- waiting for EOC# high 00295 //~ digitalInOut5.write(1); // ScopeTrigger 00296 //~ digitalInOut5.write(0); // ScopeTrigger 00297 //~ digitalInOut5.write(1); // ScopeTrigger 00298 #endif // MAX11043_ScopeTrigger_MAX32625MBED_D5 00299 //for (int futility_countdown = 100; 00300 // ((futility_countdown > 0) && 00301 // (m_EOC_pin != 1)); 00302 // futility_countdown--) 00303 //while (digitalInOut2.read() != 1) // digitalInOut2 m_EOC_pin 00304 //{ 00305 // // spinlock waiting for logic high pin state (start of new conversion) 00306 //} 00307 #if MAX11043_ScopeTrigger_MAX32625MBED_D5 00308 // Diagnostic: Use MAX32625MBED pin D5 as DigitalOut EOC#-detected 00309 //~ digitalInOut5.write(0); // ScopeTrigger 00310 //~ digitalInOut5.write(1); // ScopeTrigger high -- waiting for EOC# falling edge 00311 //~ digitalInOut5.write(0); // ScopeTrigger 00312 //~ digitalInOut5.write(1); // ScopeTrigger 00313 #endif // MAX11043_ScopeTrigger_MAX32625MBED_D5 00314 //for (int futility_countdown = 100; 00315 // ((futility_countdown > 0) && 00316 // (m_EOC_pin != 0)); 00317 // futility_countdown--) 00318 while (digitalInOut2.read() != 0) // digitalInOut2 m_EOC_pin 00319 { 00320 // spinlock waiting for logic low pin state (new data is available) 00321 } 00322 //} 00323 //else 00324 //{ 00325 // // CONVRUN pin is being driven low, so conversion result will not change, EOC# remains high 00326 // continue; 00327 //} 00328 // 00329 //extern MAX11043 g_MAX11043_device; 00330 #if MAX11043_ScopeTrigger_MAX32625MBED_D5 00331 // Diagnostic: Use MAX32625MBED pin D5 as DigitalOut EOC#-detected 00332 //~ digitalInOut5.write(0); // ScopeTrigger low -- EOC# falling edge detected, about to start SPI 00333 //~ digitalInOut5.write(1); // ScopeTrigger 00334 //~ digitalInOut5.write(0); // ScopeTrigger 00335 //~ digitalInOut5.write(1); // ScopeTrigger 00336 #endif // MAX11043_ScopeTrigger_MAX32625MBED_D5 00337 extern SPI spi; // declared in Test_Main_MAX11043.cpp 00338 spi.write((char*)mosiData_onEOCFallingEdge, byteCount_onEOCFallingEdge, (char*)misoData_onEOCFallingEdge, byteCount_onEOCFallingEdge); 00339 // Note: EOC# is high immediately after SPI read ADCabcd 00340 // SPI timing: CS low 13.30us after EOC# falling edge 00341 // SPI timing: SCLK first 14.60us after EOC# falling edge 00342 // SPI timing: SCLK last 17.70us after EOC# falling edge 00343 // SPI timing: CS high 17.70us after EOC# falling edge 00344 // 00345 // TODO1: update adca 00346 //g_MAX11043_device.adca = (misoData_onEOCFallingEdge[1] << 8) | misoData_onEOCFallingEdge[2]; 00347 // TODO1: update adcb 00348 //g_MAX11043_device.adcb = (misoData_onEOCFallingEdge[3] << 8) | misoData_onEOCFallingEdge[4]; 00349 // TODO1: update adcc 00350 //g_MAX11043_device.adcc = (misoData_onEOCFallingEdge[5] << 8) | misoData_onEOCFallingEdge[6]; 00351 // TODO1: update adcd 00352 //g_MAX11043_device.adcd = (misoData_onEOCFallingEdge[7] << 8) | misoData_onEOCFallingEdge[8]; 00353 #if MAX11043_ScopeTrigger_MAX32625MBED_D5 00354 // Diagnostic: Use MAX32625MBED pin D5 as DigitalOut EOC#-detected 00355 //~ digitalInOut5.write(0); // ScopeTrigger 00356 //~ digitalInOut5.write(1); // ScopeTrigger high -- end of while loop 00357 //~ digitalInOut5.write(0); // ScopeTrigger 00358 //~ digitalInOut5.write(1); // ScopeTrigger 00359 #endif // MAX11043_ScopeTrigger_MAX32625MBED_D5 00360 } // while (true) 00361 } // myOnEOCThread_POLLING_handler() 00362 #else // MAX11043_EOC_INTERRUPT_POLLING 00363 // Waiting for EOC# fall to signal EventQueue is too slow, ~25us to handle event but events happen every 9us. 00364 void myOnEOCThread_EVENTFLAG_ENABLE_SPI_handler() 00365 { 00366 while (true) { 00367 // MAX11043 EOC End Of Conversion input is InterruptIn(PinName:EOC_pin).fall(onEOCFallingEdge); 00368 // Interrupt Handler: EOC Event Output from device 00369 // Wait for MYONEOCTHREADEVENTFLAG_ENABLE_SPI event sent from onEOCFallingEdge interrupt 00370 //signal_wait(int32_t signals, uint32_t millisec=osWaitForever) 00371 //flags_read = myOnEOCThread_event_flags.wait_any(MYONEOCTHREADEVENTFLAG_ENABLE_SPI); 00372 // myOnEOCThread_event_flags.wait_any(MYONEOCTHREADEVENTFLAG_ENABLE_SPI, osWaitForever, false); // clear=false: don't auto clear the flag 00373 myOnEOCThread_event_flags.wait_any(MYONEOCTHREADEVENTFLAG_ENABLE_SPI, osWaitForever, true); // clear=true: auto clear the flag 00374 // 00375 //extern MAX11043 g_MAX11043_device; 00376 #if MAX11043_ScopeTrigger_MAX32625MBED_D5 00377 // Diagnostic: Use MAX32625MBED pin D5 as DigitalOut EOC#-detected 00378 digitalInOut5.write(0); // ScopeTrigger happens at 1.8us after EOC# falling edge 00379 digitalInOut5.write(1); // ScopeTrigger 00380 digitalInOut5.write(0); // ScopeTrigger 00381 digitalInOut5.write(1); // ScopeTrigger 00382 #endif // MAX11043_ScopeTrigger_MAX32625MBED_D5 00383 extern SPI spi; // declared in Test_Main_MAX11043.cpp 00384 spi.write((char*)mosiData_onEOCFallingEdge, byteCount_onEOCFallingEdge, (char*)misoData_onEOCFallingEdge, byteCount_onEOCFallingEdge); 00385 // SPI timing: CS low 13.30us after EOC# falling edge 00386 // SPI timing: SCLK first 14.60us after EOC# falling edge 00387 // SPI timing: SCLK last 17.70us after EOC# falling edge 00388 // SPI timing: CS high 17.70us after EOC# falling edge 00389 // 00390 // TODO1: update adca 00391 //g_MAX11043_device.adca = (misoData_onEOCFallingEdge[1] << 8) | misoData_onEOCFallingEdge[2]; 00392 // TODO1: update adcb 00393 //g_MAX11043_device.adcb = (misoData_onEOCFallingEdge[3] << 8) | misoData_onEOCFallingEdge[4]; 00394 // TODO1: update adcc 00395 //g_MAX11043_device.adcc = (misoData_onEOCFallingEdge[5] << 8) | misoData_onEOCFallingEdge[6]; 00396 // TODO1: update adcd 00397 //g_MAX11043_device.adcd = (misoData_onEOCFallingEdge[7] << 8) | misoData_onEOCFallingEdge[8]; 00398 #if MAX11043_ScopeTrigger_MAX32625MBED_D5 00399 // Diagnostic: Use MAX32625MBED pin D5 as DigitalOut EOC#-detected 00400 digitalInOut5.write(0); // ScopeTrigger happens at 22.5us after EOC# falling edge 00401 digitalInOut5.write(1); // ScopeTrigger 00402 digitalInOut5.write(0); // ScopeTrigger 00403 digitalInOut5.write(1); // ScopeTrigger 00404 #endif // MAX11043_ScopeTrigger_MAX32625MBED_D5 00405 } // while (true) 00406 } // myOnEOCThread_EVENTFLAG_ENABLE_SPI_handler() 00407 #endif // MAX11043_EOC_INTERRUPT_POLLING 00408 #endif // MAX11043_EOC_INTERRUPT_EVENTQUEUE 00409 00410 // MAX11043 ADC Read operations must be synchronized to EOC End Of Conversion 00411 #if MAX11043_EOC_INTERRUPT_POLLING 00412 // MAX11043 EOC End Of Conversion input should be InterruptIn(PinName:EOC_pin).fall(onEOCFallingEdge); 00413 // Workaround using DigitalIn(PinName:EOC_pin) polled to sync with EOC falling edge for ADC reads 00414 #else // MAX11043_EOC_INTERRUPT_POLLING 00415 // MAX11043 EOC End Of Conversion input is InterruptIn(PinName:EOC_pin).fall(onEOCFallingEdge); 00416 // Interrupt Handler: EOC Event Output from device 00417 void onEOCFallingEdge(void) 00418 { 00419 // VERIFIED: if DO NOTHING inside interrupt service routine, no crash 00420 #if 1 00421 // VERIFIED: GPIO PIN pulse in response to EOC# falling edge, no crash on HH, no missed pulses 00422 #if MAX11043_ScopeTrigger_MAX32625MBED_D5 00423 // Diagnostic: Use MAX32625MBED pin D5 as DigitalOut EOC#-detected 00424 digitalInOut5.write(0); // ScopeTrigger 1.8us after EOC# falling edge 00425 digitalInOut5.write(1); // ScopeTrigger 00426 digitalInOut5.write(0); // ScopeTrigger 00427 digitalInOut5.write(1); // ScopeTrigger 00428 #endif // MAX11043_ScopeTrigger_MAX32625MBED_D5 00429 #endif 00430 #if MAX11043_EOC_INTERRUPT_EVENTQUEUE 00431 // SPI is not interrupt-safe, so use EventQueue to defer execution to user context. 00432 myOnEOCThread_event_flags.set(MYONEOCTHREADEVENTFLAG_ENABLE_SPI); 00433 #else // MAX11043_EOC_INTERRUPT_EVENTQUEUE 00434 #endif // MAX11043_EOC_INTERRUPT_EVENTQUEUE 00435 #if 0 00436 // TODO: read 4 channels in response to EOC# falling edge 00437 // WIP MAX11043 interrupt CRASH on Menu item HH CONVRUN High 00438 // 00439 // ++ MbedOS Error Info ++ 00440 // Error Status: 0x80020115 Code: 277 Module: 2 00441 // Error Message: Mutex lock failed 00442 // Location: 0xBA33 00443 // Error Value: 0xFFFFFFFA 00444 // Current Thread: main Id: 0x20002CD0 Entry: 0xBD17 StackSize: 0x1000 StackMem: 0x20001CD0 SP: 0x20027ED0 00445 // For more info, visit: https://armmbed.github.io/mbedos-error/?error=0x80020115 00446 // -- MbedOS Error Info -- 00447 extern MAX11043 g_MAX11043_device; 00448 //~ g_MAX11043_device.Read_ADCabcd(); 00449 // read register ADCabcd -> &adca, &adcb, &adcc, &adcd 00450 // g_MAX11043_device.RegRead(CMD_0001_1010_d16o8_d16o8_d16o8_d16o8_Rd06_ADCabcd, 0); 00451 // SPI 8+64 = 72-bit transfer 00452 // 1234 5678 ___[1]_16 ___[2]_24 ___[3]_32 ___[4]_40 ___[5]_48 ___[6]_56 ___[7]_64 ___[8]_72 00453 // SPI MOSI = 1aaa_aaaa_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000 ... _0000 00454 // SPI MISO = xxxx_xxxx_dddd_dddd_dddd_dddd_dddd_dddd_dddd_dddd_dddd_dddd_dddd_dddd_dddd_dddd_dddd_dddd ... _xxxx 00455 // global const size_t byteCount_onEOCFallingEdge = 1 + (2 * 4); 00456 // global const uint8_t mosiData_onEOCFallingEdge[9] = { 00457 // global CMD_0001_1010_d16o8_d16o8_d16o8_d16o8_Rd06_ADCabcd, 00458 // global 0, 0, 0, 0, 0, 0, 0, 0 00459 // global }; 00460 // global uint8_t misoData_onEOCFallingEdge[9]; 00461 // SPIreadWriteWithLowCS(size_t byteCount, uint8_t mosiData[], uint8_t misoData[]); 00462 // SPIreadWriteWithLowCS(byteCount_onEOCFallingEdge, mosiData_onEOCFallingEdge, misoData_onEOCFallingEdge); 00463 // onSPIprint() is not interrupt-safe 00464 // unsigned int numBytesTransferred = m_spi.write((char*)mosiData, byteCount, (char*)misoData, byteCount); 00465 // g_MAX11043_device.m_spi is inaccessible 00466 extern SPI spi; // declared in Test_Main_MAX11043.cpp 00467 spi.write((char*)mosiData_onEOCFallingEdge, byteCount_onEOCFallingEdge, (char*)misoData_onEOCFallingEdge, byteCount_onEOCFallingEdge); 00468 // 00469 // ++ MbedOS Error Info ++ 00470 // Error Status: 0x80020115 Code: 277 Module: 2 00471 // Error Message: Mutex lock failed 00472 // Location: 0xBABB 00473 // Error Value: 0xFFFFFFFA 00474 // Current Thread: main Id: 0x20002CD0 Entry: 0xBD9F StackSize: 0x1000 StackMem: 0x20001CD0 SP: 0x20027F10 00475 // For more info, visit: https://armmbed.github.io/mbedos-error/?error=0x80020115 00476 // -- MbedOS Error Info -- 00477 // 00478 //if (ptrRegData) { (*ptrRegData) = (misoData[1] << 8) | misoData[2]; } 00479 //if (commandByte == CMD_0001_1010_d16o8_d16o8_d16o8_d16o8_Rd06_ADCabcd) { 00480 // TODO1: update adca 00481 //g_MAX11043_device.adca = (misoData_onEOCFallingEdge[1] << 8) | misoData_onEOCFallingEdge[2]; 00482 // TODO1: update adcb 00483 //g_MAX11043_device.adcb = (misoData_onEOCFallingEdge[3] << 8) | misoData_onEOCFallingEdge[4]; 00484 // TODO1: update adcc 00485 //g_MAX11043_device.adcc = (misoData_onEOCFallingEdge[5] << 8) | misoData_onEOCFallingEdge[6]; 00486 // TODO1: update adcd 00487 //g_MAX11043_device.adcd = (misoData_onEOCFallingEdge[7] << 8) | misoData_onEOCFallingEdge[8]; 00488 //} 00489 #endif 00490 #if 0 // MAX11043_ScopeTrigger_MAX32625MBED_D5 00491 // Diagnostic: Use MAX32625MBED pin D5 as DigitalOut EOC#-detected 00492 digitalInOut5.write(0); // ScopeTrigger 00493 digitalInOut5.write(1); // ScopeTrigger 00494 #endif // MAX11043_ScopeTrigger_MAX32625MBED_D5 00495 } 00496 #endif // MAX11043_EOC_INTERRUPT_POLLING 00497 00498 // CODE GENERATOR: class destructor definition 00499 MAX11043::~MAX11043() 00500 { 00501 // do nothing 00502 } 00503 00504 // CODE GENERATOR: spi_frequency setter definition 00505 /// set SPI SCLK frequency 00506 void MAX11043::spi_frequency(int spi_sclk_Hz) 00507 { 00508 m_SPI_SCLK_Hz = spi_sclk_Hz; 00509 m_spi.frequency(m_SPI_SCLK_Hz); 00510 } 00511 00512 // CODE GENERATOR: omit global g_MAX11043_device 00513 // CODE GENERATOR: extern function declarations 00514 // CODE GENERATOR: extern function requirement MAX11043::SPIoutputCS 00515 // Assert SPI Chip Select 00516 // SPI chip-select for MAX11043 00517 // 00518 inline void MAX11043::SPIoutputCS(int isLogicHigh) 00519 { 00520 // CODE GENERATOR: extern function definition for function SPIoutputCS 00521 // CODE GENERATOR: extern function definition for standard SPI interface function SPIoutputCS(int isLogicHigh) 00522 m_SPI_cs_state = isLogicHigh; 00523 if (m_cs_pin.is_connected()) { // avoid mbed runtime error if pin is NC not connected 00524 m_cs_pin = m_SPI_cs_state; 00525 } 00526 } 00527 00528 // CODE GENERATOR: extern function requirement MAX11043::SPIreadWriteWithLowCS 00529 // SPI read and write arbitrary number of 8-bit bytes 00530 // SPI interface to MAX11043 shift mosiData into MAX11043 DIN 00531 // while simultaneously capturing miso data from MAX11043 DOUT 00532 // 00533 int MAX11043::SPIreadWriteWithLowCS(size_t byteCount, uint8_t mosiData[], uint8_t misoData[]) 00534 { 00535 // CODE GENERATOR: extern function definition for function SPIreadWriteWithLowCS 00536 // TODO1: CODE GENERATOR: extern function definition for standard SPI interface function SPIreadWriteWithLowCS(size_t byteCount, uint8_t mosiData[], uint8_t misoData[]) 00537 //size_t byteCount = 4; 00538 //static char mosiData[4]; 00539 //static char misoData[4]; 00540 // 00541 // Arduino: begin critical section: noInterrupts() masks all interrupt sources; end critical section with interrupts() 00542 //~ noInterrupts(); 00543 // 00544 //~ digitalWrite(Scope_Trigger_Pin, LOW); // diagnostic Scope_Trigger_Pin 00545 // 00546 if (m_cs_pin.is_connected()) { // avoid mbed runtime error if pin is NC not connected 00547 m_cs_pin = 0; 00548 } 00549 unsigned int numBytesTransferred = m_spi.write((char*)mosiData, byteCount, (char*)misoData, byteCount); 00550 if (m_cs_pin.is_connected()) { // avoid mbed runtime error if pin is NC not connected 00551 m_cs_pin = m_SPI_cs_state; 00552 } 00553 // 00554 //~ digitalWrite(Scope_Trigger_Pin, HIGH); // diagnostic Scope_Trigger_Pin 00555 // 00556 // Arduino: begin critical section: noInterrupts() masks all interrupt sources; end critical section with interrupts() 00557 //~ interrupts(); 00558 // Optional Diagnostic function to print SPI transactions 00559 if (onSPIprint) 00560 { 00561 onSPIprint(byteCount, (uint8_t*)mosiData, (uint8_t*)misoData); 00562 } 00563 return numBytesTransferred; 00564 } 00565 00566 // TODO1: CODE GENERATOR: extern function GPIOoutputSHDN alias SHDNoutputValue 00567 // CODE GENERATOR: extern function requirement MAX11043::SHDNoutputValue 00568 // Assert MAX11043 SHDN pin : High = Shut Down, Low = Normal Operation. 00569 // 00570 void MAX11043::SHDNoutputValue(int isLogicHigh) 00571 { 00572 // CODE GENERATOR: extern function definition for function SHDNoutputValue 00573 // TODO1: CODE GENERATOR: extern function definition for gpio interface function SHDNoutputValue 00574 // TODO1: CODE GENERATOR: gpio pin SHDN assuming member function m_SHDN_pin 00575 // TODO1: CODE GENERATOR: gpio direction output 00576 // m_SHDN_pin.output(); // only applicable to DigitalInOut 00577 // TODO1: CODE GENERATOR: gpio function Value 00578 m_SHDN_pin = isLogicHigh; 00579 } 00580 00581 // TODO1: CODE GENERATOR: extern function GPIOoutputCONVRUN alias CONVRUNoutputValue 00582 // CODE GENERATOR: extern function requirement MAX11043::CONVRUNoutputValue 00583 // Assert MAX11043 CONVRUN pin : High = start continuous conversions on all 4 channels, Low = Idle. 00584 // 00585 void MAX11043::CONVRUNoutputValue(int isLogicHigh) 00586 { 00587 // CODE GENERATOR: extern function definition for function CONVRUNoutputValue 00588 // TODO1: CODE GENERATOR: extern function definition for gpio interface function CONVRUNoutputValue 00589 // TODO1: CODE GENERATOR: gpio pin CONVRUN assuming member function m_CONVRUN_pin 00590 // TODO1: CODE GENERATOR: gpio direction output 00591 // m_CONVRUN_pin.output(); // only applicable to DigitalInOut 00592 // TODO1: CODE GENERATOR: gpio function Value 00593 m_CONVRUN_pin = isLogicHigh; 00594 //-------------------------------------------------- 00595 // MAX11043 ADC Read operations must be synchronized to EOC End Of Conversion 00596 // EOC# asserts low when new data is available. 00597 // Initiate a data read prior to the next rising edge of EOC# or the result is overwritten. 00598 #if MAX11043_EOC_INTERRUPT_POLLING 00599 // MAX11043 EOC End Of Conversion input should be InterruptIn(PinName:EOC_pin).fall(onEOCFallingEdge); 00600 // Workaround using DigitalIn(PinName:EOC_pin) polled to sync with EOC falling edge for ADC reads 00601 if (m_CONVRUN_pin) 00602 { 00603 // CONVRUN was switched high, EOC# will now begin toggling 00604 } 00605 else 00606 { 00607 // CONVRUN was switched low, so wait until EOC# returns high 00608 #warning "MAX11043::Read_ADCabcd() Potential infinite loop if EOC pin not connected" 00609 // possible infinite loop; need a timeout or futility countdown to escape 00610 for (int futility_countdown = 100; 00611 ((futility_countdown > 0) && 00612 (m_EOC_pin != 1)); 00613 futility_countdown--) 00614 { 00615 // spinlock waiting for logic high pin state (start of new conversion) 00616 } 00617 } 00618 #else // MAX11043_EOC_INTERRUPT_POLLING 00619 // MAX11043 EOC End Of Conversion input is InterruptIn(PinName:EOC_pin).fall(onEOCFallingEdge); 00620 #endif // MAX11043_EOC_INTERRUPT_POLLING 00621 //-------------------------------------------------- 00622 } 00623 00624 // CODE GENERATOR: extern function requirement MAX11043::CONVRUNoutputGetValue 00625 // Return the state being driven onto the MAX11043 CONVRUN pin. 00626 // 00627 int MAX11043::CONVRUNoutputGetValue() 00628 { 00629 // CODE GENERATOR: extern function definition for function CONVRUNoutputGetValue 00630 // TODO1: CODE GENERATOR: extern function definition for gpio interface function CONVRUNoutputGetValue 00631 // TODO1: CODE GENERATOR: gpio pin CONVRUN assuming member function m_CONVRUN_pin 00632 // TODO1: CODE GENERATOR: gpio direction output 00633 // m_CONVRUN_pin.output(); // only applicable to DigitalInOut 00634 // TODO1: CODE GENERATOR: gpio function GetValue 00635 return m_CONVRUN_pin; 00636 } 00637 00638 // TODO1: CODE GENERATOR: extern function GPIOoutputDACSTEP alias DACSTEPoutputValue 00639 // CODE GENERATOR: extern function requirement MAX11043::DACSTEPoutputValue 00640 // Assert MAX11043 DACSTEP pin : High = Active, Low = Idle. 00641 // 00642 void MAX11043::DACSTEPoutputValue(int isLogicHigh) 00643 { 00644 // CODE GENERATOR: extern function definition for function DACSTEPoutputValue 00645 // TODO1: CODE GENERATOR: extern function definition for gpio interface function DACSTEPoutputValue 00646 // TODO1: CODE GENERATOR: gpio pin DACSTEP assuming member function m_DACSTEP_pin 00647 // TODO1: CODE GENERATOR: gpio direction output 00648 // m_DACSTEP_pin.output(); // only applicable to DigitalInOut 00649 // TODO1: CODE GENERATOR: gpio function Value 00650 m_DACSTEP_pin = isLogicHigh; 00651 } 00652 00653 // TODO1: CODE GENERATOR: extern function GPIOoutputUP_slash_DWNb alias UP_slash_DWNboutputValue 00654 // CODE GENERATOR: extern function requirement MAX11043::UP_slash_DWNboutputValue 00655 // Assert MAX11043 UP_slash_DWNb pin : High = Up, Low = Down. 00656 // 00657 void MAX11043::UP_slash_DWNboutputValue(int isLogicHigh) 00658 { 00659 // CODE GENERATOR: extern function definition for function UP_slash_DWNboutputValue 00660 // TODO1: CODE GENERATOR: extern function definition for gpio interface function UP_slash_DWNboutputValue 00661 // TODO1: CODE GENERATOR: gpio pin UP_slash_DWNb assuming member function m_UP_slash_DWNb_pin 00662 // TODO1: CODE GENERATOR: gpio direction output 00663 // m_UP_slash_DWNb_pin.output(); // only applicable to DigitalInOut 00664 // TODO1: CODE GENERATOR: gpio function Value 00665 m_UP_slash_DWNb_pin = isLogicHigh; 00666 } 00667 00668 // CODE GENERATOR: extern function requirement MAX11043::EOCinputWaitUntilLow 00669 // Wait for MAX11043 EOC pin low, indicating end of conversion. 00670 // Required when using any of the InternalClock modes. 00671 // 00672 void MAX11043::EOCinputWaitUntilLow() 00673 { 00674 // CODE GENERATOR: extern function definition for function EOCinputWaitUntilLow 00675 // TODO1: CODE GENERATOR: extern function definition for gpio interface function EOCinputWaitUntilLow 00676 // TODO1: CODE GENERATOR: gpio pin EOC assuming member function m_EOC_pin 00677 // TODO1: CODE GENERATOR: gpio direction input 00678 // m_EOC_pin.input(); // only applicable to DigitalInOut 00679 // TODO1: CODE GENERATOR: gpio function WaitUntilLow 00680 while (m_EOC_pin != 0) 00681 { 00682 // spinlock waiting for logic low pin state 00683 } 00684 } 00685 00686 // CODE GENERATOR: extern function requirement MAX11043::EOCinputValue 00687 // Return the status of the MAX11043 EOC pin. 00688 // 00689 int MAX11043::EOCinputValue() 00690 { 00691 // CODE GENERATOR: extern function definition for function EOCinputValue 00692 // TODO1: CODE GENERATOR: extern function definition for gpio interface function EOCinputValue 00693 // TODO1: CODE GENERATOR: gpio pin EOC assuming member function m_EOC_pin 00694 // TODO1: CODE GENERATOR: gpio direction input 00695 // m_EOC_pin.input(); // only applicable to DigitalInOut 00696 // TODO1: CODE GENERATOR: gpio function Value 00697 return m_EOC_pin.read(); 00698 } 00699 00700 // CODE GENERATOR: class member function definitions 00701 //---------------------------------------- 00702 // Menu item '!' 00703 // Initialize device 00704 // @return 1 on success; 0 on failure 00705 uint8_t MAX11043::Init(void) 00706 { 00707 00708 //---------------------------------------- 00709 // reference voltage, in Volts 00710 VRef = 2.500; 00711 00712 //---------------------------------------- 00713 // shadow of register config CMD_0010_0000_d16_Wr08_Configuration 00714 config = 0x6000; 00715 00716 //---------------------------------------- 00717 // shadow of register status CMD_0001_1110_d8_Rd07_Status 00718 status = 0x00; 00719 00720 //---------------------------------------- 00721 // shadow of register ADCa CMD_0000_0010_d16o8_Rd00_ADCa 00722 adca = 0x0000; 00723 00724 //---------------------------------------- 00725 // shadow of register ADCb CMD_0000_0110_d16o8_Rd01_ADCb 00726 adcb = 0x0000; 00727 00728 //---------------------------------------- 00729 // shadow of register ADCc CMD_0000_1010_d16o8_Rd02_ADCc 00730 adcc = 0x0000; 00731 00732 //---------------------------------------- 00733 // shadow of register ADCd CMD_0000_1110_d16o8_Rd03_ADCd 00734 adcd = 0x0000; 00735 00736 //---------------------------------------- 00737 // init (based on old EV kit GUI) 00738 #warning "Not Implemented Yet: MAX11043::Init init..." 00739 // bool bOpResult = false; 00740 // String FWVersionString = "00"; 00741 // bool bDemoMode = true; 00742 // int scan_resolution = 0; 00743 // int scan_channels = 0; 00744 // int scan_bits = 0; 00745 // int sampleRateFactore = 0; 00746 // double sampleRate = 0; 00747 // unsigned long banks_requested = 0; 00748 // bool bScanMode = 0; 00749 00750 //---------------------------------------- 00751 // Device ID Validation -- not used, no device ID register 00752 #warning "Not Implemented Yet: MAX11043::Init Device ID Validation..." 00753 // const uint32_t part_id_expect = 0x000F02; 00754 // uint32_t part_id_readback; 00755 // RegRead(xxxxxxxxxxxxCMD_r001_0001_xxxx_xxxx_xxxx_xxxx_xxxx_xddd_PART_ID, &part_id_readback); 00756 // if (part_id_readback != part_id_expect) return 0; 00757 00758 //---------------------------------------- 00759 // Active-High Shutdown Input. Drive high to shut down the MAX11043. 00760 SHDNoutputValue(0); // SHDN Inactive 00761 00762 //---------------------------------------- 00763 // Convert Run. Drive high to start continuous conversions on all 4 channels. The device is idle when 00764 // CONVRUN is low. 00765 CONVRUNoutputValue(0); // CONVRUN Idle 00766 00767 //---------------------------------------- 00768 // DAC Step Input. Drive high to move the DAC output in the direction of UP/DWN on the next rising 00769 // edge of the system clock. 00770 DACSTEPoutputValue(0); // DACSTEP Idle 00771 00772 //---------------------------------------- 00773 // DAC Step Direction Select. Drive high to step up, drive low to step down when DACSTEP is toggled. 00774 UP_slash_DWNboutputValue(0); // UP/DWN# Down 00775 00776 //---------------------------------------- 00777 // success 00778 return 1; 00779 } 00780 00781 //---------------------------------------- 00782 // Return the physical voltage corresponding to conversion result 00783 // (conversion format is Bipolar mode, 2's complement) 00784 // Does not perform any offset or gain correction. 00785 // 00786 // @pre CONFIG_xxxx_xxxx_xx1x_xxxx_24BIT is 0: 16-bit mode is configured 00787 // @pre VRef = Voltage of REF input, in Volts 00788 // @param[in] value_u24: raw 24-bit MAX11043 code (right justified). 00789 // @return physical voltage corresponding to MAX11043 code. 00790 // @test group BIP2C16 ADCVoltageOfCode_16bit(0x7FFF) expect 2.500 within 0.030 Full Scale 00791 // @test group BIP2C16 ADCVoltageOfCode_16bit(0x7FFF) expect 2.500 Full Scale 00792 // @test group BIP2C16 ADCVoltageOfCode_16bit(0x6666) expect 2.000 Two Volts 00793 // @test group BIP2C16 ADCVoltageOfCode_16bit(0x6000) expect 1.875 75% Scale 00794 // @test group BIP2C16 ADCVoltageOfCode_16bit(0x4000) expect 1.250 Mid Scale 00795 // @test group BIP2C16 ADCVoltageOfCode_16bit(0x3333) expect 1.000 One Volt 00796 // @test group BIP2C16 ADCVoltageOfCode_16bit(0x2000) expect 0.625 25% Scale 00797 // @test group BIP2C16 ADCVoltageOfCode_16bit(0x051e) expect 0.100 100mV 00798 // @test group BIP2C16 ADCVoltageOfCode_16bit(0x0000) expect 0.00000894069671 Three LSB 00799 // @test group BIP2C16 ADCVoltageOfCode_16bit(0x0000) expect 0.00000596046447 Two LSB 00800 // @test group BIP2C16 ADCVoltageOfCode_16bit(0x0000) expect 0.0000029802326 One LSB 00801 // @test group BIP2C16 ADCVoltageOfCode_16bit(0x0000) expect 0.0 Zero Scale 00802 // @test group BIP2C16 ADCVoltageOfCode_16bit(0xFFFF) expect -0.0000029802326 Negative One LSB 00803 // @test group BIP2C16 ADCVoltageOfCode_16bit(0xFFFF) expect -0.0000059604644 Negative Two LSB 00804 // @test group BIP2C16 ADCVoltageOfCode_16bit(0xFFFF) expect -0.0000089406967 Negative Three LSB 00805 // @test group BIP2C16 ADCVoltageOfCode_16bit(0xFAE1) expect -0.100 Negative 100mV 00806 // @test group BIP2C16 ADCVoltageOfCode_16bit(0xE000) expect -0.625 Negative 25% Scale 00807 // @test group BIP2C16 ADCVoltageOfCode_16bit(0xCCCC) expect -1.000 Negative One Volt 00808 // @test group BIP2C16 ADCVoltageOfCode_16bit(0xC000) expect -1.250 Negative Mid Scale 00809 // @test group BIP2C16 ADCVoltageOfCode_16bit(0xA000) expect -1.875 Negative 75% Scale 00810 // @test group BIP2C16 ADCVoltageOfCode_16bit(0x9999) expect -2.000 Negative Two Volts 00811 // @test group BIP2C16 ADCVoltageOfCode_16bit(0x8000) expect -2.500 Negative Full Scale 00812 // @test group BIP2C16 ADCVoltageOfCode_16bit(0x8000) expect -2.500 Negative Full Scale 00813 // 00814 double MAX11043::ADCVoltageOfCode_16bit(uint32_t value_u16) 00815 { 00816 00817 //---------------------------------------- 00818 // Linear map min and max endpoints 00819 double MaxScaleVoltage = 2 * VRef; // voltage of maximum code 0x7fff 00820 double MinScaleVoltage = 0; // voltage of minimum code 0x8000 00821 const int32_t FULL_SCALE_CODE_16BIT_2S_COMPLEMENT = 0x7fff; 00822 const int32_t SIGN_BIT_16BIT_2S_COMPLEMENT = 0x8000; 00823 if (value_u16 >= SIGN_BIT_16BIT_2S_COMPLEMENT) { value_u16 = value_u16 - (2 * SIGN_BIT_16BIT_2S_COMPLEMENT); } 00824 const int32_t MaxCode = FULL_SCALE_CODE_16BIT_2S_COMPLEMENT; 00825 const int32_t CodeSpan = 0x10000; 00826 const int32_t MinCode = 0; 00827 double codeFraction = ((double)((int32_t)value_u16) - MinCode) / CodeSpan; 00828 return (MinScaleVoltage + ((MaxScaleVoltage - MinScaleVoltage) * codeFraction)); // / pgaGain; 00829 } 00830 00831 //---------------------------------------- 00832 // Return the physical voltage corresponding to conversion result 00833 // (conversion format is Bipolar mode, 2's complement) 00834 // Does not perform any offset or gain correction. 00835 // 00836 // @pre CONFIG_xxxx_xxxx_xx1x_xxxx_24BIT is 1: 24-bit mode is configured 00837 // @pre VRef = Voltage of REF input, in Volts 00838 // @param[in] value_u24: raw 24-bit MAX11043 code (right justified). 00839 // @return physical voltage corresponding to MAX11043 code. 00840 // @test group BIP2C24 ADCVoltageOfCode_24bit(0x7FFFFF) expect 2.500 within 0.030 Full Scale 00841 // @test group BIP2C24 ADCVoltageOfCode_24bit(0x7FFFFE) expect 2.500 Full Scale 00842 // @test group BIP2C24 ADCVoltageOfCode_24bit(0x666666) expect 2.000 Two Volts 00843 // @test group BIP2C24 ADCVoltageOfCode_24bit(0x600000) expect 1.875 75% Scale 00844 // @test group BIP2C24 ADCVoltageOfCode_24bit(0x400000) expect 1.250 Mid Scale 00845 // @test group BIP2C24 ADCVoltageOfCode_24bit(0x333333) expect 1.000 One Volt 00846 // @test group BIP2C24 ADCVoltageOfCode_24bit(0x200000) expect 0.625 25% Scale 00847 // @test group BIP2C24 ADCVoltageOfCode_24bit(0x051eb8) expect 0.100 100mV 00848 // @test group BIP2C24 ADCVoltageOfCode_24bit(0x000003) expect 0.00000894069671 Three LSB 00849 // @test group BIP2C24 ADCVoltageOfCode_24bit(0x000002) expect 0.00000596046447 Two LSB 00850 // @test group BIP2C24 ADCVoltageOfCode_24bit(0x000001) expect 0.0000029802326 One LSB 00851 // @test group BIP2C24 ADCVoltageOfCode_24bit(0x000000) expect 0.0 Zero Scale 00852 // @test group BIP2C24 ADCVoltageOfCode_24bit(0xFFFFFF) expect -0.0000029802326 Negative One LSB 00853 // @test group BIP2C24 ADCVoltageOfCode_24bit(0xFFFFFE) expect -0.0000059604644 Negative Two LSB 00854 // @test group BIP2C24 ADCVoltageOfCode_24bit(0xFFFFFD) expect -0.0000089406967 Negative Three LSB 00855 // @test group BIP2C24 ADCVoltageOfCode_24bit(0xFAE148) expect -0.100 Negative 100mV 00856 // @test group BIP2C24 ADCVoltageOfCode_24bit(0xE00000) expect -0.625 Negative 25% Scale 00857 // @test group BIP2C24 ADCVoltageOfCode_24bit(0xCCCCCD) expect -1.000 Negative One Volt 00858 // @test group BIP2C24 ADCVoltageOfCode_24bit(0xC00000) expect -1.250 Negative Mid Scale 00859 // @test group BIP2C24 ADCVoltageOfCode_24bit(0xA00000) expect -1.875 Negative 75% Scale 00860 // @test group BIP2C24 ADCVoltageOfCode_24bit(0x99999A) expect -2.000 Negative Two Volts 00861 // @test group BIP2C24 ADCVoltageOfCode_24bit(0x800001) expect -2.500 Negative Full Scale 00862 // @test group BIP2C24 ADCVoltageOfCode_24bit(0x800000) expect -2.500 Negative Full Scale 00863 // 00864 double MAX11043::ADCVoltageOfCode_24bit(uint32_t value_u24) 00865 { 00866 00867 //---------------------------------------- 00868 // Linear map min and max endpoints 00869 double MaxScaleVoltage = 2 * VRef; // voltage of maximum code 0x7fffff 00870 double MinScaleVoltage = 0; // voltage of minimum code 0x800000 00871 const int32_t FULL_SCALE_CODE_24BIT_2S_COMPLEMENT = 0x7fffff; 00872 const int32_t SIGN_BIT_24BIT_2S_COMPLEMENT = 0x800000; 00873 if (value_u24 >= SIGN_BIT_24BIT_2S_COMPLEMENT) { value_u24 = value_u24 - (2 * SIGN_BIT_24BIT_2S_COMPLEMENT); } 00874 const int32_t MaxCode = FULL_SCALE_CODE_24BIT_2S_COMPLEMENT; 00875 const int32_t CodeSpan = 0x1000000; 00876 const int32_t MinCode = 0; 00877 double codeFraction = ((double)((int32_t)value_u24) - MinCode) / CodeSpan; 00878 return (MinScaleVoltage + ((MaxScaleVoltage - MinScaleVoltage) * codeFraction)); // / pgaGain; 00879 } 00880 00881 //---------------------------------------- 00882 // Write a MAX11043 register. 00883 // 00884 // CMDOP_1aaa_aaaa_ReadRegister bit is cleared 0 indicating a write operation. 00885 // 00886 // MAX11043 register length can be determined by function RegSize. 00887 // 00888 // For 8-bit register size: 00889 // 00890 // SPI 16-bit transfer 00891 // 00892 // SPI MOSI = 0aaa_aaaa_dddd_dddd 00893 // 00894 // SPI MISO = xxxx_xxxx_xxxx_xxxx 00895 // 00896 // For 16-bit register size: 00897 // 00898 // SPI 24-bit or 32-bit transfer 00899 // 00900 // SPI MOSI = 0aaa_aaaa_dddd_dddd_dddd_dddd 00901 // 00902 // SPI MISO = xxxx_xxxx_xxxx_xxxx_xxxx_xxxx 00903 // 00904 // For 24-bit register size: 00905 // 00906 // SPI 32-bit transfer 00907 // 00908 // SPI MOSI = 0aaa_aaaa_dddd_dddd_dddd_dddd_dddd_dddd 00909 // 00910 // SPI MISO = xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx 00911 // 00912 // @return 1 on success; 0 on failure 00913 uint8_t MAX11043::RegWrite(MAX11043_CMD_enum_t commandByte, uint32_t regData) 00914 { 00915 00916 //---------------------------------------- 00917 // switch based on register address szie RegSize(commandByte) 00918 //commandByte = (MAX11043_CMD_enum_t)((commandByte &~ CMDOP_0aaa_aa10_ReadRegister) & 0xFF); 00919 switch(RegSize(commandByte)) 00920 { 00921 case 8: // 8-bit register size 00922 { 00923 // SPI 8+8 = 16-bit transfer 00924 // 1234 5678 ___[1]_16 00925 // SPI MOSI = 0aaa_aaaa_dddd_dddd ... _0000 00926 // SPI MISO = xxxx_xxxx_xxxx_xxxx ... _xxxx 00927 size_t byteCount = 1 + 1; 00928 uint8_t mosiData[2]; 00929 uint8_t misoData[2]; 00930 mosiData[0] = commandByte; 00931 mosiData[1] = regData; 00932 // SPIreadWriteWithLowCS(size_t byteCount, uint8_t mosiData[], uint8_t misoData[]); 00933 SPIreadWriteWithLowCS(byteCount, mosiData, misoData); 00934 // TODO: cache CMD_0101_0100_d8_Wr15_FilterCAddress 00935 // if (commandByte == CMD_0101_0100_d8_Wr15_FilterCAddress) { 00936 // FilterCAddress = regData; 00937 // } 00938 // TODO: cache CMD_0110_0000_d8_Wr18_FlashMode 00939 // if (commandByte == CMD_0110_0000_d8_Wr18_FlashMode) { 00940 // FlashMode = regData; 00941 // } 00942 } 00943 break; 00944 case 16: // 16-bit register size 00945 #warning "Not Verified Yet: MAX11043::RegWrite 16-bit" 00946 { 00947 // SPI 8+16 = 24-bit transfer 00948 // 1234 5678 ___[1]_16 ___[2]_24 00949 // SPI MOSI = 0aaa_aaaa_dddd_dddd_dddd_dddd ... _0000 00950 // SPI MISO = xxxx_xxxx_xxxx_xxxx_xxxx_xxxx ... _xxxx 00951 size_t byteCount = 1 + 2; 00952 uint8_t mosiData[3]; 00953 uint8_t misoData[3]; 00954 mosiData[0] = commandByte; 00955 mosiData[1] = (uint8_t)((regData >> 8) & 0xFF); 00956 mosiData[2] = (uint8_t)((regData >> 0) & 0xFF); 00957 // SPIreadWriteWithLowCS(size_t byteCount, uint8_t mosiData[], uint8_t misoData[]); 00958 SPIreadWriteWithLowCS(byteCount, mosiData, misoData); 00959 // cache CMD_0010_0000_d16_Wr08_Configuration 00960 if (commandByte == CMD_0010_0000_d16_Wr08_Configuration) { 00961 config = regData; 00962 } 00963 // TODO: cache CMD_0010_0100_d16_Wr09_DAC 00964 // TODO: cache CMD_0010_1000_d16_Wr0A_DACStep 00965 // TODO: cache CMD_0010_1100_d16_Wr0B_DACHDACL 00966 // TODO: cache CMD_0011_0000_d16_Wr0C_ConfigA 00967 // TODO: cache CMD_0011_0100_d16_Wr0D_ConfigB 00968 // TODO: cache CMD_0011_1000_d16_Wr0E_ConfigC 00969 // TODO: cache CMD_0011_1100_d16_Wr0F_ConfigD 00970 // TODO: cache CMD_0100_0000_d16_Wr10_Reference 00971 // TODO: cache CMD_0100_0100_d16_Wr11_AGain 00972 // TODO: cache CMD_0100_1000_d16_Wr12_BGain 00973 // TODO: cache CMD_0100_1100_d16_Wr13_CGain 00974 // TODO: cache CMD_0101_0000_d16_Wr14_DGain 00975 // TODO: cache CMD_0110_0100_d16_Wr19_FlashAddr 00976 // TODO: cache CMD_0110_1000_d16_Wr1A_FlashDataIn 00977 } 00978 break; 00979 case 32: // 32-bit register size 00980 #warning "Not Verified Yet: MAX11043::RegWrite 32-bit" 00981 { 00982 // SPI 8+32 = 40-bit transfer 00983 // 1234 5678 ___[1]_16 ___[2]_24 ___[3]_32 ___[4]_40 00984 // SPI MOSI = 1aaa_aaaa_dddd_dddd_dddd_dddd_dddd_dddd_dddd_dddd ... _0000 00985 // SPI MISO = xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx ... _xxxx 00986 // 00987 size_t byteCount = 1 + (2 * 2); 00988 uint8_t mosiData[5]; 00989 uint8_t misoData[5]; 00990 mosiData[0] = commandByte; 00991 mosiData[1] = (uint8_t)((regData >> 24) & 0xFF); 00992 mosiData[2] = (uint8_t)((regData >> 16) & 0xFF); 00993 mosiData[3] = (uint8_t)((regData >> 8) & 0xFF); 00994 mosiData[4] = (uint8_t)((regData >> 0) & 0xFF); 00995 // SPIreadWriteWithLowCS(size_t byteCount, uint8_t mosiData[], uint8_t misoData[]); 00996 SPIreadWriteWithLowCS(byteCount, mosiData, misoData); 00997 // TODO: cache CMD_0101_1000_d32_Wr16_FilterCDataOut 00998 // if (commandByte == CMD_0101_1000_d32_Wr16_FilterCDataOut) { 00999 // FilterCDataOut = regData; 01000 // } 01001 // TODO: cache CMD_0101_1100_d32_Wr17_FilterCDataIn 01002 // if (commandByte == CMD_0101_1000_d32_Wr16_FilterCDataOut) { 01003 // FilterCDataOut = regData; 01004 // } 01005 } 01006 break; 01007 } 01008 01009 //---------------------------------------- 01010 // success 01011 return 1; 01012 } 01013 01014 //---------------------------------------- 01015 // Read an 8-bit MAX11043 register 01016 // 01017 // CMDOP_1aaa_aaaa_ReadRegister bit is set 1 indicating a read operation. 01018 // 01019 // MAX11043 register length can be determined by function RegSize. 01020 // 01021 // For 8-bit register size: 01022 // 01023 // SPI 16-bit transfer 01024 // 01025 // SPI MOSI = 1aaa_aaaa_0000_0000 01026 // 01027 // SPI MISO = xxxx_xxxx_dddd_dddd 01028 // 01029 // For 16-bit register size: 01030 // 01031 // SPI 24-bit or 32-bit transfer 01032 // 01033 // SPI MOSI = 1aaa_aaaa_0000_0000_0000_0000 01034 // 01035 // SPI MISO = xxxx_xxxx_dddd_dddd_dddd_dddd 01036 // 01037 // For 24-bit register size: 01038 // 01039 // SPI 32-bit transfer 01040 // 01041 // SPI MOSI = 1aaa_aaaa_0000_0000_0000_0000_0000_0000 01042 // 01043 // SPI MISO = xxxx_xxxx_dddd_dddd_dddd_dddd_dddd_dddd 01044 // 01045 // 01046 // @return 1 on success; 0 on failure 01047 uint8_t MAX11043::RegRead(MAX11043_CMD_enum_t commandByte, uint32_t* ptrRegData) 01048 { 01049 01050 //---------------------------------------- 01051 // switch based on register address szie RegSize(regAddress) 01052 #define SIGN_EXTEND_INT16_VALUE(x) (((x)&(0x8000))?((x)-65536):(x)) 01053 //commandByte = (MAX11043_CMD_enum_t)((commandByte &~ CMDOP_0aaa_aa10_ReadRegister) & 0xFF); 01054 switch(RegSize(commandByte)) 01055 { 01056 case 8: // 8-bit register size 01057 { 01058 // SPI 8+8 = 16-bit transfer 01059 // 1234 5678 ___[1]_16 01060 // SPI MOSI = 1aaa_aaaa_0000_0000 ... _0000 01061 // SPI MISO = xxxx_xxxx_dddd_dddd ... _xxxx 01062 size_t byteCount = 1 + 1; 01063 uint8_t mosiData[2]; 01064 uint8_t misoData[2]; 01065 mosiData[0] = CMDOP_0aaa_aa10_ReadRegister | commandByte; 01066 mosiData[1] = 0; // CMDOP_1111_1111_NoOperationMOSIidleHigh; 01067 // SPIreadWriteWithLowCS(size_t byteCount, uint8_t mosiData[], uint8_t misoData[]); 01068 SPIreadWriteWithLowCS(byteCount, mosiData, misoData); 01069 if (ptrRegData) { (*ptrRegData) = misoData[1]; } 01070 if (commandByte == CMD_0001_1110_d8_Rd07_Status) { 01071 // TODO1: update status 01072 status = misoData[1]; 01073 } 01074 } 01075 break; 01076 case 16: // 16-bit register size 01077 #warning "Not Verified Yet: MAX11043::RegRead 16-bit" 01078 { 01079 // SPI 8+16 = 24-bit transfer 01080 // 1234 5678 ___[1]_16 ___[2]_24 01081 // SPI MOSI = 1aaa_aaaa_0000_0000_0000_0000 ... _0000 01082 // SPI MISO = xxxx_xxxx_dddd_dddd_dddd_dddd ... _xxxx 01083 size_t byteCount = 1 + 2; 01084 uint8_t mosiData[3]; 01085 uint8_t misoData[3]; 01086 mosiData[0] = CMDOP_0aaa_aa10_ReadRegister | commandByte; 01087 mosiData[1] = 0; // CMDOP_1111_1111_NoOperationMOSIidleHigh; 01088 mosiData[2] = 0; // CMDOP_1111_1111_NoOperationMOSIidleHigh; 01089 // SPIreadWriteWithLowCS(size_t byteCount, uint8_t mosiData[], uint8_t misoData[]); 01090 SPIreadWriteWithLowCS(byteCount, mosiData, misoData); 01091 if (ptrRegData) { (*ptrRegData) = (misoData[1] << 8) | misoData[2]; } 01092 if (commandByte == CMD_0010_0010_d16_Rd08_Configuration) { 01093 // TODO1: update config 01094 config = (misoData[1] << 8) | misoData[2]; 01095 } 01096 if (commandByte == CMD_0000_0010_d16o8_Rd00_ADCa) { 01097 // TODO1: update adca 01098 // adca = (misoData[1] << 8) | misoData[2]; 01099 // TODO1: update adca as 2's complement 01100 // int raw_code = (misoData[1] << 8) | misoData[2]; 01101 // if (raw_code & 0x8000) { adca = raw_code - 65536; } else { adca = raw_code; } 01102 adca = SIGN_EXTEND_INT16_VALUE((int)(misoData[1] << 8) | misoData[2]); 01103 } 01104 if (commandByte == CMD_0000_0110_d16o8_Rd01_ADCb) { 01105 // TODO1: update adcb 01106 // adcb = (misoData[1] << 8) | misoData[2]; 01107 // TODO1: update adca as 2's complement 01108 // int raw_code = (misoData[1] << 8) | misoData[2]; 01109 // if (raw_code & 0x8000) { adca = raw_code - 65536; } else { adca = raw_code; } 01110 adcb = SIGN_EXTEND_INT16_VALUE((int)(misoData[1] << 8) | misoData[2]); 01111 } 01112 if (commandByte == CMD_0000_1010_d16o8_Rd02_ADCc) { 01113 // TODO1: update adcc 01114 // adcc = (misoData[1] << 8) | misoData[2]; 01115 // TODO1: update adca as 2's complement 01116 // int raw_code = (misoData[1] << 8) | misoData[2]; 01117 // if (raw_code & 0x8000) { adca = raw_code - 65536; } else { adca = raw_code; } 01118 adcc = SIGN_EXTEND_INT16_VALUE((int)(misoData[1] << 8) | misoData[2]); 01119 } 01120 if (commandByte == CMD_0000_1110_d16o8_Rd03_ADCd) { 01121 // TODO1: update adcd 01122 // adcd = (misoData[1] << 8) | misoData[2]; 01123 // TODO1: update adca as 2's complement 01124 // int raw_code = (misoData[1] << 8) | misoData[2]; 01125 // if (raw_code & 0x8000) { adca = raw_code - 65536; } else { adca = raw_code; } 01126 adcd = SIGN_EXTEND_INT16_VALUE((int)(misoData[1] << 8) | misoData[2]); 01127 } 01128 } 01129 break; 01130 case 24: // 24-bit register size 01131 { 01132 // SPI 8+24 = 32-bit transfer 01133 // 1234 5678 ___[1]_16 ___[2]_24 ___[3]_32 01134 // SPI MOSI = 1aaa_aaaa_0000_0000_0000_0000_0000_0000 ... _0000 01135 // SPI MISO = xxxx_xxxx_dddd_dddd_dddd_dddd_dddd_dddd ... _xxxx 01136 size_t byteCount = 1 + 3; 01137 uint8_t mosiData[4]; 01138 uint8_t misoData[4]; 01139 mosiData[0] = CMDOP_0aaa_aa10_ReadRegister | commandByte; 01140 mosiData[1] = 0; // CMDOP_1111_1111_NoOperationMOSIidleHigh; 01141 mosiData[2] = 0; // CMDOP_1111_1111_NoOperationMOSIidleHigh; 01142 mosiData[3] = 0; // CMDOP_1111_1111_NoOperationMOSIidleHigh; 01143 // SPIreadWriteWithLowCS(size_t byteCount, uint8_t mosiData[], uint8_t misoData[]); 01144 SPIreadWriteWithLowCS(byteCount, mosiData, misoData); 01145 if (ptrRegData) { (*ptrRegData) = (misoData[1] << 16) | (misoData[2] << 8) | misoData[3]; } 01146 if (commandByte == CMD_0000_0010_d16o8_Rd00_ADCa) { 01147 // TODO1: update adca 01148 adca = (misoData[1] << 16) | (misoData[2] << 8) | misoData[3]; 01149 } 01150 if (commandByte == CMD_0000_0110_d16o8_Rd01_ADCb) { 01151 // TODO1: update adcb 01152 adcb = (misoData[1] << 16) | (misoData[2] << 8) | misoData[3]; 01153 } 01154 if (commandByte == CMD_0000_1010_d16o8_Rd02_ADCc) { 01155 // TODO1: update adcc 01156 adcc = (misoData[1] << 16) | (misoData[2] << 8) | misoData[3]; 01157 } 01158 if (commandByte == CMD_0000_1110_d16o8_Rd03_ADCd) { 01159 // TODO1: update adcd 01160 adcd = (misoData[1] << 16) | (misoData[2] << 8) | misoData[3]; 01161 } 01162 } 01163 break; 01164 case 32: // 32-bit register size CMD_0001_0010_d16o8_d16o8_Rd04_ADCab, CMD_0001_0110_d16o8_d16o8_Rd05_ADCcd 01165 // 01166 #warning "Not Implemented Yet: MAX11043::RegRead 32-bit CMD_0001_0010_d16o8_d16o8_Rd04_ADCab" 01167 // TODO: support long SPI read CMD_0001_0010_d16o8_d16o8_Rd04_ADCab 01168 // %SW 0x12 (0 0) (0 0) -- for 16-bit read A,B 01169 // update adca, adcb 01170 // 01171 // TODO: support long SPI read CMD_0001_0110_d16o8_d16o8_Rd05_ADCcd 01172 // %SW 0x16 (0 0) (0 0) -- for 16-bit read C,D 01173 // update adcc, adcd 01174 // 01175 { 01176 // SPI 8+32 = 40-bit transfer 01177 // 1234 5678 ___[1]_16 ___[2]_24 ___[3]_32 ___[4]_40 01178 // SPI MOSI = 1aaa_aaaa_0000_0000_0000_0000_0000_0000_0000_0000 ... _0000 01179 // SPI MISO = xxxx_xxxx_dddd_dddd_dddd_dddd_dddd_dddd_dddd_dddd ... _xxxx 01180 size_t byteCount = 1 + (2 * 2); 01181 uint8_t mosiData[5]; 01182 uint8_t misoData[5]; 01183 mosiData[0] = CMDOP_0aaa_aa10_ReadRegister | commandByte; 01184 mosiData[1] = 0; // CMDOP_1111_1111_NoOperationMOSIidleHigh; 01185 mosiData[2] = 0; // CMDOP_1111_1111_NoOperationMOSIidleHigh; 01186 mosiData[3] = 0; // CMDOP_1111_1111_NoOperationMOSIidleHigh; 01187 mosiData[4] = 0; // CMDOP_1111_1111_NoOperationMOSIidleHigh; 01188 // SPIreadWriteWithLowCS(size_t byteCount, uint8_t mosiData[], uint8_t misoData[]); 01189 SPIreadWriteWithLowCS(byteCount, mosiData, misoData); 01190 if (ptrRegData) { (*ptrRegData) = (misoData[1] << 8) | misoData[2]; } 01191 if (commandByte == CMD_0001_0010_d16o8_d16o8_Rd04_ADCab) { 01192 // TODO1: update adca 01193 // adca = (misoData[1] << 8) | misoData[2]; 01194 // TODO1: update adca as 2's complement 01195 // int raw_code = (misoData[1] << 8) | misoData[2]; 01196 // if (raw_code & 0x8000) { adca = raw_code - 65536; } else { adca = raw_code; } 01197 adca = SIGN_EXTEND_INT16_VALUE((int)(misoData[1] << 8) | misoData[2]); 01198 // TODO1: update adcb 01199 // adcb = (misoData[3] << 8) | misoData[4]; 01200 // TODO1: update adca as 2's complement 01201 // int raw_code = (misoData[1] << 8) | misoData[2]; 01202 // if (raw_code & 0x8000) { adca = raw_code - 65536; } else { adca = raw_code; } 01203 adcb = SIGN_EXTEND_INT16_VALUE((int)(misoData[3] << 8) | misoData[4]); 01204 } 01205 if (commandByte == CMD_0001_0110_d16o8_d16o8_Rd05_ADCcd) { 01206 // TODO1: update adcc 01207 adcc = (misoData[1] << 8) | misoData[2]; 01208 // TODO1: update adca as 2's complement 01209 // int raw_code = (misoData[1] << 8) | misoData[2]; 01210 // if (raw_code & 0x8000) { adca = raw_code - 65536; } else { adca = raw_code; } 01211 adcc = SIGN_EXTEND_INT16_VALUE((int)(misoData[1] << 8) | misoData[2]); 01212 // TODO1: update adcd 01213 // adcd = (misoData[3] << 8) | misoData[4]; 01214 // TODO1: update adca as 2's complement 01215 // int raw_code = (misoData[1] << 8) | misoData[2]; 01216 // if (raw_code & 0x8000) { adca = raw_code - 65536; } else { adca = raw_code; } 01217 adcd = SIGN_EXTEND_INT16_VALUE((int)(misoData[3] << 8) | misoData[4]); 01218 } 01219 } 01220 break; 01221 case 48: // 48-bit register size CMD_0001_0010_d16o8_d16o8_Rd04_ADCab, CMD_0001_0110_d16o8_d16o8_Rd05_ADCcd 01222 // 01223 #warning "Not Verified Yet: MAX11043::RegRead 48-bit CMD_0001_0010_d16o8_d16o8_Rd04_ADCab" 01224 // TODO: support long SPI read CMD_0001_0010_d16o8_d16o8_Rd04_ADCab 01225 // %SW 0x12 (0 0 0) (0 0 0) -- for 24-bit read A,B 01226 // update adca, adcb 01227 // 01228 // TODO: support long SPI read CMD_0001_0110_d16o8_d16o8_Rd05_ADCcd 01229 // %SW 0x16 (0 0 0) (0 0 0) -- for 24-bit read C,D 01230 // update adcc, adcd 01231 // 01232 { 01233 // SPI 8+48 = 56-bit transfer 01234 // 1234 5678 ___[1]_16 ___[2]_24 ___[3]_32 ___[4]_40 ___[5]_48 ___[6]_56 01235 // SPI MOSI = 1aaa_aaaa_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000 ... _0000 01236 // SPI MISO = xxxx_xxxx_dddd_dddd_dddd_dddd_dddd_dddd_dddd_dddd_dddd_dddd_dddd_dddd ... _xxxx 01237 size_t byteCount = 1 + (3 * 2); 01238 uint8_t mosiData[7]; 01239 uint8_t misoData[7]; 01240 mosiData[0] = CMDOP_0aaa_aa10_ReadRegister | commandByte; 01241 mosiData[1] = 0; // CMDOP_1111_1111_NoOperationMOSIidleHigh; 01242 mosiData[2] = 0; // CMDOP_1111_1111_NoOperationMOSIidleHigh; 01243 mosiData[3] = 0; // CMDOP_1111_1111_NoOperationMOSIidleHigh; 01244 mosiData[4] = 0; // CMDOP_1111_1111_NoOperationMOSIidleHigh; 01245 mosiData[5] = 0; // CMDOP_1111_1111_NoOperationMOSIidleHigh; 01246 mosiData[6] = 0; // CMDOP_1111_1111_NoOperationMOSIidleHigh; 01247 // SPIreadWriteWithLowCS(size_t byteCount, uint8_t mosiData[], uint8_t misoData[]); 01248 SPIreadWriteWithLowCS(byteCount, mosiData, misoData); 01249 if (ptrRegData) { (*ptrRegData) = (misoData[1] << 16) | (misoData[2] << 8) | misoData[3]; } 01250 if (commandByte == CMD_0001_0010_d16o8_d16o8_Rd04_ADCab) { 01251 // TODO1: update adca 01252 adca = (misoData[1] << 16) | (misoData[2] << 8) | misoData[3]; 01253 // TODO1: update adcb 01254 adcb = (misoData[4] << 16) | (misoData[5] << 8) | misoData[6]; 01255 } 01256 if (commandByte == CMD_0001_0110_d16o8_d16o8_Rd05_ADCcd) { 01257 // TODO1: update adcc 01258 adcc = (misoData[1] << 16) | (misoData[2] << 8) | misoData[3]; 01259 // TODO1: update adcd 01260 adcd = (misoData[4] << 16) | (misoData[5] << 8) | misoData[6]; 01261 } 01262 } 01263 break; 01264 case 64: // 64-bit register size CMD_0001_1010_d16o8_d16o8_d16o8_d16o8_Rd06_ADCabcd 01265 // 01266 #warning "Not Verified Yet: MAX11043::RegRead 64-bit CMD_0001_1010_d16o8_d16o8_d16o8_d16o8_Rd06_ADCabcd" 01267 // TODO: support long SPI read CMD_0001_1010_d16o8_d16o8_d16o8_d16o8_Rd06_ADCabcd 01268 // %SW 0x1A (0 0) (0 0) (0 0) (0 0) -- for 16-bit read A,B,C,D 01269 // update adca, adcb, adcc, adcd 01270 // 01271 { 01272 // SPI 8+64 = 72-bit transfer 01273 // 1234 5678 ___[1]_16 ___[2]_24 ___[3]_32 ___[4]_40 ___[5]_48 ___[6]_56 ___[7]_64 ___[8]_72 01274 // SPI MOSI = 1aaa_aaaa_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000 ... _0000 01275 // SPI MISO = xxxx_xxxx_dddd_dddd_dddd_dddd_dddd_dddd_dddd_dddd_dddd_dddd_dddd_dddd_dddd_dddd_dddd_dddd ... _xxxx 01276 size_t byteCount = 1 + (2 * 4); 01277 uint8_t mosiData[9]; 01278 uint8_t misoData[9]; 01279 mosiData[0] = CMDOP_0aaa_aa10_ReadRegister | commandByte; 01280 mosiData[1] = 0; // CMDOP_1111_1111_NoOperationMOSIidleHigh; 01281 mosiData[2] = 0; // CMDOP_1111_1111_NoOperationMOSIidleHigh; 01282 mosiData[3] = 0; // CMDOP_1111_1111_NoOperationMOSIidleHigh; 01283 mosiData[4] = 0; // CMDOP_1111_1111_NoOperationMOSIidleHigh; 01284 mosiData[5] = 0; // CMDOP_1111_1111_NoOperationMOSIidleHigh; 01285 mosiData[6] = 0; // CMDOP_1111_1111_NoOperationMOSIidleHigh; 01286 mosiData[7] = 0; // CMDOP_1111_1111_NoOperationMOSIidleHigh; 01287 mosiData[8] = 0; // CMDOP_1111_1111_NoOperationMOSIidleHigh; 01288 // SPIreadWriteWithLowCS(size_t byteCount, uint8_t mosiData[], uint8_t misoData[]); 01289 SPIreadWriteWithLowCS(byteCount, mosiData, misoData); 01290 if (ptrRegData) { (*ptrRegData) = (misoData[1] << 8) | misoData[2]; } 01291 if (commandByte == CMD_0001_1010_d16o8_d16o8_d16o8_d16o8_Rd06_ADCabcd) { 01292 // TODO1: update adca 01293 // adca = (misoData[1] << 8) | misoData[2]; 01294 // TODO1: update adca as 2's complement 01295 // int raw_code = (misoData[1] << 8) | misoData[2]; 01296 // if (raw_code & 0x8000) { adca = raw_code - 65536; } else { adca = raw_code; } 01297 adca = SIGN_EXTEND_INT16_VALUE((int)(misoData[1] << 8) | misoData[2]); 01298 // 01299 // TODO1: update adcb 01300 // adcb = (misoData[3] << 8) | misoData[4]; 01301 // TODO1: update adcb as 2's complement 01302 // raw_code = (misoData[3] << 8) | misoData[4]; 01303 // if (raw_code & 0x8000) { adcb = raw_code - 65536; } else { adcb = raw_code; } 01304 adcb = SIGN_EXTEND_INT16_VALUE((int)(misoData[3] << 8) | misoData[4]); 01305 // 01306 // TODO1: update adcc 01307 // adcc = (misoData[5] << 8) | misoData[6]; 01308 // TODO1: update adcc as 2's complement 01309 // raw_code = (misoData[5] << 8) | misoData[6]; 01310 // if (raw_code & 0x8000) { adcc = raw_code - 65536; } else { adcc = raw_code; } 01311 adcc = SIGN_EXTEND_INT16_VALUE((int)(misoData[5] << 8) | misoData[6]); 01312 // 01313 // TODO1: update adcd 01314 // adcd = (misoData[7] << 8) | misoData[8]; 01315 // TODO1: update adcd as 2's complement 01316 // raw_code = (misoData[7] << 8) | misoData[8]; 01317 // if (raw_code & 0x8000) { adcd = raw_code - 65536; } else { adcd = raw_code; } 01318 adcd = SIGN_EXTEND_INT16_VALUE((int)(misoData[7] << 8) | misoData[8]); 01319 // 01320 } 01321 } 01322 break; 01323 case 96: // 96-bit register size CMD_0001_1010_d16o8_d16o8_d16o8_d16o8_Rd06_ADCabcd 01324 // 01325 #warning "Not Verified Yet: MAX11043::RegRead 96-bit CMD_0001_1010_d16o8_d16o8_d16o8_d16o8_Rd06_ADCabcd" 01326 // TODO: support long SPI read CMD_0001_1010_d16o8_d16o8_d16o8_d16o8_Rd06_ADCabcd 01327 // %SW 0x1A (0 0 0) (0 0 0) (0 0 0) (0 0 0) -- for 24-bit read A,B,C,D 01328 // update adca, adcb, adcc, adcd 01329 // 01330 { 01331 // SPI 8+96 = 104-bit transfer 01332 // 1234 5678 ___[1]_16 ___[2]_24 ___[3]_32 ___[4]_40 ___[5]_48 ___[6]_56 ___[7]_64 ___[8]_72 ___[9]_80 __[10]_88 __[11]_96 __[12]104 01333 // SPI MOSI = 1aaa_aaaa_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000 ... _0000 01334 // SPI MISO = xxxx_xxxx_dddd_dddd_dddd_dddd_dddd_dddd_dddd_dddd_dddd_dddd_dddd_dddd_dddd_dddd_dddd_dddd_dddd_dddd_dddd_dddd_dddd_dddd_dddd_dddd ... _xxxx 01335 size_t byteCount = 1 + (3 * 4); 01336 uint8_t mosiData[13]; 01337 uint8_t misoData[13]; 01338 mosiData[0] = CMDOP_0aaa_aa10_ReadRegister | commandByte; 01339 mosiData[1] = 0; // CMDOP_1111_1111_NoOperationMOSIidleHigh; 01340 mosiData[2] = 0; // CMDOP_1111_1111_NoOperationMOSIidleHigh; 01341 mosiData[3] = 0; // CMDOP_1111_1111_NoOperationMOSIidleHigh; 01342 mosiData[4] = 0; // CMDOP_1111_1111_NoOperationMOSIidleHigh; 01343 mosiData[5] = 0; // CMDOP_1111_1111_NoOperationMOSIidleHigh; 01344 mosiData[6] = 0; // CMDOP_1111_1111_NoOperationMOSIidleHigh; 01345 mosiData[7] = 0; // CMDOP_1111_1111_NoOperationMOSIidleHigh; 01346 mosiData[8] = 0; // CMDOP_1111_1111_NoOperationMOSIidleHigh; 01347 mosiData[9] = 0; // CMDOP_1111_1111_NoOperationMOSIidleHigh; 01348 mosiData[10] = 0; // CMDOP_1111_1111_NoOperationMOSIidleHigh; 01349 mosiData[11] = 0; // CMDOP_1111_1111_NoOperationMOSIidleHigh; 01350 mosiData[12] = 0; // CMDOP_1111_1111_NoOperationMOSIidleHigh; 01351 // SPIreadWriteWithLowCS(size_t byteCount, uint8_t mosiData[], uint8_t misoData[]); 01352 SPIreadWriteWithLowCS(byteCount, mosiData, misoData); 01353 if (ptrRegData) { (*ptrRegData) = (misoData[1] << 16) | (misoData[2] << 8) | misoData[3]; } 01354 if (commandByte == CMD_0001_1010_d16o8_d16o8_d16o8_d16o8_Rd06_ADCabcd) { 01355 // TODO1: update adca 01356 adca = (misoData[1] << 16) | (misoData[2] << 8) | misoData[3]; 01357 // TODO1: update adcb 01358 adcb = (misoData[4] << 16) | (misoData[5] << 8) | misoData[6]; 01359 // TODO1: update adcc 01360 adcc = (misoData[7] << 16) | (misoData[8] << 8) | misoData[9]; 01361 // TODO1: update adcd 01362 adcd = (misoData[10] << 16) | (misoData[11] << 8) | misoData[12]; 01363 } 01364 } 01365 break; 01366 } 01367 01368 //---------------------------------------- 01369 // success 01370 return 1; 01371 } 01372 01373 //---------------------------------------- 01374 // Return the size of a MAX11043 register 01375 // 01376 // @return 8 for 8-bit, 16 for 16-bit, 24 for 24-bit, else 0 for undefined register size 01377 uint8_t MAX11043::RegSize(MAX11043_CMD_enum_t commandByte) 01378 { 01379 01380 //---------------------------------------- 01381 // switch based on register address value regAddress 01382 // commandByte = (MAX11043_CMD_enum_t)((commandByte &~ CMDOP_0aaa_aa10_ReadRegister) & 0xFF); 01383 switch(commandByte) 01384 { 01385 default: 01386 // case CMDOP_0aaa_aa00_WriteRegister: 01387 // case CMDOP_0aaa_aa10_ReadRegister: 01388 // case CMDOP_1111_1111_NoOperationMOSIidleHigh: 01389 return 0; // undefined register size 01390 case CMD_0001_1110_d8_Rd07_Status: 01391 case CMD_0101_0100_d8_Wr15_FilterCAddress: 01392 case CMD_0101_0110_d8_Rd15_FilterCAddress: 01393 case CMD_0110_0000_d8_Wr18_FlashMode: 01394 case CMD_0110_0010_d8_Rd18_FlashMode: 01395 return 8; // 8-bit register size 01396 case CMD_0010_0000_d16_Wr08_Configuration: 01397 case CMD_0010_0010_d16_Rd08_Configuration: 01398 case CMD_0010_0100_d16_Wr09_DAC: 01399 case CMD_0010_0110_d16_Rd09_DAC: 01400 case CMD_0010_1000_d16_Wr0A_DACStep: 01401 case CMD_0010_1010_d16_Rd0A_DACStep: 01402 case CMD_0010_1100_d16_Wr0B_DACHDACL: 01403 case CMD_0010_1110_d16_Rd0B_DACHDACL: 01404 case CMD_0011_0000_d16_Wr0C_ConfigA: 01405 case CMD_0011_0010_d16_Rd0C_ConfigA: 01406 case CMD_0011_0100_d16_Wr0D_ConfigB: 01407 case CMD_0011_0110_d16_Rd0D_ConfigB: 01408 case CMD_0011_1000_d16_Wr0E_ConfigC: 01409 case CMD_0011_1010_d16_Rd0E_ConfigC: 01410 case CMD_0011_1100_d16_Wr0F_ConfigD: 01411 case CMD_0011_1110_d16_Rd0F_ConfigD: 01412 case CMD_0100_0000_d16_Wr10_Reference: 01413 case CMD_0100_0010_d16_Rd10_Reference: 01414 case CMD_0100_0100_d16_Wr11_AGain: 01415 case CMD_0100_0110_d16_Rd11_AGain: 01416 case CMD_0100_1000_d16_Wr12_BGain: 01417 case CMD_0100_1010_d16_Rd12_BGain: 01418 case CMD_0100_1100_d16_Wr13_CGain: 01419 case CMD_0100_1110_d16_Rd13_CGain: 01420 case CMD_0101_0000_d16_Wr14_DGain: 01421 case CMD_0101_0010_d16_Rd14_DGain: 01422 case CMD_0110_0100_d16_Wr19_FlashAddr: 01423 case CMD_0110_0110_d16_Rd19_FlashAddr: 01424 case CMD_0110_1000_d16_Wr1A_FlashDataIn: 01425 case CMD_0110_1010_d16_Rd1A_FlashDataIn: 01426 case CMD_0110_1110_d16_Rd1B_FlashDataOut: 01427 return 16; // 16-bit register size 01428 case CMD_0000_0010_d16o8_Rd00_ADCa: 01429 case CMD_0000_0110_d16o8_Rd01_ADCb: 01430 case CMD_0000_1010_d16o8_Rd02_ADCc: 01431 case CMD_0000_1110_d16o8_Rd03_ADCd: 01432 if (config & CONFIG_xxxx_xxxx_xx1x_xxxx_24BIT) 01433 { 01434 // %SW 0x02 (0 0 0) -- for 24-bit read 01435 return 24; // 24-bit register size 01436 } 01437 // %SW 0x02 (0 0) -- for 16-bit read 01438 // 01439 return 16; // 16-bit register size 01440 case CMD_0001_0010_d16o8_d16o8_Rd04_ADCab: 01441 case CMD_0001_0110_d16o8_d16o8_Rd05_ADCcd: 01442 // 01443 // TODO: support long SPI read 01444 if (config & CONFIG_xxxx_xxxx_xx1x_xxxx_24BIT) 01445 { 01446 // %SW 0x12 (0 0 0) (0 0 0) -- for 24-bit read A,B 01447 // %SW 0x16 (0 0 0) (0 0 0) -- for 24-bit read C,D 01448 return 48; // 48-bit register size: 2*(24) 01449 } 01450 // %SW 0x12 (0 0) (0 0) -- for 16-bit read A,B 01451 // %SW 0x16 (0 0) (0 0) -- for 16-bit read C,D 01452 // 01453 return 32; // 32-bit register size: 2*(16) 01454 case CMD_0001_1010_d16o8_d16o8_d16o8_d16o8_Rd06_ADCabcd: 01455 // 01456 // TODO: support long SPI read 01457 if (config & CONFIG_xxxx_xxxx_xx1x_xxxx_24BIT) 01458 { 01459 // %SW 0x1A (0 0 0) (0 0 0) (0 0 0) (0 0 0) -- for 24-bit read A,B,C,D 01460 return 96; // 96-bit register size: 4*(24) 01461 } 01462 // %SW 0x1A (0 0) (0 0) (0 0) (0 0) -- for 16-bit read A,B,C,D 01463 // 01464 return 64; // 64-bit register size: 4*(16) 01465 case CMD_0101_1000_d32_Wr16_FilterCDataOut: 01466 case CMD_0101_1010_d32_Rd16_FilterCDataOut: 01467 case CMD_0101_1100_d32_Wr17_FilterCDataIn: 01468 case CMD_0101_1110_d32_Rd17_FilterCDataIn: 01469 return 32; // 32-bit register size 01470 } 01471 } 01472 01473 //---------------------------------------- 01474 // Decode operation from commandByte 01475 // 01476 // @return operation such as idle, read register, write register, etc. 01477 MAX11043::MAX11043_CMDOP_enum_t MAX11043::DecodeCommand(MAX11043_CMD_enum_t commandByte) 01478 { 01479 01480 //---------------------------------------- 01481 // decode operation from command byte 01482 switch (commandByte & 0x83) 01483 { 01484 case CMDOP_0aaa_aa10_ReadRegister: 01485 return CMDOP_0aaa_aa10_ReadRegister; 01486 case CMDOP_0aaa_aa00_WriteRegister: 01487 return CMDOP_0aaa_aa00_WriteRegister; 01488 default: 01489 return CMDOP_1111_1111_NoOperationMOSIidleHigh; 01490 } 01491 } 01492 01493 //---------------------------------------- 01494 // Return the address field of a MAX11043 register 01495 // 01496 // @return register address field as given in datasheet 01497 uint8_t MAX11043::RegAddrOfCommand(MAX11043_CMD_enum_t commandByte) 01498 { 01499 01500 //---------------------------------------- 01501 // extract register address value from command byte 01502 return (uint8_t)((commandByte &~ 0x83) >> 2); // CMDOP_0aaa_aa10_ReadRegister 01503 } 01504 01505 //---------------------------------------- 01506 // Test whether a command byte is a register read command 01507 // 01508 // @return true if command byte is a register read command 01509 uint8_t MAX11043::IsRegReadCommand(MAX11043_CMD_enum_t commandByte) 01510 { 01511 01512 //---------------------------------------- 01513 // Test whether a command byte is a register read command 01514 return (commandByte &~ 0x02) ? 1 : 0; // CMDOP_0aaa_aa10_ReadRegister 01515 } 01516 01517 //---------------------------------------- 01518 // Return the name of a MAX11043 register 01519 // 01520 // @return null-terminated constant C string containing register name or empty string 01521 const char* MAX11043::RegName(MAX11043_CMD_enum_t commandByte) 01522 { 01523 01524 //---------------------------------------- 01525 // switch based on register address value regAddress 01526 // commandByte = (MAX11043_CMD_enum_t)((commandByte &~ CMDOP_0aaa_aa10_ReadRegister) & 0xFF); 01527 switch(commandByte) 01528 { 01529 default: 01530 return ""; // undefined register 01531 // case CMDOP_0aaa_aa00_WriteRegister: return "_______"; 01532 // case CMDOP_0aaa_aa10_ReadRegister: return "_______"; 01533 // case CMDOP_1111_1111_NoOperationMOSIidleHigh: return "_______"; 01534 case CMD_0000_0010_d16o8_Rd00_ADCa: return "ADCa"; 01535 case CMD_0000_0110_d16o8_Rd01_ADCb: return "ADCb"; 01536 case CMD_0000_1010_d16o8_Rd02_ADCc: return "ADCc"; 01537 case CMD_0000_1110_d16o8_Rd03_ADCd: return "ADCd"; 01538 case CMD_0001_0010_d16o8_d16o8_Rd04_ADCab: return "ADCab"; 01539 case CMD_0001_0110_d16o8_d16o8_Rd05_ADCcd: return "ADCcd"; 01540 case CMD_0001_1010_d16o8_d16o8_d16o8_d16o8_Rd06_ADCabcd: return "ADCabcd"; 01541 case CMD_0001_1110_d8_Rd07_Status: return "Status"; 01542 case CMD_0010_0000_d16_Wr08_Configuration: return "Configuration"; 01543 case CMD_0010_0010_d16_Rd08_Configuration: return "Configuration"; 01544 case CMD_0010_0100_d16_Wr09_DAC: return "DAC"; 01545 case CMD_0010_0110_d16_Rd09_DAC: return "DAC"; 01546 case CMD_0010_1000_d16_Wr0A_DACStep: return "DACStep"; 01547 case CMD_0010_1010_d16_Rd0A_DACStep: return "DACStep"; 01548 case CMD_0010_1100_d16_Wr0B_DACHDACL: return "DACHDACL"; 01549 case CMD_0010_1110_d16_Rd0B_DACHDACL: return "DACHDACL"; 01550 case CMD_0011_0000_d16_Wr0C_ConfigA: return "ConfigA"; 01551 case CMD_0011_0010_d16_Rd0C_ConfigA: return "ConfigA"; 01552 case CMD_0011_0100_d16_Wr0D_ConfigB: return "ConfigB"; 01553 case CMD_0011_0110_d16_Rd0D_ConfigB: return "ConfigB"; 01554 case CMD_0011_1000_d16_Wr0E_ConfigC: return "ConfigC"; 01555 case CMD_0011_1010_d16_Rd0E_ConfigC: return "ConfigC"; 01556 case CMD_0011_1100_d16_Wr0F_ConfigD: return "ConfigD"; 01557 case CMD_0011_1110_d16_Rd0F_ConfigD: return "ConfigD"; 01558 case CMD_0100_0000_d16_Wr10_Reference: return "Reference"; 01559 case CMD_0100_0010_d16_Rd10_Reference: return "Reference"; 01560 case CMD_0100_0100_d16_Wr11_AGain: return "AGain"; 01561 case CMD_0100_0110_d16_Rd11_AGain: return "AGain"; 01562 case CMD_0100_1000_d16_Wr12_BGain: return "BGain"; 01563 case CMD_0100_1010_d16_Rd12_BGain: return "BGain"; 01564 case CMD_0100_1100_d16_Wr13_CGain: return "CGain"; 01565 case CMD_0100_1110_d16_Rd13_CGain: return "CGain"; 01566 case CMD_0101_0000_d16_Wr14_DGain: return "DGain"; 01567 case CMD_0101_0010_d16_Rd14_DGain: return "DGain"; 01568 case CMD_0101_0100_d8_Wr15_FilterCAddress: return "FilterCAddress"; 01569 case CMD_0101_0110_d8_Rd15_FilterCAddress: return "FilterCAddress"; 01570 case CMD_0101_1000_d32_Wr16_FilterCDataOut: return "FilterCDataOut"; 01571 case CMD_0101_1010_d32_Rd16_FilterCDataOut: return "FilterCDataOut"; 01572 case CMD_0101_1100_d32_Wr17_FilterCDataIn: return "FilterCDataIn"; 01573 case CMD_0101_1110_d32_Rd17_FilterCDataIn: return "FilterCDataIn"; 01574 case CMD_0110_0000_d8_Wr18_FlashMode: return "FlashMode"; 01575 case CMD_0110_0010_d8_Rd18_FlashMode: return "FlashMode"; 01576 case CMD_0110_0100_d16_Wr19_FlashAddr: return "FlashAddr"; 01577 case CMD_0110_0110_d16_Rd19_FlashAddr: return "FlashAddr"; 01578 case CMD_0110_1000_d16_Wr1A_FlashDataIn: return "FlashDataIn"; 01579 case CMD_0110_1010_d16_Rd1A_FlashDataIn: return "FlashDataIn"; 01580 case CMD_0110_1110_d16_Rd1B_FlashDataOut: return "FlashDataOut"; 01581 } 01582 } 01583 01584 //---------------------------------------- 01585 // Menu item '$' -> adca, adcb, adcc, adcd 01586 // Read ADCabcd 01587 // 01588 // @return 1 on success; 0 on failure 01589 uint8_t MAX11043::Read_ADCabcd(void) 01590 { 01591 01592 //---------------------------------------- 01593 // warning -- WIP work in progress 01594 #warning "Not Tested Yet: MAX11043::Read_ADCabcd..." 01595 01596 //-------------------------------------------------- 01597 // MAX11043 ADC Read operations must be synchronized to EOC End Of Conversion 01598 //---------------------------------------- 01599 // warning -- WIP work in progress 01600 #warning "need CONVRUNoutputGetValue() -- is CONVRUN being driven high?" 01601 01602 //---------------------------------------- 01603 // Synchronize with EOC End Of Conversion 01604 // MAX11043 ADC Read operations must be synchronized to EOC End Of Conversion 01605 // EOC# asserts low when new data is available. 01606 // Initiate a data read prior to the next rising edge of EOC# or the result is overwritten. 01607 #if MAX11043_EOC_INTERRUPT_POLLING 01608 // MAX11043 EOC End Of Conversion input should be InterruptIn(PinName:EOC_pin).fall(onEOCFallingEdge); 01609 // Workaround using DigitalIn(PinName:EOC_pin) polled to sync with EOC falling edge for ADC reads 01610 // 2020-02-20 MAX11043_EOC_INTERRUPT_POLLING works on MAX32625MBED at 9us conversion rate, with 1us timing margin 01611 // TODO: poll m_EOC_pin if CONVRUN is high 01612 if (CONVRUNoutputGetValue()) // is CONVRUN being driven high? 01613 { 01614 // CONVRUN pin is being driven high, so EOC# will be changing. 01615 // Try to read as close as possible to EOC# falling edge, 01616 // because if EOC# falling edge happens during SPI data readout, 01617 // the data will be corrupted. 01618 #warning "MAX11043::Read_ADCabcd() Potential infinite loop if EOC pin not connected" 01619 // possible infinite loop; need a timeout or futility countdown to escape 01620 for (int futility_countdown = 100; 01621 ((futility_countdown > 0) && 01622 (EOCinputValue() != 1)); 01623 futility_countdown--) 01624 { 01625 // spinlock waiting for logic high pin state (start of new conversion) 01626 } 01627 for (int futility_countdown = 100; 01628 ((futility_countdown > 0) && 01629 (EOCinputValue() != 0)); 01630 futility_countdown--) 01631 { 01632 // spinlock waiting for logic low pin state (new data is available) 01633 } 01634 } 01635 else 01636 { 01637 // CONVRUN pin is being driven low, so conversion result will not change, EOC# remains high 01638 } 01639 #else // MAX11043_EOC_INTERRUPT_POLLING 01640 // MAX11043 EOC End Of Conversion input is InterruptIn(PinName:EOC_pin).fall(onEOCFallingEdge); 01641 #endif // MAX11043_EOC_INTERRUPT_POLLING 01642 //-------------------------------------------------- 01643 01644 //---------------------------------------- 01645 // read register ADCabcd -> &adca, &adcb, &adcc, &adcd 01646 RegRead(CMD_0001_1010_d16o8_d16o8_d16o8_d16o8_Rd06_ADCabcd, 0); // updates &adca, &adcb, &adcc, &adcd 01647 01648 //---------------------------------------- 01649 // success 01650 return 1; 01651 } 01652 01653 //---------------------------------------- 01654 // Menu item 'GA' 01655 // Write AGain register 01656 // 01657 // @param[in] gain 2's complement, 0x800=0.25V/V, 0x1000=0.5V/V, 0x2000=1V/V, 0x4000=2V/V, default=0x2000 01658 // 01659 // @return 1 on success; 0 on failure 01660 uint8_t MAX11043::Write_AGain(uint32_t gain) 01661 { 01662 01663 //---------------------------------------- 01664 // warning -- WIP work in progress 01665 #warning "Not Tested Yet: MAX11043::Write_AGain..." 01666 01667 //---------------------------------------- 01668 // write register 01669 RegWrite(CMD_0100_0100_d16_Wr11_AGain, gain); 01670 01671 //---------------------------------------- 01672 // success 01673 return 1; 01674 } 01675 01676 //---------------------------------------- 01677 // Menu item 'XD' 01678 // Example configuration. 01679 // Slowest conversion rate 1:6 = 9us, 01680 // Bypass PGA and filters, Gain=1V/V, 01681 // AOUT = 2.0V 01682 // 01683 void MAX11043::Configure_Demo(void) 01684 { 01685 01686 //---------------------------------------- 01687 // warning -- WIP work in progress 01688 #warning "Not Tested Yet: MAX11043::Configure_Demo..." 01689 01690 //---------------------------------------- 01691 // *Config=0x6000 (POR default, slowest conversion rate 1:6 = 9us) 01692 RegWrite(CMD_0010_0000_d16_Wr08_Configuration, 0x6000); 01693 01694 //---------------------------------------- 01695 // *ConfigA=0x0018 (Bypass PGA and filters, Gain=1V/V) 01696 RegWrite(CMD_0011_0000_d16_Wr0C_ConfigA, 0x0018); 01697 01698 //---------------------------------------- 01699 // *AGain=0x1000 (0.5) (default is 0x2000=1.0) 01700 RegWrite(CMD_0100_0100_d16_Wr11_AGain, 0x1000); 01701 01702 //---------------------------------------- 01703 // *ConfigB=0x0018 (Bypass PGA and filters, Gain=1V/V) 01704 RegWrite(CMD_0011_0100_d16_Wr0D_ConfigB, 0x0018); 01705 01706 //---------------------------------------- 01707 // *BGain=0x1000 (0.5) (default is 0x2000=1.0) 01708 RegWrite(CMD_0100_1000_d16_Wr12_BGain, 0x1000); 01709 01710 //---------------------------------------- 01711 // *ConfigC=0x0018 (Bypass PGA and filters, Gain=1V/V) 01712 RegWrite(CMD_0011_1000_d16_Wr0E_ConfigC, 0x0018); 01713 01714 //---------------------------------------- 01715 // *CGain=0x1000 (0.5) (default is 0x2000=1.0) 01716 RegWrite(CMD_0100_1100_d16_Wr13_CGain, 0x1000); 01717 01718 //---------------------------------------- 01719 // *ConfigD=0x0018 (Bypass PGA and filters, Gain=1V/V) 01720 RegWrite(CMD_0011_1100_d16_Wr0F_ConfigD, 0x0018); 01721 01722 //---------------------------------------- 01723 // *DGain=0x1000 (0.5) (default is 0x2000=1.0) 01724 RegWrite(CMD_0101_0000_d16_Wr14_DGain, 0x1000); 01725 01726 //---------------------------------------- 01727 // *DacHDacL=0xFF00 (DAC code 0xFFF fullscale 2.5V, DAC code 0x000 lowest 0V) 01728 RegWrite(CMD_0010_1100_d16_Wr0B_DACHDACL, 0xFF00); 01729 01730 //---------------------------------------- 01731 // *DacStep=0x0001 (DAC increment value triggered by DACSTEP pin) 01732 RegWrite(CMD_0010_1000_d16_Wr0A_DACStep, 0x0001); 01733 01734 //---------------------------------------- 01735 // *Dac=0x0ccc (AOUT=2V) 01736 RegWrite(CMD_0010_0100_d16_Wr09_DAC, 0x0ccc); 01737 } 01738 01739 //---------------------------------------- 01740 // Menu item 'XX' 01741 // 01742 // @return 1 on success; 0 on failure 01743 uint8_t MAX11043::Configure_XXXXX(uint8_t linef, uint8_t rate) 01744 { 01745 01746 //---------------------------------------- 01747 // warning -- WIP work in progress 01748 #warning "Not Tested Yet: MAX11043::Configure_XXXXX..." 01749 01750 //---------------------------------------- 01751 // read register 01752 RegRead(CMD_0000_0010_d16o8_Rd00_ADCa, 0); // updates &adca 01753 01754 //---------------------------------------- 01755 // success 01756 return 1; 01757 } 01758 01759 //---------------------------------------- 01760 // Menu item 'XY' 01761 // 01762 // @return 1 on success; 0 on failure 01763 uint8_t MAX11043::Configure_XXXXY(uint8_t linef, uint8_t rate) 01764 { 01765 01766 //---------------------------------------- 01767 // warning -- WIP work in progress 01768 #warning "Not Tested Yet: MAX11043::Configure_XXXXY..." 01769 01770 //---------------------------------------- 01771 // read register 01772 RegRead(CMD_0001_1110_d8_Rd07_Status, 0); // udpates &status 01773 01774 //---------------------------------------- 01775 // success 01776 return 1; 01777 } 01778 01779 01780 // End of file
Generated on Wed Jul 13 2022 22:23:56 by 1.7.2