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
1 change: 1 addition & 0 deletions ports/gprs_a9/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ SRC_C = \
modgps.c \
modusocket.c \
modi2c.c \
modaudio.c \
machine_adc.c \
machine_uart.c \
machine_rtc.c
Expand Down
8 changes: 8 additions & 0 deletions ports/gprs_a9/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,14 @@ void EventDispatch(API_Event_t* pEvent)
modmachine_notify_power_on(pEvent);
break;

case API_EVENT_ID_KEY_DOWN:
modmachine_notify_power_key_down(pEvent);
break;

case API_EVENT_ID_KEY_UP:
modmachine_notify_power_key_up(pEvent);
break;

// Network
// =======

Expand Down
197 changes: 197 additions & 0 deletions ports/gprs_a9/modaudio.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* Development of the code in this file was sponsored by Microbric Pty Ltd
*
* The MIT License (MIT)
*
* Copyright (c) 2020 <ubaldo@eja.it>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

#include "timeout.h"
#include "api_os.h"
#include "api_audio.h"
#include "api_fs.h"
#include "py/runtime.h"

uint8_t audioVolume = 5;
int audioRecordFd = -1;


STATIC mp_obj_t modaudio_record_start(size_t n_args, const mp_obj_t *args) {
// ========================================
// Audio Record.
// Args:
// filename (str): output file name with full path
// channel (int): audio channel (default 2, AUDIO_MODE_LOUDSPEAKER)
// type (int): audio type (default 3, AUDIO_TYPE_AMR)
// mode (int): audio mode (default 7, AUDIO_RECORD_MODE_AMR122)
// ========================================

const char* filename;
int channel = AUDIO_MODE_LOUDSPEAKER;
int type = AUDIO_TYPE_AMR;
int mode = AUDIO_RECORD_MODE_AMR122;

if (n_args > 0) {
filename = mp_obj_str_get_str(args[0]);
} else {
mp_raise_ValueError("filename is mandatory");
return mp_const_none;
}
if (n_args >= 2) {
channel = mp_obj_get_int(args[1]);
}
if (n_args >= 3) {
type = mp_obj_get_int(args[2]);
}
if (n_args >= 4) {
mode = mp_obj_get_int(args[3]);
}
Trace(1,"audio record start, filename: %s, channel: %d, type: %d, mode: %d", filename, channel, type, mode);
audioRecordFd = API_FS_Open(filename,FS_O_WRONLY|FS_O_CREAT|FS_O_TRUNC,0);
if (audioRecordFd < 0) {
Trace(1,"audio open file error");
mp_raise_ValueError("file open error");
return mp_const_none;
}
AUDIO_SetMode(channel);
AUDIO_Error_t result = AUDIO_RecordStart(type, mode, audioRecordFd, NULL, NULL);
if (result != AUDIO_ERROR_NO) {
Trace(1,"audio record start fail: %d",result);
API_FS_Close(audioRecordFd);
audioRecordFd = -1;
mp_raise_ValueError("cannot record audio file");
return mp_const_none;
}
Trace(1,"recording");
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(modaudio_record_start_obj, 1, 4, modaudio_record_start);


STATIC mp_obj_t modaudio_record_stop(void) {
//Stop recording audio
AUDIO_RecordStop();
API_FS_Close(audioRecordFd);
audioRecordFd = -1;
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_0(modaudio_record_stop_obj, modaudio_record_stop);


void audioPlayCallback(AUDIO_Error_t result) {
Trace(1,"audio play callback result: %d",result);
AUDIO_Stop();
}


STATIC mp_obj_t modaudio_play_start(size_t n_args, const mp_obj_t *args) {
// ========================================
// Audio Play.
// Args:
// filename (str): input file name with full path
// volume (int): (default 5)
// channel (int): audio channel (default 2, AUDIO_MODE_LOUDSPEAKER)
// type (int): audio type (default 3, AUDIO_TYPE_AMR)
// ========================================

const char* filename;
int volume = audioVolume;
int channel = AUDIO_MODE_LOUDSPEAKER;
int type = AUDIO_TYPE_AMR;

if (n_args > 0) {
filename = mp_obj_str_get_str(args[0]);
} else {
mp_raise_ValueError("filename is mandatory");
return mp_const_none;
}
if (n_args >= 2) {
volume = mp_obj_get_int(args[1]);
}
if (n_args >= 3) {
channel = mp_obj_get_int(args[2]);
}
if (n_args >= 4) {
type = mp_obj_get_int(args[3]);
}
Trace(1,"play start, filename: %s, volume: %d, channel: %d, type: %d", filename, volume, channel, type);
AUDIO_Error_t result = AUDIO_Play(filename, type, audioPlayCallback);
if (result != AUDIO_ERROR_NO) {
AUDIO_Stop();
Trace(1,"play fail: %d", result);
mp_raise_ValueError("cannot play audio file");
return mp_const_none;
} else {
Trace(1,"playing");
}
OS_Sleep(200);
AUDIO_SetMode(channel);
AUDIO_SpeakerOpen();
AUDIO_SpeakerSetVolume(volume);
Trace(1,"playing");
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(modaudio_play_start_obj, 1, 4, modaudio_play_start);


STATIC mp_obj_t modaudio_play_pause(void) {
//Pause audio play
AUDIO_Pause();
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_0(modaudio_play_pause_obj, modaudio_play_pause);


STATIC mp_obj_t modaudio_play_resume(void) {
//Resume playing after pause
//AUDIO_Resume(fileFd); //?AUDIO_Play doesn't have nor return a fileFd
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_0(modaudio_play_resume_obj, modaudio_play_resume);


STATIC mp_obj_t modaudio_play_stop(void) {
//Stop playing audio
AUDIO_Stop();
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_0(modaudio_play_stop_obj, modaudio_play_stop);


STATIC const mp_map_elem_t mp_module_audio_globals_table[] = {
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_audio) },

{ MP_OBJ_NEW_QSTR(MP_QSTR_record_start), (mp_obj_t)&modaudio_record_start_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_record_stop), (mp_obj_t)&modaudio_record_stop_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_play_start), (mp_obj_t)&modaudio_play_start_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_play_stop), (mp_obj_t)&modaudio_play_stop_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_play_pause), (mp_obj_t)&modaudio_play_pause_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_play_resume), (mp_obj_t)&modaudio_play_resume_obj },
};
STATIC MP_DEFINE_CONST_DICT(mp_module_audio_globals, mp_module_audio_globals_table);


const mp_obj_module_t audio_module = {
.base = { &mp_type_module },
.globals = (mp_obj_dict_t*)&mp_module_audio_globals,
};
27 changes: 27 additions & 0 deletions ports/gprs_a9/modmachine.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,14 @@
#include "api_hal_adc.h"

STATIC mp_obj_t modmachine_watchdog_off(void);
STATIC mp_obj_t power_key = mp_const_none;

void modmachine_init0(void) {
PM_SetSysMinFreq(PM_SYS_FREQ_312M);
modmachine_watchdog_off();
modmachine_pin_init0();
modmachine_uart_init0();
power_key = mp_const_none;
}

// ------
Expand Down Expand Up @@ -203,6 +205,30 @@ STATIC mp_obj_t modmachine_watchdog_reset(void) {

STATIC MP_DEFINE_CONST_FUN_OBJ_0(modmachine_watchdog_reset_obj, modmachine_watchdog_reset);

void modmachine_notify_power_key_down(API_Event_t* event) {
if (power_key && power_key != mp_const_none) {
mp_sched_schedule(power_key, mp_obj_new_int(1));
}
}

void modmachine_notify_power_key_up(API_Event_t* event) {
if (power_key && power_key != mp_const_none) {
mp_sched_schedule(power_key, mp_obj_new_int(0));
}
}

STATIC mp_obj_t modmachine_on_power_key(mp_obj_t callable) {
// ========================================
// Sets a callback on power key press.
// Args:
// callback (Callable): a callback to
// execute on power key press.
// ========================================
power_key = callable;
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(modmachine_on_power_key_obj, modmachine_on_power_key);

STATIC const mp_rom_map_elem_t machine_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_umachine) },
{ MP_ROM_QSTR(MP_QSTR_Pin), MP_ROM_PTR(&machine_pin_type) },
Expand All @@ -213,6 +239,7 @@ STATIC const mp_rom_map_elem_t machine_module_globals_table[] = {
{ MP_OBJ_NEW_QSTR(MP_QSTR_set_idle), (mp_obj_t)&modmachine_set_idle_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_set_min_freq), (mp_obj_t)&modmachine_set_min_freq_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_power_on_cause), (mp_obj_t)&modmachine_power_on_cause_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_on_power_key), (mp_obj_t)&modmachine_on_power_key_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_off), (mp_obj_t)&modmachine_off_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_get_input_voltage), (mp_obj_t)&modmachine_get_input_voltage_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_watchdog_on), (mp_obj_t)&modmachine_watchdog_on_obj },
Expand Down
2 changes: 2 additions & 0 deletions ports/gprs_a9/modmachine.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,5 @@ void modmachine_uart_init0(void);
void modmachine_init0(void);

void modmachine_notify_power_on(API_Event_t* event);
void modmachine_notify_power_key_down(API_Event_t* event);
void modmachine_notify_power_key_up(API_Event_t* event);
2 changes: 2 additions & 0 deletions ports/gprs_a9/mpconfigport.h
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,7 @@ extern const struct _mp_obj_module_t cellular_module;
extern const struct _mp_obj_module_t gps_module;
extern const struct _mp_obj_module_t usocket_module;
extern const struct _mp_obj_module_t i2c_module;
extern const struct _mp_obj_module_t audio_module;

#define MICROPY_PORT_BUILTIN_MODULES \
{ MP_OBJ_NEW_QSTR(MP_QSTR_machine), (mp_obj_t)&mp_module_machine }, \
Expand All @@ -222,6 +223,7 @@ extern const struct _mp_obj_module_t i2c_module;
{ MP_OBJ_NEW_QSTR(MP_QSTR_gps), (mp_obj_t)&gps_module }, \
{ MP_OBJ_NEW_QSTR(MP_QSTR_usocket), (mp_obj_t)&usocket_module }, \
{ MP_OBJ_NEW_QSTR(MP_QSTR_i2c), (mp_obj_t)&i2c_module }, \
{ MP_OBJ_NEW_QSTR(MP_QSTR_audio), (mp_obj_t)&audio_module }, \

// type definitions for the specific machine

Expand Down