Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions STM32F1/cores/maple/HardwareTimer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,22 @@ uint16 HardwareTimer::setPeriod(uint32 microseconds) {
return overflow;
}

uint16 HardwareTimer::setCycles(uint32 Cycles) {
// Not the best way to handle this edge case?
if (!Cycles) {
this->setPrescaleFactor(1);
this->setOverflow(1);
return this->getOverflow();
}

uint32 period_cyc = Cycles;
uint16 prescaler = (uint16)(period_cyc / MAX_RELOAD + 1);
uint16 overflow = (uint16)((period_cyc + (prescaler / 2)) / prescaler);
this->setPrescaleFactor(prescaler);
this->setOverflow(overflow);
return overflow;
}

void HardwareTimer::setMode(int channel, timer_mode mode) {
timer_set_mode(this->dev, (uint8)channel, (timer_mode)mode);
}
Expand Down
12 changes: 12 additions & 0 deletions STM32F1/cores/maple/HardwareTimer.h
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,18 @@ class HardwareTimer {
*/
void setCount(uint16 val);

/**
* @brief Set the timer's period in Cycles.
*
* Configures the prescaler and overflow values to generate a timer
* reload with a period of given number of
* Cycles.
*
* @param Cycles The desired period of the timer. This must be
* greater than zero.
* @return The new overflow value.
*/
uint16 setCycles(uint32 Cycles);
/**
* @brief Set the timer's period in microseconds.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
#include <HardwareCAN.h>
/*
* Uses STM32duino with Phono patch. Must add 33 and 95 CAN speeds
*/
#define BPIN 0
#define SPIN 1
byte msgD0 ; // variable to be used in the example.

// Instanciation of CAN interface
HardwareCAN canBus(CAN1_BASE);
CanMsg msg ;

void CANSetup(void)
{
CAN_STATUS Stat ;

// Initialize CAN module
canBus.map(CAN_GPIO_PB8_PB9); // This setting is already wired in the Olimexino-STM32 board
Stat = canBus.begin(CAN_SPEED_95, CAN_MODE_NORMAL); // Other speeds go from 125 kbps to 1000 kbps. CAN allows even more choices.

canBus.filter(0, 0, 0);
canBus.set_irq_mode(); // Use irq mode (recommended), so the handling of incoming messages
// will be performed at ease in a task or in the loop. The software fifo is 16 cells long,
// allowing at least 15 ms before processing the fifo is needed at 125 kbps
Stat = canBus.status();
if (Stat != CAN_OK)
/* Your own error processing here */ ; // Initialization failed
}


// Send one frame. Parameter is a pointer to a frame structure (above), that has previously been updated with data.
// If no mailbox is available, wait until one becomes empty. There are 3 mailboxes.
CAN_TX_MBX CANsend(CanMsg *pmsg) // Should be moved to the library?!
{
CAN_TX_MBX mbx;

do
{
mbx = canBus.send(pmsg) ;
#ifdef USE_MULTITASK
vTaskDelay( 1 ) ; // Infinite loops are not multitasking-friendly
#endif
}
while(mbx == CAN_TX_NO_MBX) ; // Waiting outbound frames will eventually be sent, unless there is a CAN bus failure.
return mbx ;
}

// Send message
// Prepare and send a frame containing some value
void SendCANmessage(long id=0x001, byte dlength=8, byte d0=0x00, byte d1=0x00, byte d2=0x00, byte d3=0x00, byte d4=0x00, byte d5=0x00, byte d6=0x00, byte d7=0x00)
{
// Initialize the message structure
// A CAN structure includes the following fields:
msg.IDE = CAN_ID_STD; // Indicates a standard identifier ; CAN_ID_EXT would mean this frame uses an extended identifier
msg.RTR = CAN_RTR_DATA; // Indicated this is a data frame, as opposed to a remote frame (would then be CAN_RTR_REMOTE)
msg.ID = id ; // Identifier of the frame : 0-2047 (0-0x3ff) for standard idenfiers; 0-0x1fffffff for extended identifiers
msg.DLC = dlength; // Number of data bytes to follow

// Prepare frame : send something
msg.Data[0] = d0 ;
msg.Data[1] = d1 ;
msg.Data[2] = d2 ;
msg.Data[3] = d3 ;
msg.Data[4] = d4 ;
msg.Data[5] = d5 ;
msg.Data[6] = d6 ;
msg.Data[7] = d7 ;

digitalWrite(PC13, LOW); // turn the onboard LED on
CANsend(&msg) ; // Send this frame
delay(180);
digitalWrite(PC13, HIGH); // turn the LED off
delay(100);
}

// The application program starts here
int bState = 0; // variable for reading the pushbutton status
int sState = 0; // variable for reading the switch status
byte st = 0x31; // buttot 1 on the CD30MP3

void setup() {
// put your setup code here, to run once:
CANSetup() ; // Initialize the CAN module and prepare the message structures.
pinMode(PC13, OUTPUT);
pinMode(BPIN, INPUT); // input for hardware button
pinMode(SPIN, INPUT); // input for hardware switch
Serial1.begin(115200);
Serial1.println("Hello World!");
msgD0 = 0x01;
delay(500);
}

void loop() {
bState = digitalRead(BPIN);
sState = digitalRead(SPIN);
// check if the pushbutton is pressed.
// if it is, the buttonState is HIGH:
if (bState == HIGH) {
long msgID = 0x201 ;
SendCANmessage(msgID, 3, 0x01, 0x6f, 0x00) ;
Serial1.println("OK pressed");
}

// check if the switch is high.
// if it is:
if (sState == HIGH) {
long msgID = 0x201 ;
SendCANmessage(msgID, 3, 0x01, st, 0x00) ;
Serial1.print("Station changed to ");
Serial1.println(st);
delay(500);
if (st == 0x39){st=0x31;} else {st++;};
}
// try to read message and output to serial
CanMsg *r_msg;
if ((r_msg = canBus.recv()) != NULL){
Serial1.print(r_msg->ID);
Serial1.print("#");
Serial1.print(r_msg->Data[0]);
Serial1.print(".");
Serial1.print(r_msg->Data[1]);
Serial1.print(".");
Serial1.print(r_msg->Data[2]);
Serial1.print(".");
Serial1.print(r_msg->Data[3]);
Serial1.print(".");
Serial1.print(r_msg->Data[4]);
Serial1.print(".");
Serial1.print(r_msg->Data[5]);
Serial1.print(".");
Serial1.print(r_msg->Data[6]);
Serial1.print(".");
Serial1.println(r_msg->Data[7]);
if (r_msg->ID == 0x201 and r_msg->Data[0] == 0x01 and r_msg->Data[1] == 0xFF){
// SETTINGS is pressed!
Serial1.println("SETTINGS. Pause for 2 seconds.");
digitalWrite(PC13, LOW); // turn the onboard LED on
delay(2000);
digitalWrite(PC13, HIGH); // turn the LED off
}
canBus.free();
}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
#include <HardwareCAN.h>
//#include "changes.h"
/*
* Example of use of the HardwareCAN library
* This application sends two times one frame of data and then blinkes 3 times. Then repeats after 2 seconds.
* It also produces data that are sent periodically using another two frames.
*
* Please read the file changes.h to see the changes to be performed to the core in order to use this
*/

byte msgD0 ; // variable to be used in the example.

// Instanciation of CAN interface
HardwareCAN canBus(CAN1_BASE);
CanMsg msg ;

void CANSetup(void)
{
CAN_STATUS Stat ;

// Initialize CAN module
canBus.map(CAN_GPIO_PB8_PB9); // This setting is already wired in the Olimexino-STM32 board
Stat = canBus.begin(CAN_SPEED_125, CAN_MODE_NORMAL); // Other speeds go from 125 kbps to 1000 kbps. CAN allows even more choices.

canBus.filter(0, 0, 0);
canBus.set_irq_mode(); // Use irq mode (recommended), so the handling of incoming messages
// will be performed at ease in a task or in the loop. The software fifo is 16 cells long,
// allowing at least 15 ms before processing the fifo is needed at 125 kbps
Stat = canBus.status();
if (Stat != CAN_OK)
/* Your own error processing here */ ; // Initialization failed
}


// Send one frame. Parameter is a pointer to a frame structure (above), that has previously been updated with data.
// If no mailbox is available, wait until one becomes empty. There are 3 mailboxes.
CAN_TX_MBX CANsend(CanMsg *pmsg) // Should be moved to the library?!
{
CAN_TX_MBX mbx;

do
{
mbx = canBus.send(pmsg) ;
#ifdef USE_MULTITASK
vTaskDelay( 1 ) ; // Infinite loops are not multitasking-friendly
#endif
}
while(mbx == CAN_TX_NO_MBX) ; // Waiting outbound frames will eventually be sent, unless there is a CAN bus failure.
return mbx ;
}

// Send message
// Prepare and send a frame containing some value
void SendCANmessage(long id=0x001, byte d0=0x00, byte d1=0x00, byte d2=0x00, byte d3=0x00, byte d4=0x00, byte d5=0x00, byte d6=0x00, byte d7=0x00)
{
// Initialize the message structure
// A CAN structure includes the following fields:
msg.IDE = CAN_ID_STD; // Indicates a standard identifier ; CAN_ID_EXT would mean this frame uses an extended identifier
msg.RTR = CAN_RTR_DATA; // Indicated this is a data frame, as opposed to a remote frame (would then be CAN_RTR_REMOTE)
msg.ID = id ; // Identifier of the frame : 0-2047 (0-0x3ff) for standard idenfiers; 0-0x1fffffff for extended identifiers
msg.DLC = 8; // Number of data bytes to follow

// Prepare frame : send something
msg.Data[0] = d0 ;
msg.Data[1] = d1 ;
msg.Data[2] = d2 ;
msg.Data[3] = d3 ;
msg.Data[4] = d4 ;
msg.Data[5] = d5 ;
msg.Data[6] = d6 ;
msg.Data[7] = d7 ;

digitalWrite(PC13, LOW); // turn the onboard LED on
CANsend(&msg) ; // Send this frame
delay(180);
digitalWrite(PC13, HIGH); // turn the LED off
delay(100);
}

// The application program starts here
void setup() {
// put your setup code here, to run once:
CANSetup() ; // Initialize the CAN module and prepare the message structures.
pinMode(PC13, OUTPUT);
msgD0 = 0x01;
}

void loop() {
delay(1000);
long msgID = 0x101 ;
SendCANmessage(msgID, msgD0) ;
msgD0++;
}
Loading