Jump to content

Fast Scan Matrix Using Core32


robinfawell
 Share

Recommended Posts

Whilst reading ST Application Note AN2548 "Using the STM32F101xx and STM32F103xx DMA Controller" I found the section 4.3 that describes the use of GPIO ports as a 16 bit parallel input which can be transferred by DMA to SRAM.

See http://www.st.com/stonline/products/literature/an/13529.htm

I have Fatar key board that is velocity sensitive. To scan the key contacts I need to scan

88 X 2 = 176 contacts. This can be done with a matrix of 16 X 12 = 192 leaving a few spare.

It occurred to me that using either using 11 or 16 GPIO input pins and the output pins from

a Dout shift Register with 16 or 11 outputs I could matrix scan the keyboard contacts quickly.

To read the program example see http://www.st.com/mcu/familiesdocs-110.html

Look under Firmware STM32F10x_StdPeriph_Lib downoad the file and unzip.

I am wondering whether it is feasible to utilise the Core 32 J5 a)b)c) connections configured as 12 digital inputs with an additional 4 unused ports to make up the 16 parallel input. ( I have no need of analog inputs or outputs.)

It seems to me that if this is possible it would be faster than using Dins and Douts with SDIO

I have to admit that I have a lot to learn about MIOS32 and the STM32 and would appeciate any comments.

Would this method be fast enough for the application?

Thanks Robin

Edited by robinfawell
Link to comment
Share on other sites

  • 2 weeks later...

I have had no response as yet to my post about Fast Scan Matrix. I know that this is not a mainstream topic and that it was not written in a concise manner. Since writing the message I have spent a fair amount of time looking at the SVN Repository and various technical articles from the ST website.

I have also looked at the MIOS32 Functions with reference to DMA transfers and to SPI and SRIO. Some time has been spent looking at the Core32 circuits trying to see the possibilities for using the various GPIO input/outputs. There are only 16 each GPIOs under groups A B and C and a few in D.

There are two contiguous 8-bit bytes namely:

PA (0-3) from Connector J5b with PA (4-7) from connector J16

PB (8-9) using pins 61 and 62 and PB (10-15) using J27, J4 and J8/9

The GPIO group A is more convenient. It loses less utilities and the connections use only two connectors J5b and J16. J8/9 is preserved for DOUT.

This raises another point regarding J8/9. We are limited to only 16 SR for speed considerations. This means 16 DINs. For an 88 key velocity scanned system we need 8 X 22.

A solution might be to use J19 to drive a second DIN. (Use 11 DINs on each!)

All of the above begs the question. There is no MIOS function that I have found that can be used to connect a byte (in parallel) to the memory using DMA.

There is in the ST standard peripheral library STM32F10xgpio c and h. However there is no equivalent MIOS Function

Question: Is there any merit in providing this as a MIOS function?

I'm not able to do this and I realise that this would involve others in the task.

If this is task is judged to be too great or of little demand I accept the situation and go away and try to use SPI with DIN and DOUT.

I am retired and have a fair amount of free time and would be very willing to work with others to spend time to learn more about C programming and MIOS. I also have a new unused FATAR keybed.

Please let me have some comments.

Edited by robinfawell
Link to comment
Share on other sites

Robin,

have you done calculations/benchmarks/analysis to show that the conventional method of reading switch matrix's with MIOS32 is too slow for your application?

I guess if MIOS is to be augmented and the effort mustered then there has to be a reason beyond just a "faster is better" assumption. The analysis needs to reveal that the alternative approach is sufficiently superior to warrant proceeding.

As a keyboardist, I am familiar with the feeling that latency can never be low enough, but in fact somewhere around 6ms (or more!) is totally fine in regards to playing with feel. In other words at a certain level small changes become unnoticeable.

For example if it turns out that the alternative approach yields a latency of 4 rather than 5 milliseconds then one might not divert the effort in this direction.

I guess these are the considerations that run through my mind when reading this thread. Hope I don't sound negative! :-)

Link to comment
Share on other sites

Thanks Duggle

have you done calculations/benchmarks/analysis to show that the conventional method of reading switch matrix's with MIOS32 is too slow for your application?

No I have not done any of these calculations. My reason for raising the issue is based on considerations of processor resources. We have with the STM32 microprocessor a very fast processing speed and the advantage of DMA transfer. The MIOS functions of SPI and SRIO rely on serial data transfer, this relies on the use of DIN and DOUT and in order to use them we have to reduce the clock speed. By using parallel transfer we can eliminate the DIN SR element and reduce the amount of code required for the re-assembly of the original parallel data from the switches. Therefore both speed and code memory space are preserved and conserved respectively. However all the above comments will be fairly obvious.

For my own needs I am looking for a scanning system which will not require the processor for any synthesiser ability. I have in mind trying to equalise the unequal velocity from the black and white keys. (This is a subject that I raised some time ago in the forum.) I will rely on piano and organ sounds from softsynths ilke Pianotek or Truepiano run on a PC. The Black/white key adjustment will require additional code and will degrade the latency. Each black note velocity needs to be scaled by a factor of something like 0.9.

Whether or not my scanning needs can be met is not the only consideration. There may be other applications that that can benefit from a faster parallel data/in transfer albeit with the sacrifice of the ADC facility.

Robin

Link to comment
Share on other sites

Hi,

With your specific question, as the CORE32 uses the 64 pin version of the STM32, there are limited GPIO i/o pins available. As you would need all 16 pins of an available GPIO, I think you would struggle.

A quick looks shows that some of the pins used by PA are also shared by the USB port, the LCD interface uses part of PA and some of PC, PB is also used for the boot jumper, there are probably other conflicts and PA, PB and PC are the only fully available GPIO ports on the LQFP64 package.

As DIN/DOUT modules have been available for many years, I don't think that direct parallel i/o was much of a consideration when the CORE32 was designed.... One of the other packages (100 or 144 pin) would definitely make this possible (as these expose GPIO D, E, F and G) but would need a new PCB designing.....

With regard to reducing the clock speed to talk to DIN/DOUT modules, the SPI driver is DMA based so the lower speed of the SPI transfers shouldn't impact on the overall performance.

Cheers

Phil

Link to comment
Share on other sites

The usage of serial registers give us the advantage that remaining IOs are free for other purposes.

Since most of bigger applications get use of all available pins, SRIO is the first choice and therefore the standard. (*)

Scanning the SRIOs doesn't really take that much CPU time, as MIOS32 handles the (hardware) SPIs via DMA transfers in background. While the complete SRIO chain is scanned, the CPU is doing something else. Therefore the serial clock rate doesn't matter (I selected a slow clock rate to make the transfers more robust).

Only the propagation of pin changes to the application takes CPU time, but a handler for parallel IOs would have to do exactly the same!

Note that it is possible to call MIOS32_SRIO_ScanStart() from the application to scan the SRIO more frequently. This will require to remove the

MIOS32_SRIO_ScanStart(SRIO_ServiceFinish); call in vApplicationTickHook - I could add a #ifndef based switch if you want, so that this code doesn't need to be modified.

Instead you would enable this switch in your mios32_config.h file, and call MIOS32_SRIO_ScanStart from a timer function (-> MIOS32_TIMER) embedded into your app.c file at the desired frequency.

I don't see the need to integrate an alternative method into MIOS32, but nobody prevents you (or somebody else) from writing a driver for parallel scanning and to put it into $MIOS32_PATH/modules so that other applications can access it.

In difference to MIOS8, MIOS32 is very modular (e.g. it's possible to remove the software parts which scan the SRIO chains from the binary).

Or to disable the default scanning method and to do it on a different way (e.g. more frequently) as described above.

Everything which is special and not used by most of the applications should be located under $MIOS32_PATH/modules

This has the advantage that multiple solutions for the same "function(s)" can be provided and selected by the application.

You are writing that there isn't a MIOS32 equivalent to STM32F10xgpio c

This isn't completely true - because this driver provided by STM is already compiled into each application (the sources are here) so that you can already use these functions w/o Makefile modifications.

You are even able to re-use most of the example applications provided by STM for the first experiments if you remove the system initialization parts that are mostly located in the main.c file of these examples (because the system is initialized by MIOS32_SYS_Init)

Best Regards, Thorsten.

(*) another reason for using SRIO is, that they are working at 5V level instead of 3.3V, and that 74HC595 can drive multiple LEDs w/o loading the microcontroller.

This isn't relevant for your plans, but I think that I should highlight this to make clear why SRIO is better for most applications.

Link to comment
Share on other sites

Thank you Phil and Thorsten for your replies.

I am very grateful to both of you for putting the GPIO (Parallel data) ideas for fast scan matrix into perspective.

I agree with Phil that using the 64 pin device would be limited. The 100 pin STM32 would provide an extra GPIO 16 bit capability. To run the application without a SR would require the 144 pin device!

Thorsten has provided me some valuable thought on how to use the SRIO application. For the next few months I will make the Core 32 hardware and familiarise myself with the concepts. I have many questions on the STM32 MIOS32 and programming. Hopefully I can persevere and answer these myself.

Robin

Link to comment
Share on other sites

For my own needs I am looking for a scanning system which will not require the processor for any synthesiser ability. I have in mind trying to equalise the unequal velocity from the black and white keys. (This is a subject that I raised some time ago in the forum.) I will rely on piano and organ sounds from softsynths ilke Pianotek or Truepiano run on a PC. The Black/white key adjustment will require additional code and will degrade the latency. Each black note velocity needs to be scaled by a factor of something like 0.9.

Hi Robin,

Ive not heard of this. I gather that this is implemented inside midi keyboards by default and therefor not usually encountered unless one is implementing a midi keyboard?

Anyhow, I suspect that this is easier to code (and less cpu intensive) than you may think.

Assuming that the scanning/timing subsytem has detected a closure of contacts and has produced a timer value represents the velocity of the event, here's how I would code the velocity adjustment:

Assume that the 'note' has the same value as midi spec (i.e. note==0 is a "C"), and the 'time' is inversely proportional to the velocity.


const u8 BlackNotes[]={0,1,0,1,0,0,1,0,1,0,1,0}    /*lookup table: black notes per octave from a "C"*/


u32 AdjustBlackNoteVelocity(u8 note, u32 time){

 if (BlackNotes[note%12])  

   return (time*10)/9;	/*adjust for black notes*/

else 

	return time;		/*else dont adjust for white notes*/

}

I'm not sure where your at with your C language (you may refer back to this at a later time).

I can definitely say the processing overhead for this adjustment is negligible!

Cheers

[edit]

Whoops! the expression isn't right for the velocity scaling:

return time*(1/0.9); /*adjust for black notes*/

should be

return (time*10)/9; /*adjust for black notes*/

has been changed above.

By way of further explanation: Scaling the velocity down by 0.9 is the same as scaling the Velocity timer up by 1/0.9. We should stick with integer math so first we multiply by 10 then divide by 9. This is much more efficient than using floating point on the STM32 chip used for MIOS32.

[/edit]

Edited by Duggle
Link to comment
Share on other sites

Thanks again Duggle

I am very impressed by the simplicity of your code to adjust for black and white key differing velocity.

Here is the reference to the Doepfer keyboard controller. I raised the issue in Feb 2008 on the forum. See Page 13 of the manual. They use Wheel 1 to adjust the velocity parameter during POWER ON. I have no wheel in my setup and I see no point in introducing a pot just for this adjustment. Once the factor has been decided by experiment it can be fixed.

My link

I'm not sure where your at with your C language (you may refer back to this at a later time).

I am still struggling to understand the MIOS32 spi and srio functions and it will be some time before I start with the code. However your code will be incorporated when I get to the later stages.

Robin

Link to comment
Share on other sites

Once the factor has been decided by experiment it can be fixed.

Indeed, changing a constant, compiling and downloading a fresh build with MIOS Studio, is very quick and convenient. It sounds like the kind of adjustment that you wouldn't want to change once you got it right for the particular keybed youre using.

The best way, in my opinion, of learning this sort of stuff, is through direct interaction with the target (as well as reading). Take a sample MIOS32 app. Modify it in some trivial way, predict the outcome. Run it and see if the change you made works the way you envisaged. Have fun with this process.

As you begin to understand the software stack of MIOS32, the apps, and of course the C language itself, gradually alter things in more dramatic and useful ways.

I stress that the mindlessly simple programming exercises should not be bypassed, however, when you get the hang of things you can quickly move on....

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

×
×
  • Create New...