Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Diff: Sampler.cpp
- Revision:
- 0:41db3ed6754d
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Sampler.cpp Sat Mar 12 00:18:53 2016 +0000
@@ -0,0 +1,308 @@
+/*
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ Author: Joao Paulo Barraca <jpbarraca@gmail.com>
+*/
+
+#include "mbed.h"
+#include "Sampler.h"
+#include <algorithm>
+
+#define TRIGGER_PARALLEL 0
+#define TRIGGER_SERIAL 1
+#define TRIGGER_DISABLED 0xFF
+
+#define TRIGGER_MODE_SERIAL 0
+#define TRIGGER_MODE_PARALLEL 1
+
+#define FLAGS_DEMUX 1
+#define FLAGS_FILTER 2
+#define FLAGS_CHANNEL_GROUPS 0x3C
+#define FLAGS_EXTERNAL 0x40
+#define FLAGS_INVERTED 0x80
+#define FLAGS_TEST 0x400
+
+
+#define SUMP_ORIGINAL_FREQ (100000000)
+#define SYSTEM_CLOCK_MULT (SystemCoreClock / 1000000)
+#define BUFFER_SIZE 32768
+#define MAX_FREQUENCY 10000000
+
+__attribute((section("AHBSRAM0"),aligned)) uint8_t main_buffer[BUFFER_SIZE];
+
+#define likely(x) __builtin_expect((x),1)
+
+Sampler::Sampler(Serial *sp)
+{
+ pc = sp;
+ bufferSize = BUFFER_SIZE;
+ buffer = main_buffer;
+
+ //Setup port
+ SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOBEN);
+ GPIOB->OSPEEDR = 3; // High Speed
+ GPIOB->BSRR = 0xFFFF0000; // No Special pins
+ GPIOB->MODER = 0; // Input
+ GPIOB->PUPDR = 0; // No pull up or pull down
+
+ reset();
+}
+
+void Sampler::reset()
+{
+ buffer_index = 0;
+ setTriggerMask(0);
+ setTriggerValue(0);
+ setTriggerState(0);
+ setSamplingDivider(11);
+ setFlags(0);
+ setSampleNumber(bufferSize);
+ setSamplingDelay(0);
+}
+
+uint32_t Sampler::getMaxFrequency(){
+ return MAX_FREQUENCY;
+}
+
+uint32_t Sampler::getBufferSize(){
+ return bufferSize;
+}
+
+void Sampler::setSamplingDivider(uint32_t divider)
+{
+ //Max speed is 10Mhz
+ if(divider < 9)
+ divider = 9;
+
+ samplingPeriod = (divider+1)*10;
+}
+
+void Sampler::setSampleNumber(uint32_t s)
+{
+ sampleNumber = min((uint32_t) bufferSize, s);
+}
+
+void Sampler::setSamplingDelay(uint16_t s)
+{
+ sampleDelay = s;
+}
+
+void Sampler::setTriggerMask(uint32_t s)
+{
+ triggerMask = s;
+}
+void Sampler::setTriggerValue(uint32_t s)
+{
+ triggerValue = s & 0xFF;
+}
+
+void Sampler::setTriggerState(uint8_t state){
+ triggerState = state;
+}
+
+void Sampler::setFlags(uint32_t s)
+{
+ flags = s;
+}
+
+void Sampler::runTest()
+{
+ //TODO
+}
+
+void Sampler::start()
+{
+
+ int32_t snum = sampleNumber;
+
+
+ if(sampleDelay > 0){
+ wait_us(sampleDelay);
+ }
+
+ if(triggerState == 1){
+ while((GPIOB->IDR & triggerMask) != triggerValue);
+ }
+
+ //10Mhz (Close but not really...)
+ if(samplingPeriod == 100){
+ while(likely(snum >= 4)){
+ buffer[snum - 1] = GPIOB->IDR;
+ __asm volatile ( " NOP\nNOP\n");
+ buffer[snum - 2] = GPIOB->IDR;
+ __asm volatile ( " NOP\nNOP\n");
+ buffer[snum - 3] = GPIOB->IDR;
+ __asm volatile ( " NOP\nNOP\n");
+ buffer[snum - 4] = GPIOB->IDR;
+ snum -= 4;
+ }
+ //5Mhz (Almost)
+ }else if(samplingPeriod == 200){
+ while(likely(snum >= 4)){
+ buffer[snum - 1] = GPIOB->IDR;
+ __asm volatile ( " NOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\n");
+ __asm volatile ( " NOP\nNOP\nNOP\n");
+
+ buffer[snum - 2] = GPIOB->IDR;
+ __asm volatile ( " NOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\n");
+ __asm volatile ( " NOP\nNOP\nNOP\n");
+
+ buffer[snum - 3] = GPIOB->IDR;
+ __asm volatile ( " NOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\n");
+ __asm volatile ( " \nNOP\nNOP\nNOP\n");
+
+ buffer[snum - 4] = GPIOB->IDR;
+ __asm volatile ( " NOP\nNOP\nNOP\nNOP\nNOP\n");
+ snum -= 4;
+ }
+ //2Mhz (True)
+ }else if(samplingPeriod == 500){
+ while(likely(snum >= 4)){
+
+ buffer[snum - 1] = GPIOB->IDR;
+ __asm volatile ( " NOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\n");
+ __asm volatile ( " NOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\n");
+ __asm volatile ( " NOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\n");
+ __asm volatile ( " NOP\nNOP\nNOP\nNOP\n");
+
+ buffer[snum - 2] = GPIOB->IDR;
+ __asm volatile ( " NOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\n");
+ __asm volatile ( " NOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\n");
+ __asm volatile ( " NOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\n");
+ __asm volatile ( " NOP\nNOP\nNOP\n");
+
+ buffer[snum - 3] = GPIOB->IDR;
+ __asm volatile ( " NOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\n");
+ __asm volatile ( " NOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\n");
+ __asm volatile ( " NOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\n");
+ __asm volatile ( " NOP\nNOP\nNOP\n");
+
+ buffer[snum - 4] = GPIOB->IDR;
+ __asm volatile ( " NOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\n");
+ __asm volatile ( " NOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\n");
+ __asm volatile ( " NOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\n");
+ snum -= 4;
+ }
+ //1Mhz (True)
+ }else if(samplingPeriod == 1000){
+ while(likely(snum >= 4)){
+
+ buffer[snum - 1] = GPIOB->IDR;
+ __asm volatile ( " NOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\n");
+ __asm volatile ( " NOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\n");
+ __asm volatile ( " NOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\n");
+ __asm volatile ( " NOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP");
+ __asm volatile ( " NOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\n");
+ __asm volatile ( " NOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\n");
+ __asm volatile ( " NOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\n");
+ __asm volatile ( " NOP\nNOP\nNOP\n");
+
+ buffer[snum - 2] = GPIOB->IDR;
+ __asm volatile ( " NOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\n");
+ __asm volatile ( " NOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\n");
+ __asm volatile ( " NOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\n");
+ __asm volatile ( " NOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP");
+ __asm volatile ( " NOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\n");
+ __asm volatile ( " NOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\n");
+ __asm volatile ( " NOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\n");
+ __asm volatile ( " NOP\nNOP\nNOP\n");
+
+ buffer[snum - 3] = GPIOB->IDR;
+ __asm volatile ( " NOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\n");
+ __asm volatile ( " NOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\n");
+ __asm volatile ( " NOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\n");
+ __asm volatile ( " NOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP");
+ __asm volatile ( " NOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\n");
+ __asm volatile ( " NOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\n");
+ __asm volatile ( " NOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\n");
+ __asm volatile ( " NOP\nNOP\nNOP\n");
+
+ buffer[snum - 4] = GPIOB->IDR;
+ __asm volatile ( " NOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\n");
+ __asm volatile ( " NOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\n");
+ __asm volatile ( " NOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\n");
+ __asm volatile ( " NOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP");
+ __asm volatile ( " NOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\n");
+ __asm volatile ( " NOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\n");
+ __asm volatile ( " NOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\nNOP\n");
+ snum -= 4;
+ }
+ //Others
+ }else {
+ uint32_t c = samplingPeriod/1000.0;
+ while(likely(snum >= 4)){
+ buffer[snum - 1] = GPIOB->IDR;
+ wait_us(c);
+ buffer[snum - 2] = GPIOB->IDR;
+ wait_us(c);
+ buffer[snum - 3] = GPIOB->IDR;
+ wait_us(c);
+ buffer[snum - 4] = GPIOB->IDR;
+ wait_us(c);
+ snum -= 4;
+ }
+ }
+}
+
+void Sampler::arm()
+{
+ if (flags & FLAGS_TEST) {
+ PwmOut pwm0(PB_0);
+ pwm0.period_us(1);
+ pwm0.write(0.5);
+
+ PwmOut pwm1(PB_1);
+ pwm1.period_us(10);
+ pwm1.write(0.5);
+
+ PwmOut pwm2(PB_3);
+ pwm2.period_us(100);
+ pwm2.write(0.5);
+
+ PwmOut pwm3(PB_4);
+ pwm3.period_us(500);
+ pwm3.write(0.5);
+
+ PwmOut pwm4(PB_5);
+ pwm4.period_ms(1);
+ pwm4.write(0.5);
+
+ PwmOut pwm5(PB_6);
+ pwm5.period_ms(10);
+ pwm5.write(0.5);
+
+ PwmOut pwm6(PB_7);
+ pwm6.period_ms(100);
+ pwm6.write(0.5);
+
+ start();
+
+ pwm0.write(0);
+ pwm1.write(0);
+ pwm2.write(0);
+ pwm3.write(0);
+ pwm4.write(0);
+ pwm5.write(0);
+ pwm6.write(0);
+ }else{
+ start();
+ }
+
+ for(uint16_t i = 0;i < sampleNumber; i++)
+ {
+ pc->putc(buffer[i]);
+ while(!pc->writeable());
+ }
+}
+
+void Sampler::stop()
+{
+}