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.
Dependencies: mbed-rtos mbed CRC16
Fork of S5info_APP2 by
main.cpp
- Committer:
- ericbisson
- Date:
- 2017-03-07
- Revision:
- 24:2034362db66f
- Parent:
- 23:9c4e4898b741
- Child:
- 25:d0c348c3c85d
File content as of revision 24:2034362db66f:
#include "CRC16.h"
#include "mbed.h"
#include "rtos.h"
#include <vector>
using std::vector;
DigitalIn in(p30);
Thread ThreadLecture;
Thread ThreadWrite;
const int PREAMBULE = 0b01010101;
const int START = 0b01111110;
const int END = 0b01111110;
Serial pc(USBTX, USBRX);
DigitalOut out(p13);
DigitalOut myled1(LED1);
DigitalOut myled2(LED2);
bool transmit = false; //faux pour le debut de demi-periode d'envoie d'un bit, vrai pour la 2ème demi-periode
char trame_sent[80]; //tableau de la trame à envoyer
uint8_t byte_sent_pos, //position de l'octet dans le tableau d'envoi
trame_length; //longueur de la trame complete
signed char bit_sent; //position du bit de l'octet en cours d'envoi (du MSB au LSB) 7..0
bool bTimer1 = false;
//encodage manchester
bool codeManchester(bool bit, bool clock)
{
return (bit == clock);
}
//Envoie de données bit par bit
void send_data()
{
out = codeManchester(((trame_sent[byte_sent_pos] >> bit_sent) & 0x01), bTimer1);
if(bTimer1)
{
bit_sent--;
}
bTimer1 = !bTimer1; //varier entre la 1ere et 2eme partie de demi-periode
if (bit_sent < 0) //Si l'octet a ete envoye
{
bit_sent = 7; //remettre la position initiale pour le prochain octet
byte_sent_pos++; //incrementer l'octet
if (byte_sent_pos >= trame_length) //Si la trame a ete envoyee
{
byte_sent_pos = 0;
bTimer1 = false;
LPC_TIM1->TCR = 0; // disable Timer
}
}
}
extern "C" void TIMER1_IRQHandler()
{
LPC_TIM1->TC = 0;
myled1 = !myled1;
if ((LPC_TIM1->IR & 0x01) == 0x01)
{
send_data();
LPC_TIM1->IR |= 1 << 0; // clear
}
}
int PeriodLength = 0;
bool bReceivedFirstBit = false;
bool bInvert = false;
extern "C" void TIMER2_IRQHandler()
{
LPC_TIM2->TC = 0;
LPC_TIM2->IR |= 0xFFFFFFFF; // clear
myled2 = !myled2;
if (PeriodLength > 0)
{
if (LPC_TIM2->CR0 >= PeriodLength)
{
bInvert = false;
}
else
{
bInvert = true;
}
}
else if (bReceivedFirstBit)
{
PeriodLength = (LPC_TIM2->CR0 / 2) * 1.5;
}
else
{
bReceivedFirstBit = true;
}
ThreadLecture.signal_set(1);
}
//création de la trame
void create_trame(char message[],unsigned char taille)
{
CRC16 myCRC;
unsigned short resultCRC = myCRC.calculateCRC16(message,taille);
trame_sent[0] = PREAMBULE; //Preambule
trame_sent[1] = START; //Start
trame_sent[2] = 0x00; //Type + Flag mis a 0x00
trame_sent[3] = taille; //Longueur du message (Max 33 caractères)
//message
for (char i=0;i<taille;i++)
{
trame_sent[taille + 4] = message[i];
}
//CRC16
trame_sent[taille + 4] = (resultCRC >> 8) & 0xFF;
trame_sent[taille + 5] = resultCRC & 0xFF;
trame_sent[taille + 6] = END; //End
trame_length = taille + 7; //Longueur de la trame
}
//obtention du texte
void get_text()
{
while (true)
{
char text[4] = {'a','l','l','o'};
unsigned char count = 4;
create_trame(text,count);
byte_sent_pos = 0;
bit_sent = 7;
bTimer1 = false;
LPC_TIM1->TCR = 1; // enable and reset Timer
wait_ms(1000);
}
/*pc.printf("\n\rYour text : ");
unsigned char count = 0;
char c = 0x00;
char text[73];
while(c != '\r' && count < 73) {
c = pc.getc();
text[count] = c;
pc.putc(c);
count++;
}
pc.printf("get_text();\n");*/
}
void read()
{
char byte = 0;
vector<char> bytes;
char shift = 0;
char totalsize = 7;
CRC16 mycrc16;
while (true)
{
ThreadLecture.signal_wait(1);
if (bInvert)
{
byte = (byte << 1) + !in;
}
else
{
byte = (byte << 1) + in;
}
shift++;
if (shift == 8)
{
shift = 0;
// à partir d'ici, je travaille en byte et non bit
bytes.push_back(byte);
// Validations de base
if ((bytes.size() == 1 && bytes[0] != PREAMBULE) ||
(bytes.size() == 2 && bytes[1] != START))
{
if (bytes.size() == 1)
{
pc.printf("[DEBUG] - Invalid PREAMBULE : %x\n", bytes[0]);
}
else
{
pc.printf("[DEBUG] - Invalid START : %x\n", bytes[1]);
}
bytes.clear();
}
if (bytes.size() == 3)
{
pc.printf("[DEBUG] - YESSSSSSSSSSSSSSSSSSSS\n");
}
if (bytes.size() == 4)
{
totalsize = 7 + bytes[3];
}
// fin
if (totalsize == bytes.size())
{
// Calcul du CRC
unsigned short currentCRC = bytes[bytes.size()-2] + bytes[bytes.size()-3]<<8;
vector<char> charge_utile(&bytes[4], &bytes[bytes.size()-4]);
if (currentCRC == mycrc16.calculateCRC16(&charge_utile[0], charge_utile.size()) && bytes.back() == END)
{
// Affiche à l'écran le message valide
pc.printf(&charge_utile[0], charge_utile.size());
}
else
{
pc.printf("[DEBUG] - Invalid CRC, dumping message\n");
}
bytes.clear();
}
}
}
}
void initTimers()
{
//Timer 1 (match)
LPC_SC->PCLKSEL0 |= (1 << 4); // pclk = cclk timer1
LPC_SC->PCONP |= (1 << 2); // timer1 power on
LPC_TIM1->MCR = 3; // interrupt and reset control
LPC_TIM1->TC = 0; // clear timer counter
LPC_TIM1->PC = 0; // clear prescale counter
LPC_TIM1->PR = 0; // clear prescale register
LPC_TIM1->MR0 = (960000 / 2) * 10; // 10/2 ms
LPC_TIM1->EMR = (3 << 4); // Interrupt & reset timer on match
NVIC_EnableIRQ(TIMER1_IRQn); // enable timer interrupt
LPC_TIM1->TCR = 0; // disable Timer
//Timer 2 (cap)
LPC_SC->PCLKSEL1 |= (1 << 12); // pclk = cclk timer2
LPC_SC->PCONP |= (1 << 22); // timer2 power on
LPC_TIM2->TC = 0; // clear timer counter
LPC_TIM2->PC = 0; // clear prescale counter
LPC_TIM2->PR = 0; // clear prescale register
LPC_TIM2->TCR |= (1 << 1); // reset timer
LPC_TIM2->TCR &= ~(1 << 1); // release reset
LPC_TIM2->CCR |= 0x0000007; // enable rising-edge and falling-edge capture
NVIC_EnableIRQ(TIMER2_IRQn); // enable timer interrupt
LPC_TIM2->TCR = 1; // start Timer
}
int main() {
LPC_PINCON->PINSEL0 |= (3 << 8); // pin30
LPC_PINCON->PINMODE1 |= 3;
initTimers();
ThreadLecture.start(read);
ThreadWrite.start(get_text);
while(true)
{
}
};
