Also got me a new T4 @600mhz . Paul, @ pjrc done it again...
Electronics, Synth, Sound effects, Microcontrollers, , Digital signal processing,AVR, PIC, PIC32,ARM, etc
Showing posts with label DubWorks. Show all posts
Showing posts with label DubWorks. Show all posts
Friday, 23 August 2019
Update
New boards arrived for next dub siren/delay and EQ/Reverb combos
Also got me a new T4 @600mhz . Paul, @ pjrc done it again...
Also got me a new T4 @600mhz . Paul, @ pjrc done it again...
Friday, 20 July 2018
LCD PCD8544
After bitbanging a quick library, and some head scratching, i seemed to have solved all my problems for now...
Monday, 1 June 2015
Dub Siren For The Keyboard PLayer ( Code )
For the last post DUB SIREN FOR THE LIVE KEYBOARD PLAYER, all you need is an Arduino Midi Shield ( ( you should find a local distributor for all these) , an Arduino Uno, R3 preferably, and MIDI library ( I am using the Arduino_MIDI_Library_v4.2) along with this code. NO SOLDERING DONE !
#include <MIDI.h> // MIDI_CREATE_DEFAULT_INSTANCE(); #define PBMAX 8191 // defines for MIDI Shield components only #define POT 0 #define POT2 1 #define BUTTON1 2 #define BUTTON2 3 #define BUTTON3 4 #define LED 7 #define LED2 6 // #define SINSAMPLES 256 int sineData [SINSAMPLES]; bool ledOn = false; bool ledOn2 = false; unsigned int inc = 0; uint16_t noteIn = 0; uint16_t lastnote = 0; char off = 0; char lastplay = 0; //char drv = 0; // digital read variable void setup() { sine(); pinMode(LED, OUTPUT); pinMode(LED2, OUTPUT); pinMode(POT, INPUT); pinMode(POT2, INPUT); pinMode(BUTTON1, INPUT); // defines for MIDI Shield components only digitalWrite(LED2, HIGH); digitalWrite(LED, HIGH); digitalWrite(BUTTON1, HIGH); // MIDI.begin(); // Launch MIDI } void loop() { uint16_t average = noteIn; uint16_t anIn = analogRead(POT); char play = !(digitalRead(BUTTON1)); if (lastplay != play) { if (play == 0) off = 1; } lastplay = play; noteIn = analogRead(POT2); average = (average + noteIn) >> 1; uint8_t note = average >> 3; if (play == 1) { if (lastnote != note) { MIDI.sendPitchBend(0, 1);//reset pitch bend delay(10); MIDI.sendNoteOff(lastnote, 0, 1); // Stop the note delay(10); MIDI.sendNoteOn(note, 127, 1); // Send a Note (pitch , velo 127 on channel 1) lastnote = note; } else { lastnote = note; } int smpl = sineData[inc]; int var = (smpl - PBMAX); // this calculation can be avoided MIDI.sendPitchBend(var, 1); delay(10); ledOn = !ledOn; digitalWrite(LED, ledOn); inc++; inc += (anIn >> 4); if (inc >= SINSAMPLES) { inc -= SINSAMPLES; ledOn2 = !ledOn2; digitalWrite(LED2, ledOn2); } } if (play == 0) { if (off == 1) { MIDI.sendPitchBend(0, 1);//reset pitch bend delay(10); MIDI.sendNoteOff(lastnote, 0, 1); // Stop the note inc = 0; lastnote = 0; digitalWrite(LED2, HIGH); digitalWrite(LED, HIGH); off = 0; } } } void sine () { int i; int b; for (i = 0; i < SINSAMPLES; i++) { b = PBMAX * sin((2 * PI / SINSAMPLES) * i); b += PBMAX; sineData [i] = b; } }
Monday, 4 August 2014
Arduino miniDUBsiren - compact pocket-sized dub siren
While i have to wait for some bits && pots to finish the other prototype, i decided to go back to Arduino Uno and do something quick; Ended up creating the Pocket sized miniDubSiren.
* I have even seen some 3D-printed cases for it here .
LCD Keypad Shield, Arduino Uno and you'd only have to worry about filtering the output. Cant get easier than that .
So, that makes it a shirt-pocket sized Dub Siren.
LFO is linear, for simplicity.
LCD displays top frequency/range and rate of LFO ( both with a minus - and a plus+ button for selection) and when sound is ON (triggered by the SELECT button: toggle action - one click ON , another OFF).
Also made a quick sounds FX generator for it, code to come soon ( even a "slightly slanted" sound wave LCD Char to go with it).
It was nice to work around the limitations of the available buttons and the frequency range in the tone function. Parameters can be changed during play, which creates some nice musical artifacts . A nice little toy.
While at it, developed a nice way of creating menus with this shield( despite not using it in this particular project, where simplicity was needed).
Button arrangement is : Trigger Toggle=Select ; Freq= left/right ; Rate LFO=up/down .
//Sample using LiquidCrystal library
#include < LiquidCrystal.h >
//
byte wavform2[8] = {
B01100,
B10001,
B10001,
B00001,
B00000,
B00000,
B00000,
};
byte wavform[8] = {
B00000,
B00000,
B00000,
B00001,
B10001,
B10010,
B01100,
};
/*******************************************************
miniDubSiren by
Dubworks- Aug 2014
LCD KeyPad Code original by
Mark Bramwell- Jul 2010
********************************************************/// select the pins used on the LCD panel
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
uint16_t i = 100; // tone minimum
boolean play = false;
boolean down = false;
uint16_t topFreq = 864;
uint16_t rate = 0;
int outPin = 3; // define number of output pin
// define some values used by the panel and buttons
int lcd_key = 0;
int adc_key_in = 0;
#define btnRIGHT 0
#define btnUP 1
#define btnDOWN 2
#define btnLEFT 3
#define btnSELECT 4
#define btnNONE 5
// read the buttons
int read_LCD_buttons()
{
adc_key_in = analogRead(0); // read the value from the sensor
// my buttons when read are centered at these valies: 0, 144, 329, 504, 741
// we add approx 50 to those values and check to see if we are close
if (adc_key_in > 1000) return btnNONE; // We make this the 1st option for speed reasons since it will be the most likely result
//
if (adc_key_in < 50) return btnRIGHT;
if (adc_key_in < 250) return btnUP;
if (adc_key_in < 450) return btnDOWN;
if (adc_key_in < 650) return btnLEFT;
if (adc_key_in < 850) return btnSELECT;
return btnNONE; // when all others fail, return this...
}
void setup()
{
// Serial.begin(9600);
pinMode(outPin, OUTPUT);
lcd.begin(16, 2); // start the library
lcd.createChar(0, wavform );
lcd.createChar(1, wavform2 );
lcdInit();
}
void loop()
{
lcd_key = read_LCD_buttons(); // read the buttons
switch (lcd_key) // depending on which button was pushed, we perform an action
{
case btnRIGHT:
{
topFreq += 13;
if (topFreq > 4000)
topFreq = 4000;
lcdFnct();
delay(40);
break;
}
case btnLEFT:
{
if (topFreq < 100)
topFreq = 100;
else
topFreq -= 13 ;
lcdFnct();
delay(40);
break;
}
case btnUP:
{
rate += 1 ;
if (rate > 150) {
rate = 150;
}
lcdFnct();
delay(40);
break;
}
case btnDOWN:
{
if (rate < 1)
rate = 0;
else
rate -= 1 ;
delay(40);
lcdFnct();
break;
}
case btnSELECT:
{
play = !play;
if (play == false) {
i = 100;
noTone(3);
delay(50);
}
delay(100);
lcdFnct();
break;
}
case btnNONE:
{
break;
}
}
if (play == true) {
tone(outPin, i);
delay(5); // !!
}
else if (play == false) {
i = 100;
noTone(3);
delay(50);
}
if (down == false) {
i++;
i += rate;
}
else if (down == true) {
i--;
i -= rate;
}
if (i > topFreq) {
down = true;
i = topFreq;
}
else if (i < 180) {
down = false;
i = 180;
}
}
void lcdFnct() {
lcd.clear();
lcd.setCursor(0, 0); //
lcd.print("F= ");
lcd.setCursor(4, 0);
lcd.print(topFreq);
lcd.setCursor(0, 1);
lcd.print("R= ");
lcd.setCursor(4, 1);
lcd.print(rate);
if (play == 1) {
lcd.setCursor(10, 0);
lcd.write(byte(0)); //
lcd.setCursor(11, 0);
lcd.write(byte(1));
lcd.setCursor(10, 1);
lcd.print("ON");
}
}
void lcdInit() {
lcd.setCursor(0, 0);
lcd.print(" = DubWorks = "); //
lcd.setCursor(0, 1);
lcd.print(" mini Dub Siren ");
// scroll 12 positions to the right
// to move it offscreen left:
for (int positionCounter = 0; positionCounter < 12; positionCounter++) {
// scroll one position left:
lcd.scrollDisplayLeft();
// wait a bit:
delay(50);
}
// scroll 26 positions to the right
// to move it offscreen right:
for (int positionCounter = 0; positionCounter < 26; positionCounter++) {
// scroll one position right:
lcd.scrollDisplayRight();
// wait a bit:
delay(50);
}
// scroll 14 positions to the left
// to move it back to center:
for (int positionCounter = 0; positionCounter < 14; positionCounter++) {
// scroll one position left:
lcd.scrollDisplayLeft();
// wait a bit:
delay(50);
}
// delay at the end of the full loop:
delay(500);
}
3D-Printed case : http://apcmag.com/arduino-project-digital-clock.htm
LCD KEYPAD : http://www.dfrobot.com/wiki/index.phptitle=Arduino_LCD_KeyPad_Shield_(SKU:_DFR0009)
Labels:
Arduino,
Dub,
DubWorks,
fx,
mini dub siren,
miniDUBsiren,
open source
Monday, 2 December 2013
Saturday, 12 October 2013
options to attack envelope
Ill keep it simple and share the graphic of the differences and options. Ramp legend is a linear ramp-up attack.
Following the example of period 128, we'd get : attack=32; decay=22; sustain=42; rlease=32.
the picture below is related to the ATTACK stage only.
void adsr_calculation() { uint16_t b = period >> 1; // These operations help us achieve a cheap aproximation uint16_t a = b >> 3; // of division by 3 (?!) with a loss of bits/precision, but weighed // enough for what we need, regarding the fact we wrap-up with a modulo operator for
// the last variable sustain- a "greatest-integer function" of sorts .
/* By combining the terms in an obvious manner we can reduce the number of operations: a = (period >> 2) + (period >> 4) b += (b >> 4) b += (b >> 8) b += (b >> 16) There are more exciting ways to calculate division and remainders.b * 3 = shift left 1 bit and then add b
*/
attack = period >> 2;
decay = (a <<1)+(a>>1)+(a>>2);
rlease = period >> 2;
sustain = period -(attack + rlease + decay);
// roughly the same as
// sustain = period %(attack + rlease + decay); led =!led; //toggle led /* Serial.println ("a"); Serial.println (a); Serial.println ("b"); Serial.println (b); Serial.println ("attack"); Serial.println (attack); Serial.println ("decay"); Serial.println (decay); Serial.println ("sustain"); Serial.println (sustain); Serial.println ("rlease"); Serial.println (rlease); */ }
Regarding REAL division by three
// Crazy as this might sound, but the method below indeed does divide by 3. // All it needs for doing so is a single 64 bit multiplication and a shift // (multiplications might be 3 to 4 times faster than divisions // on your CPU). In a 64 bit application this code will be a lot faster than // in a 32 bit application (in a 32 bit application multiplying two 64 bit // numbers take 3 multiplications and 3 additions on 32 bit values) // - however, it might be still faster than a division on a 32 bit machine. // It only works for constant numbers. Why ?! // You always need to know the magic number (here 0xaaaaaaab,
// 0b1010 1010 1010 1010 1010 1010 1010 1011 ; 2,863,311,531 decimal)
// and the correct operations after the multiplication (shifts and/or additions
// in most cases)and both is different depending on the number you want to divide// by (and to calculate both take too much CPU time, on the fly (that would be
// slower than hardware division). However, it's easy for a compiler to
// calculate these during compile time
static inline uint32_t div3 ( uint32_t bdivided ) { return (uint32_t)(((uint64_t)0xaaaaaaabULL * bdivided) >> 33); } void setup() { // put your setup code here, to run once: Serial.begin (115200); } void loop() { // put your main code here, to run repeatedly: uint32_t test=1000; uint32_t avar=div3(test); Serial.println(avar); delay(500); }
Monday, 30 September 2013
Symmetry of waves in wavetable generators and the differences and implications..
The reason why im sharing these wave table generators is because of the fact that some of the ones i found didnt comply with the symmetry of waveforms ( Take the above graph as the correct reference of how they should relate !).
Why is this so important ?! Hmmm, try a guess ?! * Ill leave it to the reader to guess why, as an exercise, as its quite obvious !
Instead they have the period of the Sawtooth wave starting as 0, when it should be starting at the DC-offset value ( 2047 for a 12-bits DAC, for example).
So, it was starting at PI, instead of zero. Triangle wave were starting at 1.5 PI( which both differences are easy and dirty ways of doing it, but this time didnt satisfy my needs, where i need something correct according to the symmetry for interaction and calculation purposes.
So this was my quick solution to it. I hope to maybe improve on this as soon as i can spare a moment.
Also intend to do a see-sawtooth ( with more decrement intermediate stages) generator.
// create the individual samples for our Sawtooth-wave table void createSawTable() { Serial.println(" "); Serial.println("Saw table"); for(uint32_t nIndex = 0;nIndex < WAVE_SAMPLES;nIndex++) { // normalised to 12 bit range 0-4095 nSawTable[nIndex] = nIndex * 8; // == nIndex + (4096/512 == 8);because it // never reaches 512 Serial.println(nSawTable[nIndex]); } } // create the individual samples for our triangle-wave tablevoid createTriangleTable() { //Serial.println(" "); //Serial.println("triangle table"); for (uint32_t nIndex = 0; nIndex < WAVE_SAMPLES; ++ nIndex) { if( nIndex <=128 ){ nTriangleTable[nIndex] = nIndex * 16 + 2047 ; //+offset //Serial.println(nTriangleTable[nIndex]); //Serial.println(nIndex); } else if(nIndex >128 && nIndex < 384 ) { nTriangleTable[nIndex] = 4095-((nIndex-128)*16); //Serial.println(nTriangleTable[nIndex]); //Serial.println(nIndex); } else if (nIndex == 384){ nTriangleTable[nIndex] = 0;//Serial.println(nTriangleTable[nIndex]);void createSq_WaveTable() { Serial.println(" "); Serial.println("Square Wave table"); for(uint32_t nIndex = 0;nIndex < WAVE_SAMPLES;nIndex++) { // despite using numbers directly here, keep in mind its related to // WAVE_SAMPLES as a variable // if(nIndex < (WAVE_SAMPLES/2)) if( nIndex <256 ){ nSq_WaveTable[nIndex] = 4095 ; // Serial.println(nSq_WaveTable[nIndex]); } else if(nIndex >=256 && nIndex <= WAVE_SAMPLES ) { nSq_WaveTable[nIndex] =0; Serial.println(nSq_WaveTable[nIndex]); } } }//Serial.println(nIndex);} else if (nIndex > 384){ nTriangleTable[nIndex] = (nIndex-384)*16; //Serial.println(nTriangleTable[nIndex]); //Serial.println(nIndex); } } }
Quick-Benchmark on LUT / sine wavetable generation with DUE
During my research for my "secret" project i decided to benchmark sine wave and sine wave LOOK UP TABLE's generation, the different methods and approximations, both mathematically and methods for discrete time systems like uC's.
For research purposes, and initial development i have been actually using the Arduino Due, due to its ease of testing and debugging initial stages of ideas , for which the DAC helps a lot.
I been guessing already some limitations speed performance (considering what i want to achieve) in later stages, but for now it has been a brilliant tool.
As the ARM in the DUE was a new thing to me, and to shorten the time, i had to look around for some initial guidance regarding the registers/tmers and interrupts in order to get started.
In that sense Duane B.'s work and Groovuino's with their QUICK 'N' DIRTY synth were invaluable.
At the moment, im quite advanced, and it came to mind to use some "live" sine calculations for some other purposes other than the Pure-tone sinewave itself ( complex sinusoids and subsequent modulation, etc).
So decided to benchmark both thei sinewavetable generation and a somewhat adapted version i used previously.
And using the millis() in Arduino, there was almost a halving of time taken to generate 512 samples of wavetable.
Duane's version took 27/28 Ms contrasting with 16/17 Ms.
Now, while this is not relevant for their synths, it is to me. Specially when im trying to squeeze as many cycles as i can already with the arduino Due, due to all the layers that the "easy way" places in between, massively contributing to the decrease in performance of speed/time. :)
Its easy to see where the optimization is, slightly reducing the cycles needed !
Some surprises soon, and some more on this as well...
Table_1 test code
#define WAVE_SAMPLES 512 long previousMillis = 0; // default int is 32 bit, in most cases its best to use uint32_t but for large arrays its better to use smaller // data types if possible, here we are storing 12 bit samples in 16 bit ints #define offset 2047 // In this case is the same as the Amplitude uint16_t sin_data[WAVE_SAMPLES]; float w ; // ψ float yi ; float phase; int sign_samp; int i; void create2nd_sine (){ // Serial.println(" "); // Serial.println("Sine table2"); w=(2.0 * PI)/WAVE_SAMPLES; for (i = 0; i <= 511; i++) { yi= offset*sin(phase); // Offset is the same as the Amplitude phase=phase+w;
sign_samp=offset+yi; // dc offset translated for a 12 bit DAC sin_data[i]=sign_samp; // write value into array // Serial.println(i); // Serial.println(sin_data[i]); } } // void setup() { // put your setup code here, to run once: Serial.begin(9600); } void loop() { // put your main code here, to run repeatedly: unsigned int result; unsigned long currentMillis = millis(); create2nd_sine (); result=currentMillis - previousMillis; previousMillis = currentMillis; Serial.println(result); }Table_2 test code
// Duane's
#define WAVE_SAMPLES 512 // default int is 32 bit, in most cases its best to use uint32_t but for large arrays its better to use smaller // data types if possible, here we are storing 12 bit samples in 16 bit ints uint16_t nSineTable[WAVE_SAMPLES]; long previousMillis = 0; void createSineTable() { // Serial.println(" "); // Serial.println("Sine table"); for(uint32_t nIndex = 0;nIndex < WAVE_SAMPLES;nIndex++) { // normalised to 12 bit range 0-4095 nSineTable[nIndex] = (uint16_t) (((1+sin(((2.0*PI)/WAVE_SAMPLES)*nIndex))*4095.0)/2); // Serial.println(nIndex); // Serial.println(nSineTable[nIndex]); } } // void setup() { // put your setup code here, to run once: Serial.begin(9600); } void loop() { // put your main code here, to run repeatedly: unsigned int result; unsigned long currentMillis = millis(); createSineTable(); result=currentMillis - previousMillis; previousMillis = currentMillis; Serial.println(result); }For a more detailed explanation of a sinewave generator, and a few diff methods, check below link
(1) http://dubworks.blogspot.co.uk/p/blog-page.html
Thursday, 8 August 2013
PIC32- Variable type defs
One of the main concerns about migrating/working with other type of uC’s ( 8 bits like AVR & PIC, or 16 like PIC24 or the DSC’s dsPIC family), was how the 32 bit architecture will influence any previous code i might have regarding variable type definitions.
As its based on the GCC compiler, it is prepared for both ANSI with CCI compliance. Ill keep with the basics out of type defs.
The ANSI C Standard does indicate minimum requirements for these
types, as specified in .
* For more info on compiler compliance check the XC32 Compiler User guide in chapter “2.4.6 Sizes of Type
From researching the include files, one can get this info :
/* 7.18.1.1 Exact-width integer types */
typedef __signed char __int8_t;
typedef unsigned char __uint8_t;
typedef short int __int16_t;
typedef unsigned short int __uint16_t;
typedef int __int32_t;
typedef unsigned int __uint32_t;
#ifdef __COMPILER_INT64__
typedef __COMPILER_INT64__ __int64_t;
typedef __COMPILER_UINT64__ __uint64_t;
#elif defined(_LP64)
typedef long int __int64_t;
typedef unsigned long int __uint64_t;
#else
/* LONGLONG */
__extension__
typedef long long int __int64_t;
/* LONGLONG */
__extension__
typedef unsigned long long int __uint64_t;
#endif
#define __BIT_TYPES_DEFINED__
Which gives us :
// MPLAB C32 range of Signed values
char c; // -128 to 127
short s; // -32,768 to 32,767
int i; // -2,147,483,648 to 2,147,483,647
long l; // -2,147,483,648 to 2,147,483,647
Of course, we also have the unsigned attribute:
// MPLAB C32 range of Unsigned values
unsigned char c; // 0 to 255
unsigned short s; // 0 to 65,535
unsigned int i; // 0 to 4,294,967,295
unsigned long l; // 0 to 4,294,967,295
For int, 4 bytes in the physical RAM is used.
So, if we do not have to use int and long, we should use char.
To hold one char variable, C32 compiler will use only 8 bits.
Another possibility is short type, which will use 16 bits to hold one short variable
PIC32‘s ALU is performing all arithmetic operations in the same number of cycles for 32-bit, 16-bit or 8-bit integers, which turns the variable long into just a synonym of the basic integer type int.
It is ok from performance point of view, but it comes with a price.
The only limiting factor, preventing us from always using 32-bit integers , is the consideration of the internal resources , and in this case the RAM memory
* keep the size of your variables to the minimum necessary; operating on bytes versus word can make a big difference in terms of code compactness/efficiency.
If really a large range of values is needed, we can use 64-bit types
// C32 range of 64-bit type values
long long l; // ranges from -2 to the power of 63 to +2 to the power of 63-1
unsigned long long l; // ranges from 0 to +2 to the power of 64
// C32 range of Floating point type values
float f; // 32-bit floating point
double d; // 64-bit floating point
long double d; // 64-bit floating point, synonym of double
The long long integer type offers 64-bit support and requires 8 bytes of memory; So, we can expect a small performance decrease for using long long integers.
Ill leave several excerpts from the header files...
/* 7.18.1.1 Exact-width integer types */
typedef __signed char __int8_t;
typedef unsigned char __uint8_t;
typedef short int __int16_t;
typedef unsigned short int __uint16_t;
typedef int __int32_t;
typedef unsigned int __uint32_t;
#ifdef __COMPILER_INT64__
typedef __COMPILER_INT64__ __int64_t;
typedef __COMPILER_UINT64__ __uint64_t;
#elif defined(_LP64)
typedef long int __int64_t;
typedef unsigned long int __uint64_t;
#else
/* LONGLONG */
__extension__
typedef long long int __int64_t;
/* LONGLONG */
__extension__
typedef unsigned long long int __uint64_t;
#endif
#define __BIT_TYPES_DEFINED__
/* 7.18.1.4 Integer types capable of holding object pointers */
#ifdef _LP64
typedef long int __intptr_t;
typedef unsigned long int __uintptr_t;
#else
typedef int __intptr_t;
typedef unsigned int __uintptr_t;
#endif
#endif /* !_MIPS_INT_TYPES_H_ */
__extension__
typedef __signed char int_least8_t;
typedef unsigned char uint_least8_t;
typedef short int int_least16_t;
typedef unsigned short int uint_least16_t;
typedef int int_least24_t;
typedef unsigned int uint_least24_t;
typedef int int_least32_t;
typedef unsigned int uint_least32_t;
#ifdef __COMPILER_INT64__
typedef __COMPILER_INT64__ int_least64_t;
typedef __COMPILER_UINT64__ uint_least64_t;
#elif defined(_LP64)
typedef long int int_least64_t;
typedef unsigned long int uint_least64_t;
#else
/* LONGLONG */
__extension__
typedef long long int int_least64_t;
/* LONGLONG */
__extension__
typedef unsigned long long int uint_least64_t;
#endif
/* 7.18.1.3 Fastest minimum-width integer types */
typedef int int_fast8_t;
typedef unsigned int uint_fast8_t;
typedef int int_fast16_t;
typedef unsigned int uint_fast16_t;
typedef int int_fast24_t;
typedef unsigned int uint_fast24_t;
typedef int int_fast32_t;
typedef unsigned int uint_fast32_t;
#ifdef __COMPILER_INT64__
typedef __COMPILER_INT64__ int_fast64_t;
typedef __COMPILER_UINT64__ uint_fast64_t;
#elif defined(_LP64)
typedef long int int_fast64_t;
typedef unsigned long int uint_fast64_t;
#else
/* LONGLONG */
__extension__
typedef long long int int_fast64_t;
/* LONGLONG */
__extension__
typedef unsigned long long int uint_fast64_t;
#endif
/* 7.18.1.5 Greatest-width integer types */
#ifdef __COMPILER_INT64__
typedef __COMPILER_INT64__ intmax_t;
typedef unsigned __COMPILER_INT64__ uintmax_t;
#elif defined(_LP64)
typedef long int intmax_t;
typedef unsigned long int uintmax_t;
#else
/* LONGLONG */
__extension__
typedef long long int intmax_t;
/* LONGLONG */
__extension__
typedef unsigned long long int uintmax_t;
#endif
#endif /* !_MIPS_INT_MWGWTYPES_H_ */
/* $NetBSD: int_limits.h,v 1.3 2002/11/03 19:55:23 thorpej Exp $ */
/*-
* Copyright (c) 2001 The NetBSD Foundation, Inc.
* All rights reserved.
*/
...
/*
* 7.18.2 Limits of specified-width integer types
*/
/* 7.18.2.1 Limits of exact-width integer types */
/* minimum values of exact-width signed integer types */
#define INT8_MIN (-0x7f-1) /* int8_t */
#define INT16_MIN (-0x7fff-1) /* int16_t */
#define INT32_MIN (-0x7fffffff-1) /* int32_t */
#ifdef _LP64
#define INT64_MIN (-0x7fffffffffffffffL-1) /* int64_t */
#else
#define INT64_MIN (-0x7fffffffffffffffLL-1) /* int64_t */
#endif
/* maximum values of exact-width signed integer types */
#define INT8_MAX 0x7f /* int8_t */
#define INT16_MAX 0x7fff /* int16_t */
#define INT32_MAX 0x7fffffff /* int32_t */
#ifdef _LP64
#define INT64_MAX 0x7fffffffffffffffL /* int64_t */
#else
#define INT64_MAX 0x7fffffffffffffffLL /* int64_t */
#endif
/* maximum values of exact-width unsigned integer types */
#define UINT8_MAX 0xffU /* uint8_t */
#define UINT16_MAX 0xffffU /* uint16_t */
#define UINT32_MAX 0xffffffffU /* uint32_t */
#ifdef _LP64
#define UINT64_MAX 0xffffffffffffffffUL /* uint64_t */
#else
#define UINT64_MAX 0xffffffffffffffffULL /* uint64_t */
#endif
/* 7.18.2.2 Limits of minimum-width integer types */
/* minimum values of minimum-width signed integer types */
#define INT_LEAST8_MIN (-0x7f-1) /* int_least8_t */
#define INT_LEAST16_MIN (-0x7fff-1) /* int_least16_t */
#define INT_LEAST24_MIN (-0x7fffffff-1) /* int_least24_t */
#define INT_LEAST32_MIN (-0x7fffffff-1) /* int_least32_t */
#ifdef _LP64
#define INT_LEAST64_MIN (-0x7fffffffffffffffL-1) /* int_least64_t */
#else
#define INT_LEAST64_MIN (-0x7fffffffffffffffLL-1) /* int_least64_t */
#endif
/* maximum values of minimum-width signed integer types */
#define INT_LEAST8_MAX 0x7f /* int_least8_t */
#define INT_LEAST16_MAX 0x7fff /* int_least16_t */
#define INT_LEAST24_MAX 0x7fffffff /* int_least24_t */
#define INT_LEAST32_MAX 0x7fffffff /* int_least32_t */
#ifdef _LP64
#define INT_LEAST64_MAX 0x7fffffffffffffffL /* int_least64_t */
#else
#define INT_LEAST64_MAX 0x7fffffffffffffffLL /* int_least64_t */
#endif
/* maximum values of minimum-width unsigned integer types */
#define UINT_LEAST8_MAX 0xffU /* uint_least8_t */
#define UINT_LEAST16_MAX 0xffffU /* uint_least16_t */
#define UINT_LEAST24_MAX 0xffffffffU /* uint_least24_t */
#define UINT_LEAST32_MAX 0xffffffffU /* uint_least32_t */
#ifdef _LP64
#define UINT_LEAST64_MAX 0xffffffffffffffffUL /* uint_least64_t */
#else
#define UINT_LEAST64_MAX 0xffffffffffffffffULL /* uint_least64_t */
#endif
/* 7.18.2.3 Limits of fastest minimum-width integer types */
/* minimum values of fastest minimum-width signed integer types */
#define INT_FAST8_MIN (-0x7fffffff-1) /* int_fast8_t */
#define INT_FAST16_MIN (-0x7fffffff-1) /* int_fast16_t */
#define INT_FAST24_MIN (-0x7fffffff-1) /* int_fast24_t */
#define INT_FAST32_MIN (-0x7fffffff-1) /* int_fast32_t */
#ifdef _LP64
#define INT_FAST64_MIN (-0x7fffffffffffffffL-1) /* int_fast64_t */
#else
#define INT_FAST64_MIN (-0x7fffffffffffffffLL-1) /* int_fast64_t */
#endif
/* maximum values of fastest minimum-width signed integer types */
#define INT_FAST8_MAX 0x7fffffff /* int_fast8_t */
#define INT_FAST16_MAX 0x7fffffff /* int_fast16_t */
#define INT_FAST24_MAX 0x7fffffff /* int_fast24_t */
#define INT_FAST32_MAX 0x7fffffff /* int_fast32_t */
#ifdef _LP64
#define INT_FAST64_MAX 0x7fffffffffffffffL /* int_fast64_t */
#else
#define INT_FAST64_MAX 0x7fffffffffffffffLL /* int_fast64_t */
#endif
/* maximum values of fastest minimum-width unsigned integer types */
#define UINT_FAST8_MAX 0xffffffffU /* uint_fast8_t */
#define UINT_FAST16_MAX 0xffffffffU /* uint_fast16_t */
#define UINT_FAST24_MAX 0xffffffffU /* uint_fast24_t */
#define UINT_FAST32_MAX 0xffffffffU /* uint_fast32_t */
#ifdef _LP64
#define UINT_FAST64_MAX 0xffffffffffffffffUL /* uint_fast64_t */
#else
#define UINT_FAST64_MAX 0xffffffffffffffffULL /* uint_fast64_t */
#endif
/* 7.18.2.4 Limits of integer types capable of holding object pointers */
#ifdef _LP64
#define INTPTR_MIN (-0x7fffffffffffffffL-1) /* intptr_t */
#define INTPTR_MAX 0x7fffffffffffffffL /* intptr_t */
#define UINTPTR_MAX 0xffffffffffffffffUL /* uintptr_t */
#else
#define INTPTR_MIN (-0x7fffffff-1) /* intptr_t */
#define INTPTR_MAX 0x7fffffff /* intptr_t */
#define UINTPTR_MAX 0xffffffffU /* uintptr_t */
#endif
/* 7.18.2.5 Limits of greatest-width integer types */
#ifdef _LP64
#define INTMAX_MIN (-0x7fffffffffffffffL-1) /* intmax_t */
#define INTMAX_MAX 0x7fffffffffffffffL /* intmax_t */
#define UINTMAX_MAX 0xffffffffffffffffUL /* uintmax_t */
#else
#define INTMAX_MIN (-0x7fffffffffffffffLL-1) /* intmax_t */
#define INTMAX_MAX 0x7fffffffffffffffLL /* intmax_t */
#define UINTMAX_MAX 0xffffffffffffffffULL /* uintmax_t */
#endif
/*
* 7.18.3 Limits of other integer types
*/
/* limits of ptrdiff_t */
#ifdef _LP64
#define PTRDIFF_MIN (-0x7fffffffffffffffL-1) /* ptrdiff_t */
#define PTRDIFF_MAX 0x7fffffffffffffffL /* ptrdiff_t */
#else
#define PTRDIFF_MIN (-0x7fffffff-1) /* ptrdiff_t */
#define PTRDIFF_MAX 0x7fffffff /* ptrdiff_t */
#endif
/* limits of sig_atomic_t */
#define SIG_ATOMIC_MIN (-0x7fffffff-1) /* sig_atomic_t */
#define SIG_ATOMIC_MAX 0x7fffffff /* sig_atomic_t */
/* limit of size_t */
#ifdef _LP64
#define SIZE_MAX 0xffffffffffffffffUL /* size_t */
#else
#define SIZE_MAX 0xffffffffU /* size_t */
#endif
#ifndef WCHAR_MIN /* also possibly defined in */
/* limits of wchar_t */
#define WCHAR_MIN 0 /* wchar_t */
#define WCHAR_MAX 0xffff /* wchar_t */
/* limits of wint_t */
#define WINT_MIN (-0x7fffffff-1) /* wint_t */
#define WINT_MAX 0x7fffffff /* wint_t */
#endif
#endif /* !_MIPS_INT_LIMITS_H_ */
(1): http://ww1.microchip.com/downloads/en/DeviceDoc/51686F.pdf
(2): http://www.youtube.com/watch?v=6FNKJSWuaJE
As its based on the GCC compiler, it is prepared for both ANSI with CCI compliance. Ill keep with the basics out of type defs.
The ANSI C Standard does indicate minimum requirements for these
types, as specified in
* For more info on compiler compliance check the XC32 Compiler User guide in chapter “2.4.6 Sizes of Type
From researching the include files, one can get this info :
/* 7.18.1.1 Exact-width integer types */
typedef __signed char __int8_t;
typedef unsigned char __uint8_t;
typedef short int __int16_t;
typedef unsigned short int __uint16_t;
typedef int __int32_t;
typedef unsigned int __uint32_t;
#ifdef __COMPILER_INT64__
typedef __COMPILER_INT64__ __int64_t;
typedef __COMPILER_UINT64__ __uint64_t;
#elif defined(_LP64)
typedef long int __int64_t;
typedef unsigned long int __uint64_t;
#else
/* LONGLONG */
__extension__
typedef long long int __int64_t;
/* LONGLONG */
__extension__
typedef unsigned long long int __uint64_t;
#endif
#define __BIT_TYPES_DEFINED__
Which gives us :
// MPLAB C32 range of Signed values
char c; // -128 to 127
short s; // -32,768 to 32,767
int i; // -2,147,483,648 to 2,147,483,647
long l; // -2,147,483,648 to 2,147,483,647
Of course, we also have the unsigned attribute:
// MPLAB C32 range of Unsigned values
unsigned char c; // 0 to 255
unsigned short s; // 0 to 65,535
unsigned int i; // 0 to 4,294,967,295
unsigned long l; // 0 to 4,294,967,295
For int, 4 bytes in the physical RAM is used.
So, if we do not have to use int and long, we should use char.
To hold one char variable, C32 compiler will use only 8 bits.
Another possibility is short type, which will use 16 bits to hold one short variable
PIC32‘s ALU is performing all arithmetic operations in the same number of cycles for 32-bit, 16-bit or 8-bit integers, which turns the variable long into just a synonym of the basic integer type int.
It is ok from performance point of view, but it comes with a price.
The only limiting factor, preventing us from always using 32-bit integers , is the consideration of the internal resources , and in this case the RAM memory
* keep the size of your variables to the minimum necessary; operating on bytes versus word can make a big difference in terms of code compactness/efficiency.
If really a large range of values is needed, we can use 64-bit types
// C32 range of 64-bit type values
long long l; // ranges from -2 to the power of 63 to +2 to the power of 63-1
unsigned long long l; // ranges from 0 to +2 to the power of 64
// C32 range of Floating point type values
float f; // 32-bit floating point
double d; // 64-bit floating point
long double d; // 64-bit floating point, synonym of double
The long long integer type offers 64-bit support and requires 8 bytes of memory; So, we can expect a small performance decrease for using long long integers.
Ill leave several excerpts from the header files...
/* 7.18.1.1 Exact-width integer types */
typedef __signed char __int8_t;
typedef unsigned char __uint8_t;
typedef short int __int16_t;
typedef unsigned short int __uint16_t;
typedef int __int32_t;
typedef unsigned int __uint32_t;
#ifdef __COMPILER_INT64__
typedef __COMPILER_INT64__ __int64_t;
typedef __COMPILER_UINT64__ __uint64_t;
#elif defined(_LP64)
typedef long int __int64_t;
typedef unsigned long int __uint64_t;
#else
/* LONGLONG */
__extension__
typedef long long int __int64_t;
/* LONGLONG */
__extension__
typedef unsigned long long int __uint64_t;
#endif
#define __BIT_TYPES_DEFINED__
/* 7.18.1.4 Integer types capable of holding object pointers */
#ifdef _LP64
typedef long int __intptr_t;
typedef unsigned long int __uintptr_t;
#else
typedef int __intptr_t;
typedef unsigned int __uintptr_t;
#endif
#endif /* !_MIPS_INT_TYPES_H_ */
Also :
* 7.18.1.2 Minimum-width integer types */__extension__
typedef __signed char int_least8_t;
typedef unsigned char uint_least8_t;
typedef short int int_least16_t;
typedef unsigned short int uint_least16_t;
typedef int int_least24_t;
typedef unsigned int uint_least24_t;
typedef int int_least32_t;
typedef unsigned int uint_least32_t;
#ifdef __COMPILER_INT64__
typedef __COMPILER_INT64__ int_least64_t;
typedef __COMPILER_UINT64__ uint_least64_t;
#elif defined(_LP64)
typedef long int int_least64_t;
typedef unsigned long int uint_least64_t;
#else
/* LONGLONG */
__extension__
typedef long long int int_least64_t;
/* LONGLONG */
__extension__
typedef unsigned long long int uint_least64_t;
#endif
/* 7.18.1.3 Fastest minimum-width integer types */
typedef int int_fast8_t;
typedef unsigned int uint_fast8_t;
typedef int int_fast16_t;
typedef unsigned int uint_fast16_t;
typedef int int_fast24_t;
typedef unsigned int uint_fast24_t;
typedef int int_fast32_t;
typedef unsigned int uint_fast32_t;
#ifdef __COMPILER_INT64__
typedef __COMPILER_INT64__ int_fast64_t;
typedef __COMPILER_UINT64__ uint_fast64_t;
#elif defined(_LP64)
typedef long int int_fast64_t;
typedef unsigned long int uint_fast64_t;
#else
/* LONGLONG */
__extension__
typedef long long int int_fast64_t;
/* LONGLONG */
__extension__
typedef unsigned long long int uint_fast64_t;
#endif
/* 7.18.1.5 Greatest-width integer types */
#ifdef __COMPILER_INT64__
typedef __COMPILER_INT64__ intmax_t;
typedef unsigned __COMPILER_INT64__ uintmax_t;
#elif defined(_LP64)
typedef long int intmax_t;
typedef unsigned long int uintmax_t;
#else
/* LONGLONG */
__extension__
typedef long long int intmax_t;
/* LONGLONG */
__extension__
typedef unsigned long long int uintmax_t;
#endif
#endif /* !_MIPS_INT_MWGWTYPES_H_ */
Regarding the limits of each type def...
/* $NetBSD: int_limits.h,v 1.3 2002/11/03 19:55:23 thorpej Exp $ */
/*-
* Copyright (c) 2001 The NetBSD Foundation, Inc.
* All rights reserved.
*/
...
/*
* 7.18.2 Limits of specified-width integer types
*/
/* 7.18.2.1 Limits of exact-width integer types */
/* minimum values of exact-width signed integer types */
#define INT8_MIN (-0x7f-1) /* int8_t */
#define INT16_MIN (-0x7fff-1) /* int16_t */
#define INT32_MIN (-0x7fffffff-1) /* int32_t */
#ifdef _LP64
#define INT64_MIN (-0x7fffffffffffffffL-1) /* int64_t */
#else
#define INT64_MIN (-0x7fffffffffffffffLL-1) /* int64_t */
#endif
/* maximum values of exact-width signed integer types */
#define INT8_MAX 0x7f /* int8_t */
#define INT16_MAX 0x7fff /* int16_t */
#define INT32_MAX 0x7fffffff /* int32_t */
#ifdef _LP64
#define INT64_MAX 0x7fffffffffffffffL /* int64_t */
#else
#define INT64_MAX 0x7fffffffffffffffLL /* int64_t */
#endif
/* maximum values of exact-width unsigned integer types */
#define UINT8_MAX 0xffU /* uint8_t */
#define UINT16_MAX 0xffffU /* uint16_t */
#define UINT32_MAX 0xffffffffU /* uint32_t */
#ifdef _LP64
#define UINT64_MAX 0xffffffffffffffffUL /* uint64_t */
#else
#define UINT64_MAX 0xffffffffffffffffULL /* uint64_t */
#endif
/* 7.18.2.2 Limits of minimum-width integer types */
/* minimum values of minimum-width signed integer types */
#define INT_LEAST8_MIN (-0x7f-1) /* int_least8_t */
#define INT_LEAST16_MIN (-0x7fff-1) /* int_least16_t */
#define INT_LEAST24_MIN (-0x7fffffff-1) /* int_least24_t */
#define INT_LEAST32_MIN (-0x7fffffff-1) /* int_least32_t */
#ifdef _LP64
#define INT_LEAST64_MIN (-0x7fffffffffffffffL-1) /* int_least64_t */
#else
#define INT_LEAST64_MIN (-0x7fffffffffffffffLL-1) /* int_least64_t */
#endif
/* maximum values of minimum-width signed integer types */
#define INT_LEAST8_MAX 0x7f /* int_least8_t */
#define INT_LEAST16_MAX 0x7fff /* int_least16_t */
#define INT_LEAST24_MAX 0x7fffffff /* int_least24_t */
#define INT_LEAST32_MAX 0x7fffffff /* int_least32_t */
#ifdef _LP64
#define INT_LEAST64_MAX 0x7fffffffffffffffL /* int_least64_t */
#else
#define INT_LEAST64_MAX 0x7fffffffffffffffLL /* int_least64_t */
#endif
/* maximum values of minimum-width unsigned integer types */
#define UINT_LEAST8_MAX 0xffU /* uint_least8_t */
#define UINT_LEAST16_MAX 0xffffU /* uint_least16_t */
#define UINT_LEAST24_MAX 0xffffffffU /* uint_least24_t */
#define UINT_LEAST32_MAX 0xffffffffU /* uint_least32_t */
#ifdef _LP64
#define UINT_LEAST64_MAX 0xffffffffffffffffUL /* uint_least64_t */
#else
#define UINT_LEAST64_MAX 0xffffffffffffffffULL /* uint_least64_t */
#endif
/* 7.18.2.3 Limits of fastest minimum-width integer types */
/* minimum values of fastest minimum-width signed integer types */
#define INT_FAST8_MIN (-0x7fffffff-1) /* int_fast8_t */
#define INT_FAST16_MIN (-0x7fffffff-1) /* int_fast16_t */
#define INT_FAST24_MIN (-0x7fffffff-1) /* int_fast24_t */
#define INT_FAST32_MIN (-0x7fffffff-1) /* int_fast32_t */
#ifdef _LP64
#define INT_FAST64_MIN (-0x7fffffffffffffffL-1) /* int_fast64_t */
#else
#define INT_FAST64_MIN (-0x7fffffffffffffffLL-1) /* int_fast64_t */
#endif
/* maximum values of fastest minimum-width signed integer types */
#define INT_FAST8_MAX 0x7fffffff /* int_fast8_t */
#define INT_FAST16_MAX 0x7fffffff /* int_fast16_t */
#define INT_FAST24_MAX 0x7fffffff /* int_fast24_t */
#define INT_FAST32_MAX 0x7fffffff /* int_fast32_t */
#ifdef _LP64
#define INT_FAST64_MAX 0x7fffffffffffffffL /* int_fast64_t */
#else
#define INT_FAST64_MAX 0x7fffffffffffffffLL /* int_fast64_t */
#endif
/* maximum values of fastest minimum-width unsigned integer types */
#define UINT_FAST8_MAX 0xffffffffU /* uint_fast8_t */
#define UINT_FAST16_MAX 0xffffffffU /* uint_fast16_t */
#define UINT_FAST24_MAX 0xffffffffU /* uint_fast24_t */
#define UINT_FAST32_MAX 0xffffffffU /* uint_fast32_t */
#ifdef _LP64
#define UINT_FAST64_MAX 0xffffffffffffffffUL /* uint_fast64_t */
#else
#define UINT_FAST64_MAX 0xffffffffffffffffULL /* uint_fast64_t */
#endif
/* 7.18.2.4 Limits of integer types capable of holding object pointers */
#ifdef _LP64
#define INTPTR_MIN (-0x7fffffffffffffffL-1) /* intptr_t */
#define INTPTR_MAX 0x7fffffffffffffffL /* intptr_t */
#define UINTPTR_MAX 0xffffffffffffffffUL /* uintptr_t */
#else
#define INTPTR_MIN (-0x7fffffff-1) /* intptr_t */
#define INTPTR_MAX 0x7fffffff /* intptr_t */
#define UINTPTR_MAX 0xffffffffU /* uintptr_t */
#endif
/* 7.18.2.5 Limits of greatest-width integer types */
#ifdef _LP64
#define INTMAX_MIN (-0x7fffffffffffffffL-1) /* intmax_t */
#define INTMAX_MAX 0x7fffffffffffffffL /* intmax_t */
#define UINTMAX_MAX 0xffffffffffffffffUL /* uintmax_t */
#else
#define INTMAX_MIN (-0x7fffffffffffffffLL-1) /* intmax_t */
#define INTMAX_MAX 0x7fffffffffffffffLL /* intmax_t */
#define UINTMAX_MAX 0xffffffffffffffffULL /* uintmax_t */
#endif
/*
* 7.18.3 Limits of other integer types
*/
/* limits of ptrdiff_t */
#ifdef _LP64
#define PTRDIFF_MIN (-0x7fffffffffffffffL-1) /* ptrdiff_t */
#define PTRDIFF_MAX 0x7fffffffffffffffL /* ptrdiff_t */
#else
#define PTRDIFF_MIN (-0x7fffffff-1) /* ptrdiff_t */
#define PTRDIFF_MAX 0x7fffffff /* ptrdiff_t */
#endif
/* limits of sig_atomic_t */
#define SIG_ATOMIC_MIN (-0x7fffffff-1) /* sig_atomic_t */
#define SIG_ATOMIC_MAX 0x7fffffff /* sig_atomic_t */
/* limit of size_t */
#ifdef _LP64
#define SIZE_MAX 0xffffffffffffffffUL /* size_t */
#else
#define SIZE_MAX 0xffffffffU /* size_t */
#endif
#ifndef WCHAR_MIN /* also possibly defined in
/* limits of wchar_t */
#define WCHAR_MIN 0 /* wchar_t */
#define WCHAR_MAX 0xffff /* wchar_t */
/* limits of wint_t */
#define WINT_MIN (-0x7fffffff-1) /* wint_t */
#define WINT_MAX 0x7fffffff /* wint_t */
#endif
#endif /* !_MIPS_INT_LIMITS_H_ */
(1): http://ww1.microchip.com/downloads/en/DeviceDoc/51686F.pdf
(2): http://www.youtube.com/watch?v=6FNKJSWuaJE
Subscribe to:
Posts (Atom)









