Adding CS-line to AINSER8

Hey people,

I’d like to add one or two chip-selects for the AINSER8. I’ve already made a few changes to the firmware but it’s not working yet.

Under modules I’ve edited the ainser.c:
 

{ 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\_SPI\_RC\_PinSet(AINSER\_SPI, AINSER\_SPI\_RC\_PIN\_MODULE3, value); // spi, rc\_pin, pin\_value #if AINSER\_NUM\_MODULES \> 3 # error "CS Line for more than 2 modules not prepared yet - please enhance here!" #endif }

and ainser.h:

// Which RC pin of the SPI port should be used for the third module // allowed values: 0 or 1 for SPI0 (J16:RC1, J16:RC2), 0 for SPI1 (J8/9:RC), 0 or 1 for SPI2 (J19:RC1, J19:RC2) #ifndef AINSER\_SPI\_RC\_PIN\_MODULE3 #define AINSER\_SPI\_RC\_PIN\_MODULE3 2 #endif

and mios32_spi,h
 

#define MIOS32\_SPI2\_RCLK1\_PORT GPIOA // RC1 #define MIOS32\_SPI2\_RCLK1\_PIN GPIO\_Pin\_15 #define MIOS32\_SPI2\_RCLK1\_AF { GPIO\_PinAFConfig(GPIOA, GPIO\_PinSource15, GPIO\_AF\_SPI3); } // only relevant for slave mode #define MIOS32\_SPI2\_RCLK2\_PORT GPIOB // RC2 #define MIOS32\_SPI2\_RCLK2\_PIN GPIO\_Pin\_8 #define MIOS32\_SPI2\_RCLK2\_AF { } #define MIOS32\_SPI2\_RCLK3\_PORT GPIOC // RC3 #define MIOS32\_SPI2\_RCLK3\_PIN GPIO\_Pin\_1 #define MIOS32\_SPI2\_RCLK3\_AF { }

#else MIOS32\_SPI2\_RCLK1\_AF; MIOS32\_SPI2\_RCLK2\_AF; MIOS32\_SPI2\_RCLK3\_AF; MIOS32\_SPI2\_SCLK\_AF; MIOS32\_SPI2\_MISO\_AF; MIOS32\_SPI2\_MOSI\_AF; if( slave ) { // SCLK and DOUT are inputs assigned to alternate functions GPIO\_InitStructure.GPIO\_Mode = GPIO\_Mode\_AF; GPIO\_InitStructure.GPIO\_Pin = MIOS32\_SPI2\_SCLK\_PIN; GPIO\_Init(MIOS32\_SPI2\_SCLK\_PORT, &GPIO\_InitStructure); GPIO\_InitStructure.GPIO\_Pin = MIOS32\_SPI2\_MOSI\_PIN; GPIO\_Init(MIOS32\_SPI2\_MOSI\_PORT, &GPIO\_InitStructure); // RCLK (resp. CS) are configured as inputs as well GPIO\_InitStructure.GPIO\_Mode = GPIO\_Mode\_AF; GPIO\_InitStructure.GPIO\_Pin = MIOS32\_SPI2\_RCLK1\_PIN; GPIO\_Init(MIOS32\_SPI2\_RCLK1\_PORT, &GPIO\_InitStructure); GPIO\_InitStructure.GPIO\_Pin = MIOS32\_SPI2\_RCLK2\_PIN; GPIO\_Init(MIOS32\_SPI2\_RCLK2\_PORT, &GPIO\_InitStructure); GPIO\_InitStructure.GPIO\_Pin = MIOS32\_SPI2\_RCLK3\_PIN; GPIO\_Init(MIOS32\_SPI2\_RCLK3\_PORT, &GPIO\_InitStructure); // DOUT is output assigned to alternate function GPIO\_InitStructure.GPIO\_Mode = GPIO\_Mode\_AF; GPIO\_InitStructure.GPIO\_Pin = MIOS32\_SPI2\_MISO\_PIN; GPIO\_Init(MIOS32\_SPI2\_MISO\_PORT, &GPIO\_InitStructure); } else { // SCLK and DIN are inputs GPIO\_InitStructure.GPIO\_Mode = GPIO\_Mode\_AF; GPIO\_InitStructure.GPIO\_Pin = MIOS32\_SPI2\_SCLK\_PIN; GPIO\_Init(MIOS32\_SPI2\_SCLK\_PORT, &GPIO\_InitStructure); GPIO\_InitStructure.GPIO\_Pin = MIOS32\_SPI2\_MOSI\_PIN; GPIO\_Init(MIOS32\_SPI2\_MOSI\_PORT, &GPIO\_InitStructure); // RCLK (resp. CS) are configured as inputs as well GPIO\_InitStructure.GPIO\_Mode = GPIO\_Mode\_OUT; GPIO\_InitStructure.GPIO\_Pin = MIOS32\_SPI2\_RCLK1\_PIN; GPIO\_Init(MIOS32\_SPI2\_RCLK1\_PORT, &GPIO\_InitStructure); GPIO\_InitStructure.GPIO\_Pin = MIOS32\_SPI2\_RCLK2\_PIN; GPIO\_Init(MIOS32\_SPI2\_RCLK2\_PORT, &GPIO\_InitStructure); GPIO\_InitStructure.GPIO\_Pin = MIOS32\_SPI2\_RCLK3\_PIN; GPIO\_Init(MIOS32\_SPI2\_RCLK3\_PORT, &GPIO\_InitStructure); // DIN is input with pull-up GPIO\_InitStructure.GPIO\_Mode = GPIO\_Mode\_AF; GPIO\_InitStructure.GPIO\_PuPd = GPIO\_PuPd\_UP; GPIO\_InitStructure.GPIO\_Pin = MIOS32\_SPI2\_MISO\_PIN; GPIO\_Init(MIOS32\_SPI2\_MISO\_PORT, &GPIO\_InitStructure); }

#else switch( rc\_pin ) { case 0: MIOS32\_SYS\_STM\_PINSET(MIOS32\_SPI2\_RCLK1\_PORT, MIOS32\_SPI2\_RCLK1\_PIN, pin\_value); break; case 1: MIOS32\_SYS\_STM\_PINSET(MIOS32\_SPI2\_RCLK2\_PORT, MIOS32\_SPI2\_RCLK2\_PIN, pin\_value); break; case 2: MIOS32\_SYS\_STM\_PINSET(MIOS32\_SPI2\_RCLK3\_PORT, MIOS32\_SPI2\_RCLK3\_PIN, pin\_value); break; default: return -4; // unsupported RC pin } break; #endif

In the NGC I have:

AINSER n=1 enabled=1 cs=2 num\_pins=1

and nothing happens. Which part do I overlook for adding a CS?

Thanks!
Chris

Hello Chris

For AINSER8 you have to define muxed=0 at NGC because it’s set to 1 by default, but not sure it’s your issue here

Can I ask for what reason you need more lines? because you already have two line (if not using AOUT) for 16ch

Also it may be a better workaround to use a muxed MCP3202 for 16ch or MCP3204 for 32ch, I suspect it will request less change at soft side…

I have this in mind since time, but don’t start yet…for potential project that need intermediate ADC count and to gain room compared to an AINSER64 with disabled channels.

Best

Zam

I just have a deeper look even if i’m not confident with code…

pin C1 is already used at J5, maybe you have to deactivate/remove something in the code, also it’s the 32F4 ADC

Why don’t you use a free pin at j10 ?

Best

Zam

10 hours ago, Zam said:

Hello Chris

Hi Zam! Thanks for your reply.

10 hours ago, Zam said:

For AINSER8 you have to define muxed=0 at NGC because it’s set to 1 by default, but not sure it’s your issue here

I’ve tried that without success.

10 hours ago, Zam said:

Can I ask for what reason you need more lines?

Yes. I prefer having more traces (=not muxed) instead of having less traces and more parts (=muxed). I want to get rid of HC595 and 4051.
In my application I need about 20 analog inputs. So, unfortunately 16ch. are not enough.

9 hours ago, Zam said:

pin C1 is already used at J5, maybe you have to deactivate/remove something in the code, also it’s the 32F4 ADC

I thought that too. But I comment out those lines. Also I did a double check I took these lines from mios32_spi.h:

#define MIOS32\_SPI2\_RCLK1\_PORT GPIOA // RC1 #define MIOS32\_SPI2\_RCLK1\_PIN GPIO\_Pin\_15 #define MIOS32\_SPI2\_RCLK1\_AF { GPIO\_PinAFConfig(GPIOA, GPIO\_PinSource15, GPIO\_AF\_SPI3); } // only relevant for slave mode #define MIOS32\_SPI2\_RCLK2\_PORT GPIOB // RC2 #define MIOS32\_SPI2\_RCLK2\_PIN GPIO\_Pin\_8 #define MIOS32\_SPI2\_RCLK2\_AF { } #define MIOS32\_SPI2\_RCLK3\_PORT GPIOC // RC3 #define MIOS32\_SPI2\_RCLK3\_PIN GPIO\_Pin\_1 #define MIOS32\_SPI2\_RCLK3\_AF { }

and changed the pin for RC1 to PC1 like this:

#define MIOS32\_SPI2\_RCLK1\_PORT GPIOC // RC1 #define MIOS32\_SPI2\_RCLK1\_PIN GPIO\_Pin\_1 #define MIOS32\_SPI2\_RCLK1\_AF { GPIO\_PinAFConfig(GPIOC, GPIO\_PinSource1, GPIO\_AF\_SPI3); } // only relevant for slave mode #define MIOS32\_SPI2\_RCLK2\_PORT GPIOB // RC2 #define MIOS32\_SPI2\_RCLK2\_PIN GPIO\_Pin\_8 #define MIOS32\_SPI2\_RCLK2\_AF { } #define MIOS32\_SPI2\_RCLK3\_PORT GPIOC // RC3 #define MIOS32\_SPI2\_RCLK3\_PIN GPIO\_Pin\_1 #define MIOS32\_SPI2\_RCLK3\_AF { }

And this is working great (of course with cs=0 in the NGC-file). So I don’t think that PC1 is somehow “blocked” for this application. 

It can’t be to hard to add more CS. I think I just overlook something…

Hello Chris

If PC1 work for CS 1 the pin configuration should be ok

21 hours ago, FantomXR said:

and ainser.h:

// Which RC pin of the SPI port should be used for the third module // allowed values: 0 or 1 for SPI0 (J16:RC1, J16:RC2), 0 for SPI1 (J8/9:RC), 0 or 1 for SPI2 (J19:RC1, J19:RC2) #ifndef AINSER_SPI_RC_PIN_MODULE3 #define AINSER_SPI_RC_PIN_MODULE3 2 #endif

Are you sure about the pin value here?

 

also did you define modules number ? (ainser.h)

|   |

// Maximum number of AINSER modules (1..255) // (Number of modules can be changed via soft-configuration during runtime.) #ifndef AINSER\_NUM\_MODULES #define AINSER\_NUM\_MODULES 1 #endif

and ainser.c

|   |

///////////////////////////////////////////////////////////////////////////// // 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 #if AINSER\_NUM\_MODULES \> 2 # error "CS Line for more than 2 modules not prepared yet - please enhance here!" #endif } return -1; }

Best

Zam

2 hours ago, Zam said:

Are you sure about the pin value here?

No but I followed up the logic in the code above:

// Which RC pin of the SPI port should be used for the first module // allowed values: 0 or 1 for SPI0 (J16:RC1, J16:RC2), 0 for SPI1 (J8/9:RC), 0 or 1 for SPI2 (J19:RC1, J19:RC2) #ifndef AINSER\_SPI\_RC\_PIN\_MODULE1 #define AINSER\_SPI\_RC\_PIN\_MODULE1 0 #endif // Which RC pin of the SPI port should be used for the second module // allowed values: 0 or 1 for SPI0 (J16:RC1, J16:RC2), 0 for SPI1 (J8/9:RC), 0 or 1 for SPI2 (J19:RC1, J19:RC2) #ifndef AINSER\_SPI\_RC\_PIN\_MODULE2 #define AINSER\_SPI\_RC\_PIN\_MODULE2 1 #endif // Which RC pin of the SPI port should be used for the third module // allowed values: 0 or 1 for SPI0 (J16:RC1, J16:RC2), 0 for SPI1 (J8/9:RC), 0 or 1 for SPI2 (J19:RC1, J19:RC2) #ifndef AINSER\_SPI\_RC\_PIN\_MODULE3 #define AINSER\_SPI\_RC\_PIN\_MODULE3 2

 

2 hours ago, Zam said:

also did you define modules number ? (ainser.h)

Not in ainser.h, but in the mio32_config.h with:
 

// enable three AINSER modules #define AINSER\_NUM\_MODULES 3

 

2 hours ago, Zam said:

and ainser.c

Sure! I did this:

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\_SPI\_RC\_PinSet(AINSER\_SPI, AINSER\_SPI\_RC\_PIN\_MODULE3, value); // spi, rc\_pin, pin\_value #if AINSER\_NUM\_MODULES \> 3 # error "CS Line for more than 2 modules not prepared yet - please enhance here!" #endif }

 

10 minutes ago, FantomXR said:

No but I followed up the logic in the code above:

// Which RC pin of the SPI port should be used for the first module // allowed values: 0 or 1 for SPI0 (J16:RC1, J16:RC2), 0 for SPI1 (J8/9:RC), 0 or 1 for SPI2 (J19:RC1, J19:RC2) #ifndef AINSER_SPI_RC_PIN_MODULE1 #define AINSER_SPI_RC_PIN_MODULE1 0 #endif // Which RC pin of the SPI port should be used for the second module // allowed values: 0 or 1 for SPI0 (J16:RC1, J16:RC2), 0 for SPI1 (J8/9:RC), 0 or 1 for SPI2 (J19:RC1, J19:RC2) #ifndef AINSER_SPI_RC_PIN_MODULE2 #define AINSER_SPI_RC_PIN_MODULE2 1 #endif // Which RC pin of the SPI port should be used for the third module // allowed values: 0 or 1 for SPI0 (J16:RC1, J16:RC2), 0 for SPI1 (J8/9:RC), 0 or 1 for SPI2 (J19:RC1, J19:RC2) #ifndef AINSER_SPI_RC_PIN_MODULE3 #define AINSER_SPI_RC_PIN_MODULE3 2

Ok, the logic is “0, 1 or 2 for SPI2 (J19:RC1, J19:RC2, J5A:A0(nowRC3) )”, I have something else(wrong) in mind sorry.

 

I’m afraid I can’t help more on this, miss some skill, let wait for a programmer

Best

Zam

11 minutes ago, Zam said:

Ok, the logic is “0, 1 or 2 for SPI2 (J19:RC1, J19:RC2, J5A:A0(nowRC3) )”, I have something else(wrong) in mind sorry.

This seems to be a good hint! Thanks!

Maybe  could guide us in the right direction! :slight_smile:

You don’t need to enhance mios32_spi, just control the additional pin directly from AINSER_SetCs

E.g. let’s assume that J10.D0 is unused so far, then add to AINSER_Init():

MIOS32\_BOARD\_J10A\_PinInit(0, MIOS32\_BOARD\_PIN\_MODE\_OUTPUT\_PP);

and to AINSER_SetCs:

case 2: return MIOS32\_BOARD\_J10\_PinSet(0, value);

Best Regards, Thorsten.

Thanks for chiming in! 

Is it really so easy? :slight_smile: Thanks! I’ll try it!!

14 hours ago, TK. said:

E.g. let’s assume that J10.D0 is unused so far, then add to AINSER_Init():

Dear TK,

I undo all changes and added the lines as you suggested. Unfortunately I can not get it working.

I edited the ainser.h like this:

s32 AINSER\_Init(u32 mode) { MIOS32\_BOARD\_J10\_PinInit(0, MIOS32\_BOARD\_PIN\_MODE\_OUTPUT\_PP); 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 // 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; } [] 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(0, value); #if AINSER\_NUM\_MODULES \> 3 # error "CS Line for more than 2 modules not prepared yet - please enhance here!" #endif }

But when I now connect the Chipselect to PE8, which is D0 on J10A, nothing happens.

Any idea?

Thanks,
Chris

Another modification in mbng_file_c.c is required where the number of CS lines is hardcoded (actually you should have seen the error message…)

I put an example which works at my side into the demo/mbng_ainser_with_3_cs branch, see: https://github.com/midibox/mios32/commit/ac6151ea7012e2b3e5e6a15575b4c4f92c8ffe2f

Best Regards, Thorsten.

 

Additional notes: could be that you rely on 5V output - in this case change MIOS32_BOARD_PIN_MODE_OUTPUT_PP to MIOS32_BOARD_PIN_MODE_OUTPUT_OD, and add a 1k pull-up to 5V to this pin.

And if J10A is already used for SCS inputs (standard), just take J10B.D0 (pin index #8)

Best Regards, Thorsten.

Thank you very much!

I’ll give it a try. 

Hey ,

I tried it without success. I copied the code from you into my firmware. 

My NGC file looks like this:

RESET\_HW AINSER n=1 enabled=1 num\_pins=1 cs=1 resolution=7bit AINSER n=2 enabled=1 num\_pins=1 cs=2 resolution=7bit

I have a potentiometer connected to the first analog input of the second and another one to the first input of the third module. The first module is not used at the moment. 

If I “set debug on” in the terminal, I see movements if I turn the potentiometer which is connected to the second module. Anyway I can not see anything when I turn the pot which is connected to the third module.

I’ve tried both PP and OD mode (with 1k pullup to 5V). I use PE6, which should lead to

MIOS32\_BOARD\_J10\_PinInit(14, MIOS32\_BOARD\_PIN\_MODE\_OUTPUT\_OD)

and

 case 2: return MIOS32\_BOARD\_J10\_PinSet(14, value);

Any ideas what I do wrong?

Dear ,

could you help on this? I have no clue why this is not working at my side but at yours.

 

Hi Chris,

Do you test it without the NG with a regular app first?
Can you share the code you change in MIOS32, whole AINSER files?

Best Bruno

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. 

ok. And physically, did you check the cs lines with the oscillo? you should see a periodic pulse.

Yes. I did. I see the pulses on the CS line.