57 minutes ago, Antichambre said:
Do you test it without the NG with a regular app first?
No. As I don’t use any other app and I stated above that I want to use it in NG TK surely took care of it.
This is ainser.c:
// $Id$ //! \defgroup AINSER //! //! AINSER module driver //! //! \{ /\* ========================================================================== \* \* Copyright (C) 2011 Thorsten Klose (tk@midibox.org) \* Licensed for personal non-commercial use only. \* All other rights reserved. \* \* ========================================================================== \*/ ///////////////////////////////////////////////////////////////////////////// // Include files ///////////////////////////////////////////////////////////////////////////// #include \<mios32.h\> #include "ainser.h" ///////////////////////////////////////////////////////////////////////////// // Local variables ///////////////////////////////////////////////////////////////////////////// static u8 num\_used\_modules = AINSER\_NUM\_MODULES; static u8 ainser\_enable\_mask; static u8 ainser\_muxed\_mask; static u8 num\_used\_pins[AINSER\_NUM\_MODULES]; static u16 ain\_pin\_values[AINSER\_NUM\_MODULES][AINSER\_NUM\_PINS]; static u16 previous\_ain\_pin\_value; static u8 ain\_deadband[AINSER\_NUM\_MODULES]; ///////////////////////////////////////////////////////////////////////////// // Local Prototypes ///////////////////////////////////////////////////////////////////////////// static s32 AINSER\_SetCs(u8 module, u8 value); ///////////////////////////////////////////////////////////////////////////// //! Initializes AINSER driver //! Should be called from Init() during startup //! \param[in] mode currently only mode 0 supported //! \return \< 0 if initialisation failed ///////////////////////////////////////////////////////////////////////////// s32 AINSER\_Init(u32 mode) { s32 status = 0; int module, pin; // currently only mode 0 supported if( mode != 0 ) return -1; // unsupported mode #if AINSER\_SPI\_OUTPUTS\_OD // pins in open drain mode (to pull-up the outputs to 5V) status |= MIOS32\_SPI\_IO\_Init(AINSER\_SPI, MIOS32\_SPI\_PIN\_DRIVER\_STRONG\_OD); #else // pins in push-poll mode (3.3V output voltage) status |= MIOS32\_SPI\_IO\_Init(AINSER\_SPI, MIOS32\_SPI\_PIN\_DRIVER\_STRONG); #endif // extra CS pin #if AINSER\_NUM\_MODULES \>= 3 MIOS32\_BOARD\_J10\_PinInit(14, MIOS32\_BOARD\_PIN\_MODE\_OUTPUT\_OD); #endif // SPI Port will be initialized in AINSER\_Update() num\_used\_modules = AINSER\_NUM\_MODULES; #if AINSER\_NUM\_MODULES \> 8 # error "If more than 8 AINSER\_NUM\_MODULES should be supported, the ainser\_enable\_mask variable type has to be changed from u8 to u16 (up to 16) or u32 (up to 32)" #endif #if AINSER\_NUM\_MODULES \> 8 # error "If more than 8 AINSER\_NUM\_MODULES should be supported, the ainser\_muxed\_mask variable type has to be changed from u8 to u16 (up to 16) or u32 (up to 32)" #endif for(module=0; module\<AINSER\_NUM\_MODULES; ++module) { num\_used\_pins[module] = AINSER\_NUM\_PINS; // ensure that CS is deactivated AINSER\_SetCs(module, 1); AINSER\_EnabledSet(module, 1); AINSER\_MuxedSet(module, 1); AINSER\_NumPinsSet(module, AINSER\_NUM\_PINS); AINSER\_DeadbandSet(module, MIOS32\_AIN\_DEADBAND); // clear all values for(pin=0; pin\<AINSER\_NUM\_PINS; ++pin) { ain\_pin\_values[module][pin] = 0; } previous\_ain\_pin\_value = 0; } return status; } ///////////////////////////////////////////////////////////////////////////// //! \return the number of modules which are scanned ///////////////////////////////////////////////////////////////////////////// s32 AINSER\_NumModulesGet(void) { return num\_used\_modules; } ///////////////////////////////////////////////////////////////////////////// //! Sets the number of modules which should be scanned //! \return \< 0 on error (e.g. unsupported number of modules) ///////////////////////////////////////////////////////////////////////////// s32 AINSER\_NumModulesSet(u8 num\_modules) { if( num\_modules \>= AINSER\_NUM\_MODULES ) return -1; num\_used\_modules = num\_modules; return 0; // no error } ///////////////////////////////////////////////////////////////////////////// //! \return the enable mask for modules which should be scanned ///////////////////////////////////////////////////////////////////////////// s32 AINSER\_EnabledGet(u8 module) { if( module \>= AINSER\_NUM\_MODULES ) return 0; return (ainser\_enable\_mask & (1 \<\< module)) ? 1 : 0; } ///////////////////////////////////////////////////////////////////////////// //! Sets the enable mask for modules which should be scanned ///////////////////////////////////////////////////////////////////////////// s32 AINSER\_EnabledSet(u8 module, u8 enabled) { if( module \>= AINSER\_NUM\_MODULES ) return -1; // invalid module if( enabled ) ainser\_enable\_mask |= (1 \<\< module); else ainser\_enable\_mask &= ~(1 \<\< module); return 0; // no error } ///////////////////////////////////////////////////////////////////////////// //! \retval 0 if 1-to-8 multiplexers disabled for the given module //! \retval 1 if 1-to-8 multiplexers enabled for the given module (default) ///////////////////////////////////////////////////////////////////////////// s32 AINSER\_MuxedGet(u8 module) { if( module \>= AINSER\_NUM\_MODULES ) return 0; return (ainser\_muxed\_mask & (1 \<\< module)) ? 1 : 0; } ///////////////////////////////////////////////////////////////////////////// //! Enables/disables the 1-to-8 multiplexer handling.\n //! Use muxed=0 for AINSER8 module, and muxed=1 for AINSER64 module (default) ///////////////////////////////////////////////////////////////////////////// s32 AINSER\_MuxedSet(u8 module, u8 muxed) { if( module \>= AINSER\_NUM\_MODULES ) return -1; // invalid module if( muxed ) ainser\_muxed\_mask |= (1 \<\< module); else ainser\_muxed\_mask &= ~(1 \<\< module); return 0; // no error } ///////////////////////////////////////////////////////////////////////////// //! \return the number of AIN pins per module which are scanned ///////////////////////////////////////////////////////////////////////////// s32 AINSER\_NumPinsGet(u8 module) { if( module \>= AINSER\_NUM\_MODULES ) return 0; // invalid module (return 0 pins) return num\_used\_pins[module]; } ///////////////////////////////////////////////////////////////////////////// //! Sets the number of AIN pins per module which should be scanned //! \return \< 0 on error (e.g. unsupported number of pins) ///////////////////////////////////////////////////////////////////////////// s32 AINSER\_NumPinsSet(u8 module, u8 num\_pins) { if( module \>= AINSER\_NUM\_MODULES ) return -1; // invalid module if( num\_pins \> AINSER\_NUM\_PINS ) return -2; num\_used\_pins[module] = num\_pins; return 0; // no error } ///////////////////////////////////////////////////////////////////////////// //! \return the deadband which is used to notify changes //! \return \< 0 on error ///////////////////////////////////////////////////////////////////////////// s32 AINSER\_DeadbandGet(u8 module) { if( module \>= AINSER\_NUM\_MODULES ) return 0; // invalid module (return 0) return ain\_deadband[module]; } ///////////////////////////////////////////////////////////////////////////// //! Sets the difference between last and current pot value which has to //! be achieved to trigger the callback function passed to AINSER\_Handler() //! \return \< 0 on error ///////////////////////////////////////////////////////////////////////////// s32 AINSER\_DeadbandSet(u8 module, u8 deadband) { if( module \>= AINSER\_NUM\_MODULES ) return -1; // invalid module ain\_deadband[module] = deadband; return 0; // no error } ///////////////////////////////////////////////////////////////////////////// //! \return the AIN pin value of the given module and pin //! \return \< 0 if wrong module or pin selected! ///////////////////////////////////////////////////////////////////////////// s32 AINSER\_PinGet(u8 module, u8 pin) { if( module \>= AINSER\_NUM\_MODULES ) return -1; if( pin \>= AINSER\_NUM\_PINS ) return -1; return ain\_pin\_values[module][pin]; } ///////////////////////////////////////////////////////////////////////////// //! \return the previous value of the pin which has triggered the NotifyChanged hook.\n //! Only valid when function is called from this hook! ///////////////////////////////////////////////////////////////////////////// s32 AINSER\_PreviousPinValueGet(void) { return previous\_ain\_pin\_value; } ///////////////////////////////////////////////////////////////////////////// //! This function should be periodically called to scan AIN pin changes. //! //! A scan of a single multiplexer selection takes ca. 50 uS on a LPC1769 with MIOS32\_SPI\_PRESCALER\_8 //! //! Whenever a pin has changed, the given callback function will be called.\n //! Example: //! \code //! void AINSER\_NotifyChanged(u32 pin, u16 value); //! \endcode //! \param[in] \_callback pointer to callback function //! \return \< 0 on errors ///////////////////////////////////////////////////////////////////////////// s32 AINSER\_Handler(void (\*\_callback)(u32 module, u32 pin, u32 value)) { // the mux\_ctr -\> pin mappin is layout dependend //const u8 mux\_pin\_map[8] = {0, 1, 2, 3, 4, 5, 6, 7 }; //const u8 mux\_pin\_map[8] = {1, 4, 3, 5, 2, 7, 0, 6 }; // reversed pins const u8 mux\_pin\_map[8] = {6, 3, 4, 2, 5, 0, 7, 1 }; // order of MUX channels static u8 mux\_ctr = 0; // will be incremented on each update to select the next AIN pin static u8 first\_scan\_done = 0; static u16 link\_status\_ctr = 0; s32 status = 0; // init SPI port for fast frequency access // we will do this here, so that other handlers (e.g. AOUT) could use SPI in different modes // Maxmimum allowed SCLK is 2 MHz according to datasheet // We select prescaler 64 @120 MHz (-\> ca. 500 nS period) status |= MIOS32\_SPI\_TransferModeInit(AINSER\_SPI, MIOS32\_SPI\_MODE\_CLK0\_PHASE0, MIOS32\_SPI\_PRESCALER\_64); // determine next MUX selection int next\_mux\_ctr = (mux\_ctr + 1) % 8; // link LED will flash with PWM effect ++link\_status\_ctr; const u32 pwm\_period = 20; // \*1 mS -\> 20 mS const u32 pwm\_sweep\_steps = 100; // \*20 mS -\> 2000 mS u32 pwm\_duty = ((link\_status\_ctr / pwm\_period) % pwm\_sweep\_steps) / (pwm\_sweep\_steps/pwm\_period); if( (link\_status\_ctr % (2\*pwm\_period\*pwm\_sweep\_steps)) \> pwm\_period\*pwm\_sweep\_steps ) pwm\_duty = pwm\_period-pwm\_duty; // negative direction each 20\*25 ticks u32 link\_status = ((link\_status\_ctr % pwm\_period) \> pwm\_duty) ? 1 : 0; // loop over connected modules int module; u32 module\_mask = 1; for(module=0; module\<num\_used\_modules; ++module, module\_mask \<\<= 1) { if( !(ainser\_enable\_mask & module\_mask) ) continue; u8 muxed = ainser\_muxed\_mask & module\_mask; // loop over channels int chn; for(chn=0; chn\<8; ++chn) { // CS=0 status |= AINSER\_SetCs(module, 0); // retrieve conversion values // shift in start bit + SGL + MSB of channel selection, shift out dummy byte MIOS32\_SPI\_TransferByte(AINSER\_SPI, 0x06 | (chn\>\>2)); // shift in remaining 2 bits of channel selection, shift out MSBs of conversion value u8 b1 = MIOS32\_SPI\_TransferByte(AINSER\_SPI, chn \<\< 6); // shift in mux\_ctr + "Link LED" status to 74HC595, shift out LSBs of conversion value u8 b2 = MIOS32\_SPI\_TransferByte(AINSER\_SPI, ((chn == 7 ? next\_mux\_ctr : mux\_ctr) \<\< 5) | link\_status); // CS=1 (the rising edge will update the 74HC595) AINSER\_SetCs(module, 1); // store conversion value if difference to old value is outside the deadband u16 pin = muxed ? (mux\_pin\_map[mux\_ctr] + 8\*(7-chn)) : (7-chn); // the mux/chn -\> pin mapping is layout dependend u16 value = (b2 | (b1 \<\< 8)) & 0xfff; previous\_ain\_pin\_value = ain\_pin\_values[module][pin]; int diff = value - previous\_ain\_pin\_value; int abs\_diff = (diff \> 0 ) ? diff : -diff; if( !first\_scan\_done || abs\_diff \> ain\_deadband[module] ) { ain\_pin\_values[module][pin] = value; // notify callback function // check pin number as well... just to ensure if( first\_scan\_done && \_callback && pin \< num\_used\_pins[module] ) \_callback(module, pin, value); } } } // select MUX input mux\_ctr = next\_mux\_ctr; // one complete scan done? if( next\_mux\_ctr == 0 ) first\_scan\_done = 1; return 0; // no error } ///////////////////////////////////////////////////////////////////////////// // Internal function to set CS line depending on module ///////////////////////////////////////////////////////////////////////////// static s32 AINSER\_SetCs(u8 module, u8 value) { switch( module ) { case 0: return MIOS32\_SPI\_RC\_PinSet(AINSER\_SPI, AINSER\_SPI\_RC\_PIN\_MODULE1, value); // spi, rc\_pin, pin\_value case 1: return MIOS32\_SPI\_RC\_PinSet(AINSER\_SPI, AINSER\_SPI\_RC\_PIN\_MODULE2, value); // spi, rc\_pin, pin\_value case 2: return MIOS32\_BOARD\_J10\_PinSet(14, value); #if AINSER\_NUM\_MODULES \> 3 # error "CS Line for more than 3 modules not prepared yet - please enhance here!" #endif } return -1; } //! \}
and in mios32_config.h I set
#define AINSER\_NUM\_MODULES 3
So, it should be exactly the same as in TKs branch.